На прошлом уроке мы таки подключили дисплей и кнопки + сохранили значения кнопок в памяти ЕЕПРОМ (энергонезависимой памяти). Настала пора получить данные с модуля RTC и вывести эти значения на экран. В принципе ничего сложного в этом нет, но появилась пара подводных камней о которые мне пришлось биться головой и в конце концов я победил! Приступаем.
Модуль RTC тоже будет подключаться к шине I2C т.е. к выводам А4 и А5. Никаких дополнительных деталей не нужно для подключения, наоборот- несколько деталей с блока RTC просто необходимо выпаять. Почему спросите вы? Когда я установил элемент 2032 (батарейка проще говоря) в модуль- часы даже не хотели заводиться. Померил напряжение батареи. Оно упало до 2,7 В и продолжало падать. Прозвонка цепи питания не обнаружила КЗ и низкоомных цепей но факт оставался фактом- батарейка стремительно разряжалась, при этом в даташите написано что ток потребления RTC составляет порядка 5 мкА, или проще говоря 0,000005 А, еще проще говоря- ток саморазряда элемента 2032. Пришлось искать схему RTC и выпаивать/впаивать необходимые детали. Я опишу здесь процесс подготовки модуля RTC1307.

Во первых вынимаем батарейку, затем выпаиваем все 4 детали обведенные прямоугольниками. Затем вместо сопротивления 510кОм (зеленый прямоугольник) впаиваем перемычку. Можно взять деталь со старой материнской платы, на ней должно быть написано О или ООО что значит деталь с нулевым сопротивлением, проще говоря- перемычка. А можно просто повесить «соплю» из припоя. Эти действия снимут режим так называемой «подзарядки» и позволят в дальнейшем работать только от батареи. Теперь блок RTC1307 подготовлен к работе. Подключаем его.

Схема подключения приведена ниже. Что интересно LCD и RTC подключены к одним и тем же выходам Ардуино но не конфликтуют между собой! Для тех кто подключает дисплей не по шине I2C схема такая же, только дисплей должен быть подключен к цифровым выходам Ардуино. Теперь мы можем записать/считать данные в/из RTC! Чем сейчас и займемся. Тем более что просто необходимо понять степень пригодности RTC для наших часов. Что значит степень пригодности. Это я так образно выразился, но в моем случае часы за 4 суток «убежали» на 3 минуты и 15 секунд! Поэтому сразу вырисовывается несколько выходов из данной ситуации. Но обо всем по порядку. Во первых когда я подключил все библиотеки и попробовал залить скетч в Ардуино- начали выпрыгивать ошибки при компиляции. Как я выяснил немного позже это оказались библиотеки для подключения RTC, или по другому говоря, их надо было ставить первыми в скетче. Оказывается это тоже влияет на работу RTC. Не знал, не знал. Прошу прощения что раньше ввел вас в заблуждение говоря что библиотеки можно в заголовке объявлять не по порядку. Оказалось- по порядку. Теперь начало скетча выглядит так:
#include <Wire.h>
#include <iarduino_RTC.h>
iarduino_RTC time(RTC_DS1307);
#include <EEPROM.h>
#include <LiquidCrystal_I2C.h>
В секцию setup добавляем команду time.begin(); что дает доступ к модулю RTC. Теперь в секции loop вводим следущее:
//основной цикл работы
/*
lcd.setCursor(0, 0);
lcd.print(EEPROM.read(1));
lcd.setCursor(6, 0);
lcd.print(EEPROM.read(2));
lcd.setCursor(12, 0);
lcd.print(EEPROM.read(3));
lcd.setCursor(0, 1);
lcd.print(iButMinus);
lcd.setCursor(6, 1);
lcd.print(iButMenu);
lcd.setCursor(12, 1);
lcd.print(iButPlus);*/
if (millis() % 1000 == 0)
{ // Если прошла 1 секунда.
lcd.setCursor(0, 0);
lcd.print(time.gettime(«H:i:s D»));
lcd.setCursor(0, 1);
lcd.print(time.gettime(«d M Y»));
delay(1);
Как видно из листинга мы закомментировали то что было раньше написано в нашем скетче знаками /* и */, теперь эта часть кода работать не будет. Смысл программы прост. Если прошла секунда то устанавливаем курсор в 0 столбец 0 строки (проще говоря в левый верхний угол) и выводим время, полученной с RTC. Переводим курсор на начало второй строки и выводим дату. Вы можете изменить параметры отображения как вам угодно. Т.е. вывести не 24 часовой а 12 часовой формат времени, убрать показания секунд, сменить отображение дней недели, сменить формат отображения даты… Все это можно описать именно в строках lcd.print(time.gettime()); Если вы хотите поподробнее узнать какие еще команды поддерживает RTC то сделайте следующее: Файл- Примеры- iarduino RTC-gettime или settime. Ниже примеров приведены описания и примеры работ с данной библиотекой. После заливки скетча вы,вероятнее всего, увидите на дисплее одни нули… Т.е. часы не идут, но данные с часов мы получаем. Давайте установим время. Т.к. время нам нужно установить только один раз то запишем оператор установки времени в секцию setup. Пишем в любом месте секции но обязательно после оператора time.begin(); строку time.settime(30, 39, 22, 18, 01, 18, 4); // Записываем время в модуль: сек, мин, час, день, месяц, год, день недели (воскресение-0 и т.д.). Значения в скобках выставьте какое вам нужно. В данном примере установлен четверг, 18 января 2018 года, 22 часа, 39 минут, 30 секунд. Хочу сразу предупредить что скетч надо заливать за 10-15 секунд до наступления устанавливаемого времени. Программа скомпилируется, зальется и начнет работать. Теперь часы пойдут так как вы установили НО! При выключении часов или их перезагрузке часы опять установятся на то значение которые вы указали в операторе time.settime. поэтому комментируем строку установки времени символами // и снова заливаем скетч. Теперь время не будет переустанавливаться даже при полном отключении питания. Самое главное- не вынимайте батарейку из RTC. Ну а теперь пришло время проверить качество вашего RTC. Запомните время на которое ваши часы опережают/ отстают от времени, например, на компьютере. На следующий день в такое же время посмотрите как изменилось отношение времени на RTC и компьютера. Если часы очень сильно бегут/ отстают то придется перепаять кварцевый резонатор. Это блестящий цилиндрик на плате RTC, он расположен слева и параллельно зеленому прямоугольнику. Выпаиваем такой же со старой материнской платы компьютера. Опять заливаем установочный скетч, затем скетч без установки времени и снова контроллируем. Я перепаял резонатор и часы бегут у меня на 5 сек в сутки. Все равно бегут но опять есть 2 выхода:
- Купить RTC DS3231, они на немного дороже чем 1302 и 1307 но имеют температурную компенсацию.
- Установить коррекцию времени как на старых советских наручных электронных часах.
Пункт 2 можно применить сразу но большие отклонения значений в течении дня будут более заметны поэтому целесообразно сначала перепаять резонатор а только потом ввести коррекцию. Значения коррекции будем вводить вручную через меню. Давайте подумаем более детально над самим процессом коррекции.
- Значение коррекции будем сохранять в ЕЕПРОМ. Т.к. коррекция может быть как и положительная (часы отстают) так и отрицательная (часы убегают) то сохранять будем в ЕЕПРОМ два значения: первое- знак коррекции 0- часы отстают, 1- часы убегают, и второе- значение собственно значение коррекции.
- Когда будем корректировать значение. Я предлагаю корректировать в полночь. Например часы убегают на 15 секунд в сутки. При достижении 0 час 0 мин 15 секунд вызываем функцию time.settime с установкой на 0 час 0 мин 0 сек и все… Часы скорректированы. Аналогично будет работать функция и при отставании. Т.е нам будет 3 условия. Об этом будет ниже.
- Как вводить значение коррекции. Вопрос поставлен немного некорректно но за какой период времени будет вводиться отклонение. Например измерение проводилось за день, неделю, 10 дней, месяц и т.д. Соответственно коррекция должна быть рассчитанной. Например за 10 дней часы убежали на 123 секунд, значит в день часы убегают на 123/10= 12,3 секунды. Можно предусмотреть и данный вариант но я решил сделать дневную коррекцию. Если вам уж очень надо сделать плавающую коррекцию то выделите для этого еще одну ячейку ЕЕПРОМ и заносите туда количество дней. Еще раз напомню что значение ячейки ЕЕПРОМ не могут быть выше 255. Старайтесь исходить из этих данных.
- Теперь наверное самая запутанная часть. Каждый человек считает любую ситуацию относительно своего чувства и мировоззрения. Приведу пример с нашими часами. Возьмем одну ситуацию. Например для меня. Я как программист считаю что если часы отстают то и нужно ввести время отставания с ОТРИЦАТЕЛЬНЫМ (часы отстают все таки, значит минус) знаком и потом добавлять отстающее значение. Теперь другая ситуация. Человек считает что часы отстают и ему надо ДОБАВИТЬ отстающие секунды. Т.е. в его понимании коррекция должна уже быть со знаком ПЛЮС (т.е. надо добавить отстающие секунды). Как к этому отнестись и описать для каждого индивидуально… Я пока не представляю. Если кто знает- отпишитесь в комментариях.
- Еще одна проблема будет возникать при полном отключении питания на часы. Например в 22.00 отключилось электричество у вас в квартире. В 2 часа ночи оно включилось но коррекция так и не произошла т.к. время было уже упущено. Следует понимать что время будет переустанавливать Ардуино в RTC а не сам RTC. Если отключения будут происходить каждую ночь в течение 7 дней то отклонения будут уже большими. По всем прикидкам нужно ввести еще одну ячейку в ЕЕПРОМ в которую будет записываться значения дня и по разнице между днями проводить корректировку. Например из примера выше возьмем значение 12,3 секунды в день. За неделю часы убегут на 12,3*7=86,1 сек. Больше минуты. Об этом тоже стоит подумать, но мы будем исходить из того что у вас не отключат питание каждую ночь и поэтому коррекция будет происходить каждую ночь в 24 часа.
Как видите на данном примере приходится решать задачи настолько далекие от программирования что очень много времени уходит именно на такие вот «мелочи».
На этом подключение RTC DS1307 закончено. В следующем уроке мы будем программировать собственно программу управления часами. После этого останется только установить часы в корпус. Спасибо за внимание.
<-Урок 7.4 |