Если вы проектируете устройство, которому нужно всегда и везде знать точное время, вам пригодится модуль часов реального времени. Такие часы способны отсчитывать точное время и сохранять его даже при отключении основного питания, так как подразумевается их эксплуатация с батарейкой (обычно CR2032). В режиме работы без основного питания, часы способны отработать на такой батарейке c десяток лет!
Одним из наиболее часто используемых модулей ЧРВ (RTC – Real Time Clock) является микросхема DS1307 от Dallas Semiconductors. Точность хода микросхемы сильно зависит от внешнего кварца и его обвязки, поэтому на просторах Интернета данный модуль считается неточным.
Однако, существует «автономный» модуль – DS3231, который имеет встроенный кварц с термостабилизацией.
Его точность составляет 2ppm (partspermillion – частей на миллион). Такая погрешность зачастую незаметна и примерно равна погрешности наручных часов. При всех его плюсах, модуль ещё и совместим со всеми DS1307-ми библиотеками!
И в нашей сегодняшней статье мы поговорим о подключении данной микросхемы к микроконтроллерам Arduino.
Для реализации проекта из этой статьи нам потребуются следующие компоненты:
Подключение DS3231 к Arduino
Часы подключаются по двухпроводной шине IIC (Inter-IntegratedCircuit) через выводы SDA и SCL к SDA и SCL Arduino соответственно. Также необходимо подключить питание +5В и GND. Остальные выводы специфичны для DS3231 и не поддерживаются библиотеками для DS1307, да и не часто используются.
Обратите внимание – выводы шины IICна разных контроллерах расположены на разных пинах:
Контакт SDA | Контакт SCL | |
---|---|---|
На Arduino UNO, Nano, Pro Mini etc. | A4 | A5 |
На Arduino Mega, Due | 20 | 21 |
На Arduino Leonardo, Pro Micro | 2 | 3 |
После подключения у нас должно получится примерно так:
Настройка и подключение в Arduino IDE
Как и со всей периферией Arduino, с модулем часов удобнее работать, используя библиотеку. Мы будем пользоваться низкоуровневой библиотекой Wire (входит в комплект поставки Arduino IDE) и двумя высокоуровневыми DS1307 RTCи Time (необходимо скачать).
Несмотря на то, что библиотека написана для «неточных» часов, она поддерживает работу и с DS3231.
После скачивания библиотек их необходимо установить. Для этого две папки с библиотеками копируются в поддиректорию libraries в папке установки среды Arduino IDE.
Папка Libraries находится по разным адресам в зависимости от вашей ОС:
На Mac: домашняя директория -> Documents -> Arduino -> libraries
На PC: Мои документы -> Arduino -> libraries
На Linux: домашняя директория -> sketchbook -> libraries
После установки запустите среду Arduino IDE и откройте пример TimeRTC библиотеки Time (Файл Examples Time TimeRTC), или просто скопируйте код:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
#include <Time.h> #include <Wire.h> #include <DS1307RTC.h> void setup() { Serial.begin(9600); while (!Serial) ; // wait until Arduino Serial Monitor opens setSyncProvider(RTC.get); // the function to get the time from the RTC if(timeStatus()!= timeSet) Serial.println("Unable to sync with the RTC"); else Serial.println("RTC has set the system time"); } void loop() { if (timeStatus() == timeSet) { digitalClockDisplay(); } else { Serial.println("The time has not been set. Please run the Time"); Serial.println("TimeRTCSet example, or DS1307RTC SetTime example."); Serial.println(); delay(4000); } delay(1000); } void digitalClockDisplay(){ // digital clock display of the time Serial.print(hour()); printDigits(minute()); printDigits(second()); Serial.print(" "); Serial.print(day()); Serial.print(" "); Serial.print(month()); Serial.print(" "); Serial.print(year()); Serial.println(); } void printDigits(int digits){ // utility function for digital clock display: prints preceding colon and leading 0 Serial.print(":"); if(digits < 10) Serial.print('0'); Serial.print(digits); } |
Загрузите скетч в плату, после чего откройте монитор последовательного порта (Ctrl+Shift+M). Скорее всего, вы увидите неправильное время или вообще его не увидите, так как часы всё ещё не настроены.
Для их настройки запустите пример SetTime (Файл Примеры DS1307RTC SetTime) и залейте его в плату. После загрузки время будет настроено по системному времени ПК на момент компиляции. Если вы в любой момент времени перезагрузите плату, то время снова будет сброшено ко времени компиляции, поэтому после заливки настроенного скетча отключите сигнальные линии часов и залейте любой другой скетч (например, наш первый, выводящий время).
Если вам не нравится настройка времени по времени компиляции, вы можете задать ее самостоятельно, для этого используйте следующий код:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
//Подключаем библиотеки для работы: #include <Time.h> #include <Wire.h> #include <DS1307RTC.h> void setup() { setSyncProvider(RTC.get); //Устанавливаем нужное время в формате: Часы, минуты, секунды, день, месяц, год setTime(13,00,0,01,4,2016); //Применяем значение: RTC.set(now()); } void loop() { //Ставим задержку в 100 миллисекунд: delay(100); } |
Он установит время и дату на 13:00:00 1 апреля 2016 года. Поменяйте это значение для установки своего времени. Учтите – если вы перезагрузите плату, время будет сброшено, как с временем компиляции, так что повторите действия с отключением платы и заливкой другого скетча.
12 комментариев. Оставить новый
спасибо но работает только с ардуино IDE 0015-1.5
а какие ошибки появляются при работе с другой версией?
Мне интересно, эти ошибки специально созданы для того, чтобы только продвинутый пользователь мог разобраться? Или всё же случайно?
Arduino: 1.8.2 Hourly Build 2017/03/21 05:33 (Windows XP), Плата:”Arduino Nano, ATmega328P”
In file included from C:\Program Files\Arduino\libraries\DS1307RTC\examples\SetTime\SetTime.ino:1:0:
C:\Program Files\Arduino\libraries\DS1307RTC/DS1307RTC.h:19:22: error: ‘tmElements_t’ has not been declared
static bool read(tmElements_t &tm);
^
C:\Program Files\Arduino\libraries\DS1307RTC/DS1307RTC.h:20:23: error: ‘tmElements_t’ has not been declared
static bool write(tmElements_t &tm);
^
SetTime:10: error: ‘tmElements_t’ does not name a type
tmElements_t tm;
^
C:\Program Files\Arduino\libraries\DS1307RTC\examples\SetTime\SetTime.ino: In function ‘void setup()’:
SetTime:20: error: expected primary-expression before ‘)’ token
if (RTC.write(tm)) {
^
C:\Program Files\Arduino\libraries\DS1307RTC\examples\SetTime\SetTime.ino: In function ‘bool getTime(const char*)’:
SetTime:53: error: expected unqualified-id before ‘.’ token
tm.Hour = Hour;
^
SetTime:54: error: expected unqualified-id before ‘.’ token
tm.Minute = Min;
^
SetTime:55: error: expected unqualified-id before ‘.’ token
tm.Second = Sec;
^
C:\Program Files\Arduino\libraries\DS1307RTC\examples\SetTime\SetTime.ino: In function ‘bool getDate(const char*)’:
SetTime:70: error: expected unqualified-id before ‘.’ token
tm.Day = Day;
^
SetTime:71: error: expected unqualified-id before ‘.’ token
tm.Month = monthIndex + 1;
^
SetTime:72: error: expected unqualified-id before ‘.’ token
tm.Year = CalendarYrToTm(Year);
^
exit status 1
‘tmElements_t’ does not name a type
Возможно под этой версией Arduino IDE данная библиотека не работает
Здраствуйте, есть ли возможность переадресации портов?
Приведенный модуль RTC имеет проблему. Схема подключения DS3231 отличается от даташита на эту микросхему. В нем есть цепь “подзарядки” батарейки CR2032, что категорически недопустимо и со временем приводит к вздутию батарейки при круглосуточной работе устройства. Единственное быстродоступное решение – сделать так, чтобы плюсовой контакт батарейки соединялся только с выводом 14 DS3231, для чего на плате перерезается дорожка, ведущая от соединения батарейки и 14 вывода.
Здравствуйте. а подскажите как к данной связке подключить дисплей SSD1306. везде где находил у кого это работает -у меня нет(. по идее все подключают дисплей в параллель проводам I2C к модулю времени. не знаю почему…., после загрузки скейча он даже не светится. он рабочий,проверял его тестовой библиотекой . Пробовал кучу библиотек к дисплею, бесполезно. то ошибка, то не работает. хотя в мониторе порта время идёт,т.е. модулю времени тоже рабочий. Что я делаю не так?. такое ощущение…., что дисплей надо как то по другому подключать.
Спасибо , помогли разобраться
Arduino: 1.8.15 (Windows 10), Плата:”Arduino Nano, ATmega328P (Old Bootloader)”
In file included from C:\Users\Asus\Documents\Arduino\libraries\Time\examples\TimeRTC\TimeRTC.pde:9:0:
C:\Users\Asus\Documents\Arduino\libraries\DS1307RTC/DS1307RTC.h:19:22: error: ‘tmElements_t’ has not been declared
static bool read(tmElements_t &tm);
^~~~~~~~~~~~
C:\Users\Asus\Documents\Arduino\libraries\DS1307RTC/DS1307RTC.h:20:23: error: ‘tmElements_t’ has not been declared
static bool write(tmElements_t &tm);
^~~~~~~~~~~~
C:\Users\Asus\Documents\Arduino\libraries\Time\examples\TimeRTC\TimeRTC.pde: In function ‘void setup()’:
TimeRTC:14:3: error: ‘setSyncProvider’ was not declared in this scope
setSyncProvider(RTC.get); // the function to get the time from the RTC
^~~~~~~~~~~~~~~
TimeRTC:15:6: error: ‘timeStatus’ was not declared in this scope
if(timeStatus()!= timeSet)
^~~~~~~~~~
C:\Users\Asus\Documents\Arduino\libraries\Time\examples\TimeRTC\TimeRTC.pde:15:6: note: suggested alternative: ‘time_t’
if(timeStatus()!= timeSet)
^~~~~~~~~~
time_t
TimeRTC:15:21: error: ‘timeSet’ was not declared in this scope
if(timeStatus()!= timeSet)
^~~~~~~
C:\Users\Asus\Documents\Arduino\libraries\Time\examples\TimeRTC\TimeRTC.pde:15:21: note: suggested alternative: ‘time_t’
if(timeStatus()!= timeSet)
^~~~~~~
time_t
C:\Users\Asus\Documents\Arduino\libraries\Time\examples\TimeRTC\TimeRTC.pde: In function ‘void loop()’:
TimeRTC:23:7: error: ‘timeStatus’ was not declared in this scope
if (timeStatus() == timeSet) {
^~~~~~~~~~
C:\Users\Asus\Documents\Arduino\libraries\Time\examples\TimeRTC\TimeRTC.pde:23:7: note: suggested alternative: ‘time_t’
if (timeStatus() == timeSet) {
^~~~~~~~~~
time_t
TimeRTC:23:23: error: ‘timeSet’ was not declared in this scope
if (timeStatus() == timeSet) {
^~~~~~~
C:\Users\Asus\Documents\Arduino\libraries\Time\examples\TimeRTC\TimeRTC.pde:23:23: note: suggested alternative: ‘time_t’
if (timeStatus() == timeSet) {
^~~~~~~
time_t
C:\Users\Asus\Documents\Arduino\libraries\Time\examples\TimeRTC\TimeRTC.pde: In function ‘void digitalClockDisplay()’:
TimeRTC:36:16: error: ‘hour’ was not declared in this scope
Serial.print(hour());
^~~~
TimeRTC:37:15: error: ‘minute’ was not declared in this scope
printDigits(minute());
^~~~~~
C:\Users\Asus\Documents\Arduino\libraries\Time\examples\TimeRTC\TimeRTC.pde:37:15: note: suggested alternative: ‘init’
printDigits(minute());
^~~~~~
init
TimeRTC:38:15: error: ‘second’ was not declared in this scope
printDigits(second());
^~~~~~
C:\Users\Asus\Documents\Arduino\libraries\Time\examples\TimeRTC\TimeRTC.pde:38:15: note: suggested alternative: ‘rewind’
printDigits(second());
^~~~~~
rewind
TimeRTC:40:16: error: ‘day’ was not declared in this scope
Serial.print(day());
^~~
TimeRTC:42:16: error: ‘month’ was not declared in this scope
Serial.print(month());
^~~~~
TimeRTC:44:16: error: ‘year’ was not declared in this scope
Serial.print(year());
^~~~
C:\Users\Asus\Documents\Arduino\libraries\Time\examples\TimeRTC\TimeRTC.pde:44:16: note: suggested alternative: ‘char’
Serial.print(year());
^~~~
char
exit status 1
‘setSyncProvider’ was not declared in this scope
Этот отчёт будет иметь больше информации с
включенной опцией Файл -> Настройки ->
“Показать подробный вывод во время компиляции”
Работает. Только день надо задавать без ведущего ноля иначе ошибку выдавало.
Хочу купить
Здравствуйте. Вы можете приобрести данные товары, оформив заказ в нашем магазине.