[sape_tizer]
Ср. Май 31st, 2023

Что и как строить на земельном участке или обо всем понемногу

Все о инструментах, строительстве, работах, АРДУИНО, электрика, электроника и многое другое

Урок 7.5- Пишем скетч на часы (ч.2)

На прошлом уроке мы таки подключили дисплей и кнопки + сохранили значения кнопок в памяти ЕЕПРОМ (энергонезависимой памяти). Настала пора получить данные с модуля RTC и вывести эти значения на экран. В принципе ничего сложного в этом нет, но появилась пара подводных камней о которые мне пришлось биться головой и в конце концов я победил! Приступаем.

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

Доработка RTC1307
Доработка RTC1307

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

Подключение LCD и RTC1307 по шине I2C
Подключение LCD и RTC1307 по шине I2C

Схема подключения приведена ниже. Что интересно 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 выхода:

  1. Купить RTC DS3231, они на немного дороже чем 1302 и 1307 но имеют температурную компенсацию.
  2. Установить коррекцию времени как на старых советских наручных электронных часах.

Пункт 2 можно применить сразу но большие отклонения значений в течении дня будут более заметны поэтому целесообразно сначала перепаять резонатор а только потом ввести коррекцию. Значения коррекции будем вводить вручную через меню. Давайте подумаем более детально над самим процессом коррекции.

  1. Значение коррекции будем сохранять в ЕЕПРОМ. Т.к. коррекция может быть как и положительная (часы отстают) так и отрицательная (часы убегают) то сохранять будем в ЕЕПРОМ два значения: первое- знак коррекции 0- часы отстают, 1- часы убегают, и второе- значение собственно значение коррекции.
  2. Когда будем корректировать значение. Я предлагаю корректировать в полночь. Например часы убегают на 15 секунд в сутки. При достижении 0 час 0 мин 15 секунд вызываем функцию time.settime с установкой на 0 час 0 мин 0 сек и все… Часы скорректированы. Аналогично будет работать функция и при отставании. Т.е нам будет 3 условия. Об этом будет ниже.
  3. Как вводить значение коррекции. Вопрос поставлен немного некорректно но за какой период времени будет вводиться отклонение. Например измерение проводилось за день, неделю, 10 дней, месяц и т.д. Соответственно коррекция должна быть рассчитанной. Например за 10 дней часы убежали на 123 секунд, значит в день часы убегают на 123/10= 12,3 секунды. Можно предусмотреть и данный вариант но я решил сделать дневную коррекцию. Если вам уж очень надо сделать плавающую коррекцию то выделите для этого еще одну ячейку ЕЕПРОМ и заносите туда количество дней. Еще раз напомню что значение ячейки ЕЕПРОМ не могут быть выше 255. Старайтесь исходить из этих данных.
  4. Теперь наверное самая запутанная часть. Каждый человек считает любую ситуацию относительно своего чувства и мировоззрения. Приведу пример с нашими часами. Возьмем одну ситуацию. Например для меня. Я как программист считаю что если часы отстают то и нужно ввести время отставания с ОТРИЦАТЕЛЬНЫМ (часы отстают все таки, значит минус) знаком и потом добавлять отстающее значение. Теперь другая ситуация. Человек считает что часы отстают и ему надо ДОБАВИТЬ отстающие секунды. Т.е. в его понимании коррекция должна уже быть со знаком ПЛЮС (т.е. надо добавить отстающие секунды). Как к этому отнестись и описать для каждого индивидуально… Я пока не представляю. Если кто знает- отпишитесь в комментариях.
  5. Еще одна проблема будет возникать при полном отключении питания на часы. Например в 22.00 отключилось электричество у вас в квартире. В 2 часа ночи оно включилось но коррекция так и не произошла т.к. время было уже упущено. Следует понимать что время будет переустанавливать Ардуино в RTC  а не сам RTC. Если отключения будут происходить каждую ночь в течение 7 дней то отклонения будут уже большими. По всем прикидкам нужно ввести еще одну ячейку в ЕЕПРОМ в которую будет записываться значения дня и по разнице между днями проводить корректировку. Например из примера выше возьмем значение 12,3 секунды в день. За неделю часы убегут на 12,3*7=86,1 сек. Больше минуты. Об этом тоже стоит подумать, но мы будем исходить из того что у вас не отключат питание каждую ночь и поэтому коррекция будет происходить каждую ночь в 24 часа.

Как видите на данном примере приходится решать задачи настолько далекие от программирования что очень много времени уходит именно на такие вот «мелочи».

На этом подключение RTC DS1307 закончено. В следующем уроке мы будем программировать собственно программу управления часами. После этого останется только установить часы в корпус. Спасибо за внимание.

<-Урок 7.4

 

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