Какой модуль часов для ардуино due. Часы на Arduino без использования модуля RTC

Какой модуль часов для ардуино due. Часы на Arduino без использования модуля RTC

04.05.2019

Одним из первых проектов, которые новички собирают на основе платы Arduino, являются простые часы, ведущие отсчет времени. В основном такие часы основаны на подключаемом к Arduino модуле RTC (Real Time Clock или Часы реального времени). Сегодня на рынке электронных компонентов доступны разные модели RTC, различающиеся точностью и ценой. Среди распространенных моделей можно назвать DS1302, DS1307, DS3231.



Но часы на Arduino можно сделать и без использования RTC, особенно если не получается достать такие модули. Конечно, точность в данном случае будет невелика, поэтому проект скорее должен рассматриваться как учебный.


Принцип работы таких часов довольно прост. Каждый раз, когда вы включаете эти часы на Arduino, вы должны будете установить для них текущее значение времени, также как и любые аналоговые часы. Такие часы, безусловно, лучше не использовать в своей повседневной жизни при долгой их активности без перезагрузки и дальнейшей настройки, поскольку рассинхронизация с текущим временем в процессе длительной эксплуатации может быть существенной.


Данные часы можно собрать на обычной макетной плате, поскольку здесь не потребуется много компонентов. Основным нашим звеном здесь будет плата Arduino Uno. Для отображения времени можно взять ЖК-дисплей 16x2. Для изменения настроек времени следует подключить две кнопки (для часов и минут). Кнопки подключаются к Aduino через резисторы 10 КОм. Чтобы изменять яркость дисплея потребуется потенциометр на 10 КОм. Схема подключения всех этих компонентов к плате Arduino Uno представлена ниже.



Теперь следует запрограммировать Arduino. Простой код (скетч), позволяющий выводить время на экран LCD-дисплея приведен ниже.


#include LiquidCrystal lcd(12,11,5,4,3,2); int h=12; int m; int s; int flag; int TIME; const int hs=8; const int ms=9; int state1; int state2; void setup() { lcd.begin(16,2); } void loop() { lcd.setCursor(0,0); s=s+1; lcd.print("TIME:"); lcd.print(h); lcd.print(":"); lcd.print(m); lcd.print(":"); lcd.print(s); if(flag<12)lcd.print("AM"); if(flag==12)lcd.print("PM"); if(flag>12)lcd.print("PM"); if(flag==24)flag=0; delay(1000); lcd.clear(); if(s==60){ s=0; m=m+1; } if(m==60) { m=0; h=h+1; flag=flag+1; } if(h==13) { h=1; } lcd.setCursor(0,1); lcd.print("HAVE A NICE DAY"); //-------Time // setting-------// state1=digitalRead(hs); if(state1==1) { h=h+1; flag=flag+1; if(flag<12)lcd.print("AM"); if(flag==12)lcd.print("PM"); if(flag>12)lcd.print("PM"); if(flag==24)flag=0; if(h==13)h=1; } state2=digitalRead(ms); if(state2==1){ s=0; m=m+1; } }

   Благодарим Вас за интерес к информационному проекту сайт.
   Если Вы хотите, чтобы интересные и полезные материалы выходили чаще, и было меньше рекламы,
   Вы можее поддержать наш проект, пожертвовав любую сумму на его развитие.

В данной статье мы рассмотрим, как сделать точные часы на базе Arduino или AVR-микроконтроллера микросхемы часов реального времени DS1307. Время будет выводиться на LCD дисплей.

Что необходимо

  • компьютер с установленной Arduino IDE;
  • микросхема DS1307 или модуль RTC на ее основе ;
  • комплектующие из списка элементов.

Вы можете заменить плату Arduino на контроллер Atmel, но убедитесь, что у него достаточно входных и выходных выводов и есть аппаратная реализация интерфейса I2C. Я использую ATMega168A-PU. Если вы будете использовать отдельный микроконтроллер, то вам понадобится программатор, например, AVR MKII ISP.

Предполагается, что читатель знаком с макетированием, программированием в Arduino IDE и имеет некоторые знания языка программирования C. Обе программы, приведенные ниже, не нуждаются в дополнительном разъяснении.

Введение

Как микроконтроллеры отслеживают время и дату? Обычный микроконтроллер обладает функцией таймера, который стартует от нуля при подаче напряжения питания, а затем начинает считать. В мире Arduino мы можем использовать функцию millis() , чтобы узнать, сколько прошло миллисекунд с того времени, когда было подано напряжение питания. Когда вы снимете и снова подадите питания, она начнет отсчет с самого начала. Это не очень удобно, когда дело доходит до работы с часами и датами.

Вот здесь и будет удобно использование микросхемы RTC (Real Time Clock, часов реального времени). Эта микросхема с батарейкой 3В или каким-либо другим источником питания следит за временем и датой. Часы/календарь обеспечивают информацию о секундах, минутах, часах, дне недели, дате, месяце и годе. Микросхема корректно работает с месяцами продолжительностью 30/31 день и с високосными годами. Связь осуществляется через шину I2C (шина I2C в данной статье не обсуждается).

Если напряжение на главной шине питания Vcc падает ниже напряжения на батарее Vbat, RTC автоматически переключается в режим низкого энергопотребления от резервной батареи. Резервная батарея - это обычно миниатюрная батарея (в виде «монетки», «таблетки») напряжением 3 вольта, подключенная между выводом 3 и корпусом. Таким образом, микросхема по-прежнему будет следить за временем и датой, и когда на основную схему будет подано питание, микроконтроллер получит текущие время и дату.

В этом проекте мы будем использовать DS1307. У этой микросхемы вывод 7 является выводом SQW/OUT (выходом прямоугольных импульсов). Вы можете использовать этот вывод для мигания светодиодом и оповещения микроконтроллера о необходимости фиксации времени. Мы будем делать и то, и другое. Ниже приведено объяснение работы с выводом SQW/OUT.

Для управления работой вывода SQW/OUT используется регистр управления DS1307.

Бит 7: управление выходом (OUT) Этот бит управляет выходным уровнем вывода SQW/OUT, когда выход прямоугольных импульсов выключен. Если SQWE = 0, логический уровень на выводе SQW/OUT равен 1, если OUT = 1, и 0, если OUT = 0. Первоначально обычно этот бит равен 0. Бит 4: включение прямоугольных импульсов (SQWE) Этот бит, когда установлен в логическую 1, включает выходной генератор. Частота прямоугольных импульсов зависит от значений битов RS0 и RS1. Когда частота прямоугольных импульсов настроена на значение 1 Гц, часовые регистры обновляются во время спада прямоугольного импульса. Первоначально обычно этот бит равен 0. Биты 1 и 0: выбор частоты (RS) Эти биты управляют частотой выходных прямоугольных импульсов, когда выход прямоугольных импульсов включен. Следующая таблица перечисляет частоты прямоугольных импульсов, которые могут быть выбраны с помощью данных битов. Первоначально обычно эти биты равны 1.

Данная таблица поможет вам с частотой:

Выбор частоты прямоугольных импульсов DS1307
Частота импульсов Бит 7 Бит 6 Бит 5 Бит 4 Бит 3 Бит 2 Бит 1 Бит 0
1 Гц 0 0 0 1 0 0 0 0
4,096 кГц 0 0 0 1 0 0 0 1
8,192 кГц 0 0 0 1 0 0 1 0
32,768 кГц 0 0 0 1 0 0 1 1

Если вы подключили светодиод и резистор к выводу 7 и хотите, чтобы светодиод мигал с частотой 1 Гц, то должны записать в регистр управления значение 0b00010000. Если вам нужны импульсы 4,096 кГц, то вы должны записать 0b000100001. В этом случае, чтобы увидеть импульсы вам понадобится осциллограф, так как светодиод будет мигать так быстро, что будет казаться, что он светится постоянно. Мы будем использовать импульсы с частотой 1 Гц.

Аппаратная часть

Ниже показана структурная схема того, что нам необходимо.

Мы нужны:

  • разъем ISP (In System Programming, внутрисхемное программирование) для прошивки микроконтроллера;
  • кнопки для установки времени и даты;
  • микроконтроллер для связи с RTC через шину I2C;
  • дисплей для отображения даты и времени.

Принципиальная схема:


Перечень элементов

Ниже приведен скриншот из Eagle:


Программное обеспечение

В этом руководстве мы будем использовать два различных скетча: один, который записывает время и дату в RTC, и один, который считывает время и дату из RTC. Мы сделали так потому, что так вы сможете получить более полное представление о том, что происходит. Мы будем использовать одну и ту же схему для обеих программ.

Сперва мы запишем время и дату в RTC, что аналогично установке времени на часах.

Мы используем две кнопки. Одну для увеличения часов, минут, даты, месяца, года и дня недели, а вторую для выбора между ними. Приложение не считывает состояния каких-либо критически важных датчиков, поэтому мы будем использовать прерывания для проверки, нажата ли кнопка, и обработки дребезга контактов.

Следующий код устанавливает значения и записывает их в RTC:

#include // Определение выводов LCD #define RS 9 #define E 10 #define D4 8 #define D5 7 #define D6 6 #define D7 5 LiquidCrystal lcd(RS, E, D4, D5, D6, D7); // Прерывание 0 – это вывод 4 микроконтроллера (цифровой вывод 2 Arduino) int btnSet = 0; // Прерывание 1 – это вывод 5 микроконтроллера (цифровой вывод 3 Arduino) int btnSel = 1; // Флаги прерываний volatile int togBtnSet = false; volatile int togBtnSel = false; volatile int counterVal = 0; // Переменные для отслеживания, где в "меню" мы находимся volatile int menuCounter = 0; // Массив значений volatile int menuValues; // 0=часы, 1=минуты, 2=день месяца, 3=месяц, 4=год, 5=день недели // Заголовки меню char* menuTitles = { "Set hour. ", "Set minute. ", "Set date. ", "Set month. ", "Set year. ", "Set day (1=mon)." }; // Массив дней недели char* days = { "NA", "Mon", "Tue", "Wed", "Thu", "Fre", "Sat", "Sun" }; void setup() { // Объявление прерываний, выполнение функций increaseValue/nextItem // по переднему фронту на btnXXX attachInterrupt(btnSet, increaseValue, RISING); attachInterrupt(btnSel, nextItem, RISING); Wire.begin(); lcd.begin(16,2); showWelcome(); } // Функция прерывания void increaseValue() { // Переменные static unsigned long lastInterruptTime = 0; // Создание метки времени unsigned long interruptTime = millis(); // Если timestamp - lastInterruptTime больше, чем 200 if (interruptTime - lastInterruptTime > 200) { togBtnSet = true; // Увеличить counterVal на 1 counterVal++; } // Установка lastInterruptTime равным метке времени // так мы знаем, что прошли дальше lastInterruptTime = interruptTime; } // Функция прерывания для следующего пункта меню void nextItem() { static unsigned long lastInterruptTime = 0; unsigned long interruptTime = millis(); if (interruptTime - lastInterruptTime > 200) { togBtnSel = true; // Увеличить счетчик меню, так мы переходим к следующему пункту меню menuCounter++; if (menuCounter > 6) menuCounter = 0; // Поместить counterVal в элемент массива счетчиков меню menuValues = counterVal; // Сбросить counterVal, сейчас мы начинаем с 0 для следующего пункта меню counterVal = 0; } lastInterruptTime = interruptTime; } // Функция преобразования десятичных чисел в двоично-десятичный код byte decToBCD(byte val) { return ((val/10*16) + (val%10)); } // Функция проверки, была ли нажата кнопки листания меню, // и обновления заголовка на дисплее. void checkCurrentMenuItem() { if (togBtnSel) { togBtnSel = false; lcd.setCursor(0,0); lcd.print(menuTitles); } } // Функция проверки, была ли нажата кнопка увеличения значения, // и обновления переменной в соответствующем элементе массива, // плюс вывод нового значения на дисплей. void checkAndUpdateValue() { // Проверить, если прерывание сработало = кнопка нажата if (togBtnSet) { // Обновить значение элемента массива с counterVal menuValues = counterVal; // Сбросить флаг прерывания togBtnSet = false; lcd.setCursor(7,1); // Напечатать новое значение lcd.print(menuValues); lcd.print(" "); } } // Короткое приветственное сообщение, теперь мы знаем, что всё нормально void showWelcome() { lcd.setCursor(2,0); lcd.print("Hello world."); lcd.setCursor(3,1); lcd.print("I"m alive."); delay(500); lcd.clear(); } // Запись данных в RTC void writeRTC() { Wire.beginTransmission(0x68); Wire.write(0); // начальный адрес Wire.write(0x00); // секунды Wire.write(decToBCD(menuValues)); // преобразовать минуты в BCD-код и записать Wire.write(decToBCD(menuValues)); // преобразовать часы в BCD-код и записать Wire.write(decToBCD(menuValues)); // преобразовать день недели в BCD-код и записать Wire.write(decToBCD(menuValues)); // преобразовать день месяца в BCD-код и записать Wire.write(decToBCD(menuValues)); // преобразовать месяц в BCD-код и записать Wire.write(decToBCD(menuValues)); // преобразовать год в BCD-код и записать Wire.write(0b00010000); // включить прямоугольные импульсы 1 Гц на выводе 7 Wire.endTransmission(); // закрыть передачу } // Показать время // Чтобы посмотреть, что RTC работает, вам необходимо посмотреть другую программу void showTime() { lcd.setCursor(0,0); lcd.print(" "); lcd.print(menuValues); lcd.print(":"); // часы lcd.print(menuValues); lcd.print(":"); lcd.print("00 "); // минуты lcd.setCursor(3,1); lcd.print(days); lcd.print(" "); // день недели lcd.print(menuValues); lcd.print("."); // дата lcd.print(menuValues); lcd.print("."); // месяц lcd.print(menuValues); lcd.print(" "); // год // вызов функции writeRTC writeRTC(); } void loop() { if (menuCounter < 6) { checkCurrentMenuItem(); checkAndUpdateValue(); } else { showTime(); } }

Эта программа начинается с короткого приветственного сообщения. Это сообщение говорит нам, что подано питание, LCD работает, и что программа запустилась. Так как скетч служит лишь для того, чтобы показать, как записать данные из Arduino в RTC DS1307, то в нем отсутствует вспомогательный функционал (проверка, попадают ли значения в допустимые диапазоны; зацикливание при нажимании на кнопку увеличения значения, то есть сброс на 0, когда значение, например, минут превысит 60, и т.д.)

// Включение заголовочных файлов #include #include // Определение выводов LCD #define RS 9 #define E 10 #define D4 8 #define D5 7 #define D6 6 #define D7 5 LiquidCrystal lcd(RS, E, D4, D5, D6, D7); // Вывод, который будет принимать импульсы от RTC volatile int clockPin = 0; // Переменные времени и даты byte second; byte minute; byte hour; byte day; byte date; byte month; byte year; // Массив дней недели char* days = { "NA", "Mon", "Tue", "Wed", "Thu", "Fre", "Sat", "Sun" }; // Функция, которая выполняется только при запуске void setup() { pinMode(clockPin, INPUT); pinMode(clockPin, LOW); Wire.begin(); lcd.begin(16,2); showWelcome(); } // Короткое приветственное сообщение, теперь мы знаем, что всё нормально void showWelcome() { lcd.setCursor(2,0); lcd.print("Hello world."); lcd.setCursor(3,1); lcd.print("I"m alive."); delay(500); lcd.clear(); } byte bcdToDec(byte val) { return ((val/16*10) + (val%16)); } // Это выполняется постоянно void loop() { // Если уровень на выводе clockPin высокий if (digitalRead(clockPin)) { // Начать передачу I2C, адрес 0x68 Wire.beginTransmission(0x68); // Начать с адреса 0 Wire.write(0); // Закрыть передачу Wire.endTransmission(); // Начать чтение 7 двоичных данных от 0x68 Wire.requestFrom(0x68, 7); second = bcdToDec(Wire.read()); minute = bcdToDec(Wire.read()); hour = bcdToDec(Wire.read()); day = bcdToDec(Wire.read()); date = bcdToDec(Wire.read()); month = bcdToDec(Wire.read()); year = bcdToDec(Wire.read()); // Форматирование и отображение времени lcd.setCursor(4,0); if (hour < 10) lcd.print("0"); lcd.print(hour); lcd.print(":"); if (minute < 10) lcd.print("0"); lcd.print(minute); lcd.print(":"); if (second < 10) lcd.print("0"); lcd.print(second); lcd.setCursor(2,1); // Форматирование и отображение даты lcd.print(days); lcd.print(" "); if (date < 10) lcd.print("0"); lcd.print(date); lcd.print("."); if (month < 10) lcd.print("0"); lcd.print(month); lcd.print("."); lcd.print(year); } }

Заключение

В данной статье мы рассмотрели микросхему DS1307 от Maxim Integrated и написали две демонстрационные программы: одну для установки времени и даты и вторую для чтения времени и даты. Для проверки нажатия кнопок мы использовали прерывания, в которых также избавлялись от влияния дребезга контактов.

Фото и видео

Установка времени

Считывание времени

Итак, часы реального времени. Эта полезная штучка решает большинство полезных задач, связанных со временем. Допустим управление поливом в 5 часов утра на даче. Или включение и выключение освещения в определённый момент. По дате можно запускать отопление в каком-нибудь доме. Вещь достаточно интересная и полезная. А конкретно? Мы с вами рассмотрим часы реального времени DS1302 для популярной платформы Arduino.

Из этой статьи вы узнаете:

Доброго времени суток, уважаемые читатели блока kip-world! Как ваши дела? Напишите в комментариях, вы увлекаетесь робототехникой? Что значит для вас эта тема?

У меня ни на минуту не покидает мысль об этом. Я сплю и вижу, когда мы наконец — то придём к тому, что каждый сможет позволить себе купить персонального робота — помощника. Не важно, чем он будет заниматься, уборкой мусора, стрижкой газонов, мойкой автомобиля.

Я просто представляю себе, насколько сложные алгоритмы они должны содержать в своих «мозгах».

Ведь мы придём к тому, что мы будем так же прошивать ПО, как на персональных компах. Так же скачивать прикладные программы. Пришивать руки, ноги, менять клешни, манипуляторы.

Посмотрите фильмы «Я-робот», «Искусственный интеллект», «Звёздных воинов».

Японцы уже давно внедряют свои разработки. Чем мы хуже?? У нас очень слабая популярность. Я знаю немногих разработчиков. По пальцам пересчитать. Мы занимаемся другим. Мы перекупщики. Просто покупаем готовые наборчики, роботов — игрушек и всякую дребедень.

Почему не разрабатываем вот это:

Или вот это:

Я закончил свои размышления вслух. Давайте мы с вами поговорим о подключении Таймера часов реального времени DS1302 к Arduino.

Часы реального времени DS1302

Контроллер Arduino не имеет своих собственных часов. Поэтому в случае необходимости нужно дополнять специальной микросхемой DS1302.

По питанию эти платы могут использовать свой элемент питания, или запитываться непосредственно с платы Arduino.

Таблица распиновки:

Схема подключения c Arduino UNO:


Способ программирования Arduino для работы с DS1302

Обязательно нужно скачать действующую библиотеку из надёжных источников.

Библиотека позволяет считывать и записывать параметры реального времени. Небольшое описание я привожу ниже:

#include // Подключаем библиотеку.
iarduino_RTC ОБЪЕКТ (НАЗВАНИЕ [, ВЫВОД_RST [, ВЫВОД_CLK [, ВЫВОД_DAT ]]]); // Создаём объект.

Функция begin (); // Инициализация работы RTC модуля.

Функция settime (СЕК [, МИН [, ЧАС [, ДЕНЬ [, МЕС [, ГОД [, ДН ]]]]]]); // Установка времени.

Функция gettime ([ СТРОКА ]); // Чтение времени.

функция blinktime (ПАРАМЕТР [ ЧАСТОТА ] ); // Заставляет функцию gettime «мигать» указанным параметром времени.

функция period (МИНУТЫ ); // Указывает минимальный период обращения к модулю в минутах.

Переменная seconds // Возвращает секунды от 0 до 59.

Переменная minutes // Возвращает минуты от 0 до 59.

Переменная hours // Возвращает часы от 1 до 12.

Переменная Hours // Возвращает часы от 0 до 23.

Переменная midday // Возвращает полдень 0 или 1 (0-am, 1-pm).

Переменная day // Возвращает день месяца от 1 до 31.

Переменная weekday // Возвращает день недели от 0 до 6 (0-воскресенье, 6-суббота).

Переменная month // Возвращает месяц от 1 до 12.

Переменная year // Возвращает год от 0 до 99.

Пишем простенькую программу. Установка текущего времени в RTC модуль (DS1302):

Arduino

#include iarduino_RTC time(RTC_DS1302,6,7,8); void setup() { delay(300); Serial.begin(9600); time.begin(); time.settime(0,51,21,27,10,15,2); // 0 сек, 51 мин, 21 час, 27, октября, 2015 года, вторник } void loop(){ if(millis()%1000==0){ // если прошла 1 секунда Serial.println(time.gettime("d-m-Y, H:i:s, D")); // выводим время delay(1); // приостанавливаем на 1 мс, чтоб не выводить время несколько раз за 1мс } }

#include

iarduino _ RTCtime (RTC_DS1302 , 6 , 7 , 8 ) ;

void setup () {

delay (300 ) ;

Serial . begin (9600 ) ;

time . begin () ;

time . settime (0 , 51 , 21 , 27 , 10 , 15 , 2 ) ; // 0 сек, 51 мин, 21 час, 27, октября, 2015 года, вторник

void loop () {

if (millis () % 1000 == 0 ) { // если прошла 1 секунда

Serial . println (time . gettime ("d-m-Y, H:i:s, D" ) ) ; // выводим время

delay (1 ) ; // приостанавливаем на 1 мс, чтоб не выводить время несколько раз за 1мс

Считываем текущее время с RTC модуля (DS1302) и выводим в "Последовательный порт" :

#include iarduino_RTC time(RTC_DS1302,6,7,8); void setup() { delay(300); Serial.begin(9600); time.begin(); } void loop(){ if(millis()%1000==0){ // если прошла 1 секунда Serial.println(time.gettime("d-m-Y, H:i:s, D")); // выводим время delay(1); // приостанавливаем на 1 мс, чтоб не выводить время несколько раз за 1мс } }

«. Знакомимся с модулем часов реального времени DS3231. В статье видео-инструкция, листинги программ, назначение и способы подключения к Arduino модулей из семейства DS.

Модуль часов реального времени DS3231

Что такое модуль часов реального времени DS3231?

Модуль часов реального времени - это электронная схема, предназначенная для учета хронометрических данных (текущее время, дата, день недели и др.), представляет собой систему из автономного источника питания и учитывающего устройства.

Модуль DS3231 по сути представляет из себя обыкновенные часы. В платах Arduino уже есть встроенный датчик времени Millis , однако он работает только при поданном питании на плату. При отключении и дальнейшем включении Arduino отсчет времени Millis сбросится до нуля. А DS3231 имеет на борту батарейку, которая даже при отключенной плате Arduino продолжает «питать» модуль, позволяя ему измерять время.

Модуль можно использовать в качестве часов или будильника, построенных на базе плат Arduino. Или же в качестве оповещения для различных систем, к примеру в «Умном доме».

Технические характеристики DS3231:

  • модуль производит подсчет часов, минут, секунд, дат, месяцев, лет (високосные года учитываются до 2100 года);
  • для подключения к различным устройствам, часы подключаются по I2C интерфейсу.

32К — Выход, предназначенный для подачи внешнего питания >12В.

SQW — Программируемый выход Square-Wave сигнала.

SCL – Через этот пин по интерфейсу I2C происходит обмен данными с часами.

SDA – Через этот пин передаются данные с часов.

VCC – Питание часов реального времени, нужно 5 вольт. Если на этот пин не поступает напряжение, часы переходят в спящий режим.

GND — Земля.

Схема подключения часов реального времени DS3231 и простейшая программа

Пины SDA и SCL на разных платах Arduino:

SDA SCL
UNO A4 A5
Mini A4 A5
Nano A4 A5
Mega2560 20 21
Leonardo 2 3

Подключим модуль часов реального времени к Arduino UNO. SDA — пин A4, SCL — пин A5.

Для работы модели подойдет следующая программа (программу вы можете просто скопировать в Arduino IDE):

#include

void setup() {
delay(300);
Serial.begin(9600);
time.begin();
}
void loop(){



}
}

В данном скетче просто идет отсчет времени.

В первую очередь в сктече подключение библиотеки iarduino_RTC.h.

Там же укажите точное название своего модуля для корректной работы с ним.

В итоге получаем вывод времени с модуля DS3231 в монитор порта. Идет вывод часов, минут, секунд.

В следующем скетче добавим функцию settime , позволяющую установить начальное время отсчета.

#include
iarduino_RTC time(RTC_DS3231);
void setup() {
delay(300);
Serial.begin(9600);
time.begin();
time.settime(0,0,18,24,04,17,1); // 0 сек, 0 мин, 18 час, 24, апреля, 2017 года, понедельник
}
void loop(){
if(millis()%1000==0){ // если прошла 1 секунда
Serial.println(time.gettime("d-m-Y, H:i:s, D")); // выводим время
delay(1); // приостанавливаем на 1 мс, чтоб не выводить время несколько раз за 1мс
}
}

В примере время начинает отсчитываться с 0 сек, 0 мин, 18 час, 24, апреля, 2017 года, понедельник.

Посты по урокам:

  1. Первый урок: .
  2. Второй урок: .
  3. Третий урок: .
  4. Четвертый урок: .
  5. Пятый урок: .
  6. Шестой урок: .
  7. Седьмой урок: .
  8. Восьмой урок: .
  9. Девятый урок:

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

С помощью этого модуля можно отслеживать время в ваших проектах на Arduino даже в случае перепрограммирования или отключения питания. Это один из необходимых элементов для проектов будильников, сигнализаций, снятия показаний с датчиков в режиме реального времени. Одна из самых популярных моделей модуля часов реального времени - DS1307. Именно на нем мы и остановимся. Модуль отлично сочетается с микроконтроллерами Arduino, на которых питание логики равно 5 В.

Особенности модуля от компании-производителя Adafruit (китайцы предлагают аналогичные варианты раза в три-четыре дешевле):

  • Все включено: чип, обвязка, батарейка;
  • Легко собирается и прост в использовании;
  • Устанавливается на любую макетную плату или подключается напрямую с помощью проводов;
  • Есть отличные библиотеки и скетчи-примеры;
  • Два отверстия для монтажа;
  • Продолжительность работы - около пяти лет!

Модуль часов реального времени может быть уже распаянным, а может продаваться в виде отдельных комплектующих, пайка которых займет около 15-ти минут, не более.

Что такое часы реального времени?

Часы реально времени - это... часы. Модуль работает от автономного питания - батарейки и продолжает вести отсчет времени, даже если на вашем проекте на Arduino пропало питание. Используя модуль реального времени, вы можете отслеживать время, даже если вы захотите внести изменения в ваш скетч и перепрограммировать микроконтроллер.

На большинстве микроконтроллеров, в том числе и Arduino, есть встроенный счетчик временни, который называется millis(). Есть и встроенные в чип таймеры, которые могут отслеживать более длительные промежутки времени (минуты или дни). Так зачем же вам отдельным модуль часов? Основная проблема в том, что millis() отслеживает время только с момента подачи питания на Arduino. То есть, как только вы отключили плату, таймер сбрасывается в 0. Вша Arduino не знает, что сейчас, например, четверг или 8-е марта. Все, чего вы можете добиться от встроенного счетчика - это "Прошло 14000 миллисекунд с момента последнего включения".

Например вы создали программу и хотите вести отсчет времени с этого момента. Если вы отключите питание микроконтроллера, счетчик времени собьется. Примерно так, как это происходит с дешевыми китайскими часами: когда садится батарейка, они начинают мигать с показанием 12:00.

В некоторых проектах Arduino вам понадобится надежный контроль времени без прерываний. Именно в таких случаях используется внешний модуль часов реального времени. Чип, который используется в подобных часах, отслеживает года и даже знает сколько дней в месяце (единственно, что обычно не учитывается - это переход на летнее и зимнее время, так как подобные переводы разные в разных частях мира).

На рисунке ниже показана материнская плата компьютера с часами реального времени DS1387. В часах используется литиевая батарея, поэтому они разрослись в размерах.

Мы рассмотрим пример использования часов реального времени DS1307. Это дешевый, легкий в использовании модуль, который работает несколько лет от небольшой батарейки.

Пока батарейка в самом модуле не исчерпает свой заряд, DS1307 будет вести отсчет времени, даже если Arduino отключен от питания или перепрограммируется.

Узлы, из которых состоит модуль часов реального времени

Детали модуля часов реального времени DS1307 от компании Adafruit
Рисунок Обозначение Описание Производитель Количество
IC2 Чип часов реального времени DS1307 1
Q1 32.768 КГц, 12.5 пФ кристалл Generic 1
R1, R2 1/4 Вт 5% 2.2 КОм резистор Красный, Красный, Красный, Золотой Generic 2
C1 0.1 мкФ керамический конденсатор Generic 1
Рельса на 5 контактов (1x5) Generic 1
Батарейка 12 мм 3 В литиевая батарейка CR1220 1
12mm coin cell holder Keystone 3001 1
Плата Adafruit Industries 1

Сборка модуля часов реального времени

Сборка часов реального времени DS1307 компании Adafruit
Фото Пояснения

Подготовьтесь к сборке. Проверьте наличие всех необходимых деталей и инструментов. Установите монтажную плату в тисках.

Нанесите немного припоя на отрицательный контакт батареи.

Установите два резистора 2.2 КОм и керамический конденсатор. Как именно вы их расположите - неважно. Полярность не имеет значения. После этого установите кристалл (также симметрично), держатель (холдер) для батарейки и чип часов реального времени. Чип модуля реального времени надо установить таким образом, чтобы отметка (паз) на чипе располагалась в соответствии с обозначением на монтажной плате. Внимательно посмотрите на фото слева, там чип установлен верно.


Чтобы холдер для батарейки не выпадал, лучше его припаять сверху. После этого переверните плату и и припаяйте оставшиеся контакты.

Удалите остатки контактов от резисторов, кристалла и конденсатора.

Если вы хотите использовать контакты для установки модуля на беспаечную монтажную плату, установите рельсу контактов на макетку, модуль часов реального времени сверху и припаяйте контакты.

Установите батарейку. Плоская часть батареи должна быть сверху. В среднем батарейка будет служить около 5 лет. Даже если батарейка села, не оставляйте слот для нее пустым.

Библиотека Arduino для работы с DS1307

DS1307 легко подключается к любому микроконтроллеру с питанием логики 5 В и возможностью I2C подключения. Мы рассмотрим подключение и использование этого модуля с Arduino .

Будем использовать библиотеку RTClib для получения и настройки показаний с DS1307. Если у вас есть вопросы по учтановке дополнительных библиотек Arduino - ознакомьтесь с этой инструкцией .

В статье рассмотрен пример часов реального времени от Adafruit, но вы можете с тем же успехом использовать китайские аналоги. Принцип работы и подключения не отличается.

  • КУПИТЬ Arduino Uno R3 ;
  • КУПИТЬ Breadboard ;
  • КУПИТЬ модуль часов реального времени DS1307 ;

На часах реального премени 5 пинов: 5V, GND, SCL, SDA и SQW.

  • 5V используется для питания чипа модуля часов реального времени, когда вы делаете к нему запрос для получения данных о времени. Если сигнал 5 В не поступает, чип переходит в "спящий" режим.
  • GND - общая земля. Обязательно подключается в схему.
  • SCL - контакт i2c часов - необходим для обмена данными с часами реального времени.
  • SDA - контакт, по которому через i2c передаются данные с часов реального времени.
  • SQW дает возможность настроить вывод данных в виде square-wave. В большинстве случаев этот контакт не используется.

Если вы настроили аналоговый пин 3 (цифровой 17) в режим OUTPUT и HIGH, а аналоговый пин 2 (цифровой 16) в режим OUTPUT и LOW, вы можете запитывать часы реального времени непосредственно от этих контактов!

Подключите аналоговый пин 4 на Arduino к SDA. Аналоговый пин 5 на Arduino подключите к SCL.


Скетч для Arduino

Проверка часов реального времени

Первый скетч, который стоит запустить - это программа, которая будет считывать данные с модуля часов реального времени раз в секунду.

Для начала давайте посмотрим, что произойдет, если мы извлечем батарейку и заменим ее на другую, пока Arduino не подключен к USB. Подождите 3 секунды и извлеките батарейку. В результате чип на часах реального времени перезагрузится. После этого вставьте код, который приведен ниже (код также можно выгрузить в меню Examples→RTClib→ds1307 в Arduino IDE) и загрузите его на Arduino.

Вам также понадобится библиотека OneWire.h, скачть ее можно

.

// функции даты и времени с использованием часов реального времени DS1307, подключенные по I2C. В скетче используется библиотека Wire lib

#include <Wire.h>

#include "RTClib.h"

Serial.begin(57600);

if (! RTC.isrunning()) {

Serial.println("RTC is NOT running!");

// RTC.adjust(DateTime(__DATE__, __TIME__));

DateTime now = RTC.now();

Serial.print("/");

Serial.print("/");

Serial.print(now.day(), DEC);

Serial.print(" ");

Serial.print(":");

Serial.print(":");

Serial.println();

Serial.print(now.unixtime());

Serial.print("s = ");

Serial.println("d");

// рассчитываем дату: 7 дней и 30 секунд

DateTime future (now.unixtime() + 7 * 86400L + 30);

Serial.print(" now + 7d + 30s: ");

Serial.print(future.year(), DEC);

Serial.print("/");

Serial.print(future.month(), DEC);

Serial.print("/");

Serial.print(future.day(), DEC);

Serial.print(" ");

Serial.print(future.hour(), DEC);

Serial.print(":");

Serial.print(future.minute(), DEC);

Serial.print(":");

Serial.print(future.second(), DEC);

Serial.println();

Serial.println();

Теперь откройте окно серийного монитора и убедитесь, что скорость передачи данных установлена корректно: на 57600 bps.

В результате вы должны увидеть в окне серийного монитора примерно следующее:


Если в часах реального времени пропадет питание, отобразится 0:0:0. Секунды отсчитываться перестанут. После настройки времени, пойдет новый отсчет. Именно по этой причине извлекать батарейку во время работы модуля часов реального времени нельзя.

Настройка времени на модуле часов

В этом же скетче раскомментируйте строку, которая начинается с RTC.adjust:

// строка ниже используется для настройки даты и времени часов

RTC.adjust(DateTime(__DATE__, __TIME__));

Процесс настройки даты и времени реализован очень элегантно. В эту строку попадают данные с вашего счетчика на персональном компьютере (в момент компилляции кода). Эти данные используются для прошивки вашего модуля часов реального времени. То есть, если время на вашем ПК настроено неверно, рекомендуем сначала исправить этот баг, а потом переходить к прошивке модуля часов для Arduino.

После настройки, откройте серийный монитор и убедитесь, что часы настроены корректно:


Все. С этого момента и на протяжении ближайших нескольких лет настраивать DS1307 не придется.

Считывание показаний времени с DS1307

После настройки часов реального времени DS1307, может отправлять к ним запросы. Давайте рассмотрим часть скетча, в которой реализованы эти запросы.

DateTime now = RTC.now();

Serial.print(now.year(), DEC);

Serial.print("/");

Serial.print(now.month(), DEC);

Serial.print("/");

Serial.print(now.day(), DEC);

Serial.print(" ");

Serial.print(now.hour(), DEC);

Serial.print(":");

Serial.print(now.minute(), DEC);

Serial.print(":");

Serial.print(now.second(), DEC);

Serial.println();

По сути существует один вариант для получения времени с использованием часов реального времени. Для этого используется функция now(), которая возвращает объект DateTime. В этом объекте содержаться данные про год, месяц, день, час, минуту и секунду.

Есть ряд библиотек для часов реального времени, в которых предусмотрены функции вроде RTC.year() и RTC.hour(). Эти функции вытягивают отдельно год и час. Но их использование сопряжено с рядом проблем: если вы сделаете запрос на вывод минут в момент времени, например, 3:14:59, то есть, прямо перед тем как показания минут должны приравняться к "15" (3:15:00), полученные данные будут равны 3:14:00 - то есть, вы потеряете одну минуту.

В общем, использование отдельных функций для вызова часа или года обосновано только в том случае, когда точность контроля времени с разбросом в одну минуту/года для вашего проекта не критична (как правило, это в тех случаях, когда показания снимаются редко - раз в сутки, раз в неделю). В любом случае, если вы хотите избежать погрешностей в показаниях, используйте now(), а уже из полученных данных тяните необходимые вам показания (минуты, года и т.п.).

Есть еще один формат данных, которые мы можем подучить - количество секунд от полуночи, 1-го января 1970 года. Для этого используется функция unixtime ():

Serial.print(" since 1970 = ");

Serial.print(now.unixtime());

Serial.print("s = ");

Serial.print(now.unixtime() / 86400L);

Serial.println("d");

Так как в одном дне 60*60*24 = 86400 секунд, можно перевести полученное значение в дни и года. Очень удобный вариант, если вам надо отследить, сколько времени прошло с момента последнего запроса. Например, если прошло 5 минут с момента последнего последнего обращения Arduino к часам реального времени DS1307, значение, которое вернет функция unixtime() будет больше на 300.

Оставляйте Ваши комментарии, вопросы и делитесь личным опытом ниже. В дискуссии часто рождаются новые идеи и проекты!



© 2024 beasthackerz.ru - Браузеры. Аудио. Жесткий диск. Программы. Локальная сеть. Windows