Новичкам от новичка — Arduino LCD 16×2 I2C RTC 1307 — Делаем часы на с LCD + модуль часов реального времени и все это по 2-м проводам


Всем привет!

Я сам еще новичек, совсем зеленый. Поэтому мой пост будет полезен таким же начинающим))

С ардуиной познакомился с месяц назад, заказал деталек — стали приходить — начал потихоньку вникать. Вообще — глобально я хочу собрать бортовой компьютер в авто — для вывода оперативной информации и сброса ошибок. Ну а пока тернеруюь на кошках__)

Решил собрать часы.

Сначала пришел LCD экран 1602 символов, стандартный экран, инстсрукций по подключению в интернете масса. http://www.dreamdealer.nl/tutorials/connecting_a_1602a_lcd_display_and_a_light_sensor_to_arduino_uno.html
Подключил-посмотрел, мдя, проводов много(( Запустил на нем простейшие софтовые часы, все ничего, но как только отключаешь питание — продавает и время( А так как кнопок еще нету — то установка происходит через комп по ком порту через Процессинг, вообщем тот еще геморой.

Потом пришел заранее заказанный модуль I2C — символьный LCD. Модуль этот основан на микрухе которая расширяет порты ввода вывода. тоесть по 2м проводам данные входят — а по 8 выводам расходятся на экран. Вещь дюже полезная, на ибээ их полно.

Стало совсем красиво.

Есть некоторая загвоздка. дело в том что в библиотеке с которой работает экран по i2c протоколу — нерабочие примеры((( Это у меня отняло какое-то время для понимания сути процессов))

Кратенько для тех кто купит переходник — в каждом переходнике зашит его адрес, адрес можно узнать с помощью сканера адресов или аналитическим методом. На платке есть перемычки — если ихзапаять, адрес будет 0x20, а если перемычки сводобные — адрес будет 0x27. Адресация нужна для правильной инициализации переходника и работы с LCD экраном.

Сразу понятно будет не все, но после суток-двух копания в инете, прийдет понимание.

Вообщем суть такая, по двум проводам можно подключить любое количество экранов! Главное чтобы у каждого был свой адрес, а менять адрес можно если менть перемычки на переходничке i2c lcd. Если экранчик один, то можно выяснить аэрес перебором или найти сканер и посмотреть все доступные адреса по протоколу i2c. Адрес зависит от типа переходника, про типы подробно вот тут http://arduino-info.wikispaces.com/LCD-Blue-I2C

У меня оказался Третий вариант как по ссылке. Разобравшись что куда, выяснил что адрес у него 0x27, эта цифра нужна для обращения к экрану.

А теперь важное.

Есть 2 рабочих варианта (может даже больше)

Перая библиотека с примерами качается по ссылке http://arduino-info.wikispaces.com/LCD-Blue-I2C
Сама библиотка https://bitbucket.org/fmalpartida/new-liquidcrystal/downloads
Примеры брать не из библиотки а из блога выше.

Второй вариант, http://arduino-info.wikispaces.com/file/detail/LiquidCrystal_I2C1602V1.zip/341635514
Мой пример работает на этой библиотеке. Она старее, но мне показалось достаточной использовать ее.

Обе эти библиотеки НЕ СОВМЕСТИМЫ!

Так что ставим второй вариант, если не заработает — ставим первый и переписываем пример под свою библиотеку, благо там не много.

Я честно уже не помню почему выбрал второй вариант и где взял примеры, главное, что все работает))

//

После настройки экрана по двум проводам, пришли RTC модуль — часы реального времени на микрухе 1307. Общаются они по тем же 2м проводам, то есть портов на ардуине не занимают вообще.

Рабочую библиотеку нашел не сразу, заработала вот эта https://github.com/adafruit/RTClib

Примеры в ней хорошие, рабочие, все сразу стало понятно. Адрес в часах зашит жестко (я не понял как его менять)

Теперь при отключении питания, часы не сбрасываются)))

//

Итак, особенностью часов является отображение 3х чисел в виде столбиков, секундыи минуты слева -направо, часы — наоборот справа-налево.

Используется 8 собственных символов, которые создают индикацию. Сначала сдеал 9 — начали скакать символы, смотрел — думал — оказалось что максимальное количество собственных символов — 8. Поэтому в качестве полного закрашенного квадрата используется системный знак по коду, а процентное заполнение — нарисовано в массиве битами.

Я думаю что в коде все понятно.

Функция Map — «растягивает» отображаемый промежуток в 24 часа на то количество клеток, которое нужно. так же и с минутами и секундами, но там растягивается другой диапазон.

Сначала делал без мапа — не смог найти функцию округления, коэффициенты были целыми числами — и растягивался диапазон всегда то больше — то меньше чем нужно. А мап меня спас))

В остальном все довольно просто, не забываем стирать квадраты, когда цикл часов начинается занова.

// Date and time functions using a DS1307 RTC connected via I2C and Wire lib

#include <Wire.h>
#include "RTClib.h"
#include <LiquidCrystal_I2C.h>
RTC_DS1307 rtc;
LiquidCrystal_I2C lcd(0x27,16,2);  // set the LCD address to 0x27 for a 16 chars and 2 line display
int progbar=0;

byte p20[8] = {
  B10000,
  B10000,
  B10000,
  B10000,
  B10000,
  B10000,
  B10000,
};
byte p40[8] = {
  B11000,
  B11000,
  B11000,
  B11000,
  B11000,
  B11000,
  B11000,
};
byte p60[8] = {
  B11100,
  B11100,
  B11100,
  B11100,
  B11100,
  B11100,
  B11100,
};
byte p80[8] = {
  B11110,
  B11110,
  B11110,
  B11110,
  B11110,
  B11110,
  B11110,
};
byte p100[8] = {
  B11111,
  B11111,
  B11111,
  B11111,
  B11111,
  B11111,
  B11111,
};
byte ip20[8] = {
  B00001,
  B00001,
  B00001,
  B00001,
  B00001,
  B00001,
  B00001,
};
byte ip40[8] = {
  B00011,
  B00011,
  B00011,
  B00011,
  B00011,
  B00011,
  B00011,
};
byte ip60[8] = {
  B00111,
  B00111,
  B00111,
  B00111,
  B00111,
  B00111,
  B00111,
};
byte ip80[8] = {
  B01111,
  B01111,
  B01111,
  B01111,
  B01111,
  B01111,
  B01111,
};



void setup () {
  Serial.begin(57600);
  Wire.begin();
  rtc.begin();
  lcd.init();                      // initialize the lcd
  lcd.backlight();
  lcd.home();

  //Make progress characters
  lcd.createChar(0, p20);
  lcd.createChar(1, p40);
  lcd.createChar(2, p60);
  lcd.createChar(3, p80);
  // lcd.createChar(4, p100);
  lcd.createChar(4, ip20);
  lcd.createChar(5, ip40);
  lcd.createChar(6, ip60);
  lcd.createChar(7, ip80);


  lcd.clear();




  if (! rtc.isrunning()) {
    Serial.println("RTC is NOT running!");
    // following line sets the RTC to the date & time this sketch was compiled
    // rtc.adjust(DateTime(__DATE__, __TIME__));
  }
}

void loop () {

  digitalClockDisplay();
  delay(200);
}


void digitalClockDisplay(){
  // digital clock display of the time
  DateTime now = rtc.now();






  lcd.setCursor(5, 0);
  printDigits(now.hour()); // печатает часы

  //рисуем прогресс бар часов

  progbar=map(now.hour(),0,24,0,25);

  //стираем бар если час =0
  if(now.hour()<1  ){
    lcd.setCursor(0,0);
    lcd.print("     ");
  }

  // отрисовка бара часа в обратном направлении
  //сначала рисуем квадраты

  for (int i = 0; i<(progbar/5); i++)
  {

    lcd.setCursor(4-i, 0);
    lcd.write(B11111111);

  }

  //отрисовываем деления в поле символа,
  lcd.setCursor(4-progbar/5, 0);
  if(progbar%5<4){
    lcd.write(progbar%5+4);
  }
  else{
    lcd.write(B11111111);
  }

  //нарисовали часы и шкалу часов
  //рисуем бегающие двоеточие, привязано к секундам, вывод слева или справа двоеточие зависит от четности секунд

  lcd.setCursor(7, 0);
  if (now.second()%10%2==0){
    lcd.print(": ");
  }
  else
  {
    lcd.print(" :");
  }
  //нарисовали двоеточие


  //рисуем минуты

  lcd.setCursor(9, 0);
  printDigits(now.minute());
  //стираем бар минут если минуты=0
  if(now.minute()<1  ){
    lcd.setCursor(11,0);
    lcd.print("     ");
  }
  //рисуем бар минут
  //тут уже отрисовка происходит в прямом направлении

  progbar=map(now.minute(),0,60,0,25);


  for (int i = 0; i<(progbar/5); i++)
  {

    lcd.setCursor(i+11, 0);
    lcd.write(B11111111);

  }


  lcd.setCursor(progbar/5+11, 0);
  if(progbar%5<4){
    lcd.write(progbar%5);
  }
  else{
    lcd.write(B11111111);
  }

  //нарисовали минуты


  //рисуем бар минут
  //самый длинный бар в самом низу

  lcd.setCursor(7, 1);
  printDigits(now.second());

  if(now.second()<1  ){
    lcd.setCursor(0,1);
    lcd.print("       ");
    lcd.setCursor(9,1);
    lcd.print("       ");
  }


  progbar=map(now.second(),0,60,0,80);


  for (int i = 0; i<(progbar/5); i++)
  {

    lcd.setCursor(i, 1);
    lcd.write(B11111111);

  }


  lcd.setCursor(progbar/5, 1);
  if(progbar%5<4){
    lcd.write(progbar%5);
  }
  else{
    lcd.write(B11111111);
  }


  lcd.setCursor(7, 1);
  printDigits(now.second());

}



void printDigits(int digits){
  // utility function for digital clock display: prints preceding colon and leading 0


  if(digits < 10){

    lcd.print('0');
  }

  lcd.print(digits);
}



Ссылка на видео


0 комментариев на «“Новичкам от новичка — Arduino LCD 16×2 I2C RTC 1307 — Делаем часы на с LCD + модуль часов реального времени и все это по 2-м проводам”»

  1. Да, как только приедет еще какая-нибудь шабашка — сразу поделюсь))

    Ребят, какие еще варианты есть сделать что-то необычное имея только символьный экран и ардуину? руки чешутся, а не из чего делать)))

  2. Доброго времени суток. Я извиняюсь, вопрос слегка не по теме. Возможно вы меня перенаправите куда надо. Я абсолютный нуб в этом, но вот решил познакомиться с микроконтроллером Freeduino Through-Hole и дисплеем WH1602B-YYK-CTK. Соединяю все согласно схеме на сайте фридуино. После записи скетча дисплей начинает выдавать рандомные символы целыми строчками. Скетч не выполняется. Вы сталкивались с подобным?

    • Чего у меня только не было))

      Скорее всего неправильное подключение. Еще раз перепроверить все провода. robocraft.ru/blog/arduino/503.html как пример.

      Потом в скетче нужно проверить
      //в порядке RS, E, DB4, DB5, DB6, DB7
      LiquidCrystal lcd(12, 10, 5, 4, 3, 2);
      и соотнести то в каком порядке они прописаны в функции обьявления экрана и в каком порядке подключены к ардуине.

      На ошибках учатся, вперед!))

  3. Здравствуйте.
    Огромное спасибо за статью.
    Сначала с помощью неё удалось запустить LCD (до этого как и у многих были проблемы с библиотеками и примерами).
    Затем подключил часы. Все заработало замечательно.
    Но, попытался допилить код под свои нужды, подключение часов и LCD через I2C, без всяких «красивостей» (просто часы, желательно c выводом даты).
    И тут начались проблемы. Не работает, постоянно ошибки при компилировании.
    Пытался «скрестить» Ваш код с примером для 8-битного подключения, опять ничего не получается.
    На просторах интернета подобных примеров нет (ну всмысле, подключение RTC & LCD через I2C), везде только Ваш пример.
    Может подскажите как организовать простые часы, или примером поделитесь?
    Заранее Спасибо.

  4. У меня заработало с DS3231. Так как часы не имеют кнопок корректировки времени, для решения этой проблемы рекомендую править время на RTC модуле таким методом т. е. на компе.

Добавить комментарий

Arduino

Что такое Arduino?
Зачем мне Arduino?
Начало работы с Arduino
Для начинающих ардуинщиков
Радиодетали (точка входа для начинающих ардуинщиков)
Первые шаги с Arduino

Разделы

  1. Преимуществ нет, за исключением читабельности: тип bool обычно имеет размер 1 байт, как и uint8_t. Думаю, компилятор в обоих случаях…

  2. Добрый день! Я недавно начал изучать программирование под STM32 и ваши уроки просто бесценны! Хотел узнать зачем использовать переменную типа…

3D-печать AI Arduino Bluetooth CraftDuino DIY Google IDE iRobot Kinect LEGO OpenCV Open Source Python Raspberry Pi RoboCraft ROS swarm ИК автоматизация андроид балансировать бионика версия видео военный датчик дрон интерфейс камера кибервесна манипулятор машинное обучение наше нейронная сеть подводный пылесос работа распознавание робот робототехника светодиод сервомашинка собака управление ходить шаг за шагом шаговый двигатель шилд юмор

OpenCV
Робототехника
Будущее за бионическими роботами?
Нейронная сеть - введение