Как подключить часы реального времени (rtc) к arduino
Содержание:
Usage
Initialization
#include <ErriezDS1302.h> // Connect DS1302 data pin to Arduino DIGITAL pin #if defined(ARDUINO_ARCH_AVR) #define DS1302_CLK_PIN 2 #define DS1302_IO_PIN 3 #define DS1302_CE_PIN 4 #elif defined(ARDUINO_ARCH_ESP8266) #define DS1302_CLK_PIN D4 #define DS1302_IO_PIN D3 #define DS1302_CE_PIN D2 #elif defined(ARDUINO_ARCH_ESP32) #define DS1302_CLK_PIN #define DS1302_IO_PIN 4 #define DS1302_CE_PIN 5 #else #error #error "May work, but not tested on this target" #endif // Create DS1302 RTC object DS1302 rtc = DS1302(DS1302_CLK_PIN, DS1302_IO_PIN, DS1302_CE_PIN); void setup() { bool running; // Initialize RTC running = rtc.begin(); }
Set date and time
DS1302_DateTime dt; // Set initial date and time dt.second = ; dt.minute = 41; dt.hour = 22; dt.dayWeek = 6; // 1 = Monday dt.dayMonth = 21; dt.month = 4; dt.year = 2018; rtc.setDateTime(&dt);
Get date and time
DS1302_DateTime dt; char buf; // Get RTC date and time if (!rtc.getDateTime(&dt)) { Serial.println(F("Error: DS1302 read failed")); } else { snprintf(buf, sizeof(buf), "%d %02d-%02d-%d %d:%02d:%02d", dt.dayWeek, dt.dayMonth, dt.month, dt.year, dt.hour, dt.minute, dt.second); Serial.println(buf); }
Set time
// Set time rtc.setTime(12, , );
Get time
uint8_t hour; uint8_t minute; uint8_t second; char buf; // Read RTC time if (!rtc.getTime(&hour, &minute, &second)) { Serial.println(F("Error: DS1302 read failed")); } else { // Print time snprintf(buf, sizeof(buf), "%d:%02d:%02d", hour, minute, second); Serial.println(buf); }
Write to RTC RAM
// Write Byte to RTC RAM rtc.writeByteRAM(0x02, 0xA9); // Write buffer to RTC RAM uint8_t buf = { 0x00 }; rtc.writeBufferRAM(buf, sizeof(buf));
Read from RTC RAM
// Read byte from RTC RAM uint8_t dataByte = rtc.readByteRAM(0x02); // Read buffer from RTC RAM uint8_t buf; rtc.readBufferRAM(buf, sizeof(buf));
Set Trickle Charger
Please refer to the datasheet how to configure the trickle charger.
// Disable (default) rtc.writeClockRegister(DS1302_REG_TC, DS1302_TCS_DISABLE); // Minimum 2 Diodes, 8kOhm rtc.writeClockRegister(DS1302_REG_TC, 0xAB); // Maximum 1 Diode, 2kOhm rtc.writeClockRegister(DS1302_REG_TC, 0xA5);
Set RTC date and time using Python
Flash Terminal example.
Set COM port in examples/Terminal/Terminal.py Python script.
Run Python script:
// Install Pyserial python3 pip -m pyserial // Set RTC date and time python3 Terminal.py
Сравнение популярных модулей RTC DS1302, DS1307, DS3231
В этой таблице мы привели список наиболее популярных модулей и их основные характеристики.
Название | Частота | Точность | Поддерживаемые протоколы |
DS1307 | 1 Гц, 4.096 кГц, 8.192 кГц, 32.768 кГц | Зависит от кварца – обычно значение достигает 2,5 секунды в сутки, добиться точности выше 1 секунды в сутки невозможно. Также точность зависит от температуры. | I2C |
DS1302 | 32.768 кГц | 5 секунд в сутки | I2C, SPI |
DS3231 | Два выхода – первый на 32.768 кГц, второй – программируемый от 1 Гц до 8.192 кГц | ±2 ppm при температурах от 0С до 40С.
±3,5 ppm при температурах от -40С до 85С. Точность измерения температуры – ±3С |
I2C |
Пример проекта с i2C модулем часов и дисплеем
Проект представляет собой обычные часы, на индикатор будет выведено точное время, а двоеточие между цифрами будет мигать с интервалом раз в одну секунду. Для реализации проекта потребуются плата Arduino Uno, цифровой индикатор, часы реального времени (в данном случае вышеописанный модуль ds1307), шилд для подключения (в данном случае используется Troyka Shield), батарейка для часов и провода.
В проекте используется простой четырехразрядный индикатор на микросхеме TM1637. Устройство обладает двухпроводным интерфейсом и обеспечивает 8 уровней яркости монитора. Используется только для показа времени в формате часы:минуты. Индикатор прост в использовании и легко подключается. Его выгодно применять для проектов, когда не требуется поминутная или почасовая проверка данных. Для получения более полной информации о времени и дате используются жидкокристаллические мониторы.
Модуль часов подключается к контактам SCL/SDA, которые относятся к шине I2C. Также нужно подключить землю и питание. К Ардуино подключается так же, как описан выше: SDA – A4, SCL – A5, земля с модуля к земле с Ардуино, VCC -5V.
Индикатор подключается просто – выводы с него CLK и DIO подключаются к любым цифровым пинам на плате.
Скетч. Для написания кода используется функция setup, которая позволяет инициализировать часы и индикатор, записать время компиляции. Вывод времени на экран будет выполнен с помощью loop.
#include <Wire.h> #include "TM1637.h" #include "DS1307.h" //нужно включить все необходимые библиотеки для работы с часами и дисплеем. char compileTime[] = __TIME__; //время компиляции. #define DISPLAY_CLK_PIN 10 #define DISPLAY_DIO_PIN 11 //номера с выходов Ардуино, к которым присоединяется экран; void setup() { display.set(); display.init(); //подключение и настройка экрана. clock.begin(); //включение часов. byte hour = getInt(compileTime, 0); byte minute = getInt(compileTime, 2); byte second = getInt(compileTime, 4); //получение времени. clock.fillByHMS(hour, minute, second); //подготовка для записывания в модуль времени. clock.setTime(); //происходит запись полученной информации во внутреннюю память, начало считывания времени. } void loop() { int8_t timeDisp; //отображение на каждом из четырех разрядов. clock.getTime();//запрос на получение времени. timeDisp = clock.hour / 10; timeDisp = clock.hour % 10; timeDisp = clock.minute / 10; timeDisp = clock.minute % 10; //различные операции для получения десятков, единиц часов, минут и так далее. display.display(timeDisp); //вывод времени на индикатор display.point(clock.second % 2 ? POINT_ON : POINT_OFF);//включение и выключение двоеточия через секунду. } char getInt(const char* string, int startIndex) { return int(string - '0') * 10 + int(string) - '0'; //действия для корректной записи времени в двухзначное целое число. В ином случае на экране будет отображена просто пара символов. }
После этого скетч нужно загрузить и на мониторе будет показано время.
Программу можно немного модернизировать. При отключении питания выше написанный скетч приведет к тому, что после включения на дисплее будет указано время, которое было установлено при компиляции. В функции setup каждый раз будет рассчитываться время, которое прошло с 00:00:00 до начала компиляции. Этот хэш будет сравниваться с тем, что хранятся в EEPROM, которые сохраняются при отключении питания.
Для записи и чтения времени в энергонезависимую память или из нее нужно добавить функции EEPROMWriteInt и EEPROMReadInt. Они нужны для проверки совпадения/несовпадения хэша с хэшем, записанным в EEPROM.
Можно усовершенствовать проект. Если использовать жидкокристаллический монитор, можно сделать проект, который будет отображать дату и время на экране. Подключение всех элементов показано на рисунке.
В результате в коде нужно будет указать новую библиотеку (для жидкокристаллических экранов это LiquidCrystal), и добавить в функцию loop() строки для получения даты.
Алгоритм работы следующий:
- Подключение всех компонентов;
- Загрузка скетча;
- Проверка – на экране монитора должны меняться ежесекундно время и дата. Если на экране указано неправильное время, нужно добавить в скетч функцию RTC.write (tmElements_t tm). Проблемы с неправильно указанным временем связаны с тем, что модуль часов сбрасывает дату и время на 00:00:00 01/01/2000 при выключении.
- Функция write позволяет получить дату и время с компьютера, после чего на экране будут указаны верные параметры.