Модуль часов реального времени на микросхеме DS3231,
Особенности модуля ZS-042:
- Часы реального времени DS3231 с температурной компенсацией хода, календарь до 2100 года, с учетом високосного года.
- 32 байт внешней EEPROM памяти.
- Держатель для Li-Ion аккумулятора LIR2032 с возможностью зарядки. Модуль не поддерживает батареи типа CR2032 без доработки.
- Интерфейс: I2C
- Напряжение питания: 2,3 В — 5,5 В.
- Габариты: 40 х 22 мм.
DS3231:
В основе модуля лежит микросхема RTC (Real Time Clock) DS3231 от Maxim. Это полноценные часы и календарь до 2100 года. Точность хода ±2ppm при температуре 0°C — +40°C. Часы могут работать в 24 или 12 часовом формате с отображением AM/PM. Также в наличии два будильника и датчик температуры.
EEPROM 24C32:
На модуле установлена микросхема EEPROM 24C32 объемом 32 байт, можно использован для хранения настроек, 24C32 использует I2C интерфейс. I2C адрес EEPROM можно изменить с помощью трех перемычек на плате, A0, A1 и A2.

Согласно спецификации, это 3 бита в конце 7-битного адреса

A0, A1 и A2 подтянуты к питанию, а значит адрес с не запаянными перемычками, 0b1010111 или 0x57.
Аккумулятор или батарея?
LIR2032 на модуле служит в качестве резервного источника питания для часов, чтобы часы не сбрасывались при отключении питания. Если посмотреть на схему модуля (она ниже) увидим схему зарядки аккумулятора, диод (D2) с резистором (R5), если ее можно так называть, т.е. при внешнем питании, через эту цепочку подается напряжение заряда на аккумулятор.
В случаи использования не перезаряжаемой батареи CR2032, от этой цепочки желательно избавится.
Распиновка модуля:

- 32K — Выход с открытым стоком (требуется подтягивающий резистор), на выходе генерируется импульсы с частотой 32КГц.
- SQW — В даташите обозначен как INT/SQW. Программируемый выход с открытым стоком, обычно служит как выход прерывания для микроконтроллера, назначение зависит от конфигурации регистра, можно дернуть ногой по срабатыванию будильника, на выходе можно генерировать импульсы с частотой 1Гц, 4кГц, 8kHz или 32кГц.
- SCL и SDA — Выходы интерфейса I2C, уже подтянутые к питанию резисторами на 4,7К на плате модуля.
- VCC и GND — Питание 2,3 В — 5,5 В и масса.
Принципиальная схема модуля:
Подключение к Arduino

Код из видео:
#include <Wire.h> #include <OLED_I2C.h> OLED myOLED(SDA, SCL, 8); extern uint8_t SmallFont[]; extern uint8_t MediumNumbers[]; extern uint8_t BigNumbers[]; ///// часы .. byte decToBcd(byte val){ return ( (val/10*16) + (val%10) ); } byte bcdToDec(byte val){ return ( (val/16*10) + (val%16) ); } void setDateDs1307(byte second, // 0-59 byte minute, // 0-59 byte hour, // 1-23 byte dayOfWeek, // 1-7 byte dayOfMonth, // 1-28/29/30/31 byte month, // 1-12 byte year) // 0-99 { Wire.beginTransmission(0x68); Wire.write(0); Wire.write(decToBcd(second)); Wire.write(decToBcd(minute)); Wire.write(decToBcd(hour)); Wire.write(decToBcd(dayOfWeek)); Wire.write(decToBcd(dayOfMonth)); Wire.write(decToBcd(month)); Wire.write(decToBcd(year)); Wire.endTransmission(); } void getDateDs1307(byte *second, byte *minute, byte *hour, byte *dayOfWeek, byte *dayOfMonth, byte *month, byte *year) { Wire.beginTransmission(0x68); Wire.write(0); Wire.endTransmission(); Wire.requestFrom(0x68, 7); *second = bcdToDec(Wire.read() & 0x7f); *minute = bcdToDec(Wire.read()); *hour = bcdToDec(Wire.read() & 0x3f); *dayOfWeek = bcdToDec(Wire.read()); *dayOfMonth = bcdToDec(Wire.read()); *month = bcdToDec(Wire.read()); *year = bcdToDec(Wire.read()); } ///// температура .. float get3231Temp(){ byte tMSB, tLSB; float temp3231; Wire.beginTransmission(0x68); Wire.write(0x11); Wire.endTransmission(); Wire.requestFrom(0x68, 2); if(Wire.available()) { tMSB = Wire.read(); //2's complement int portion tLSB = Wire.read(); //fraction portion temp3231 = (tMSB & B01111111); //do 2's math on Tmsb temp3231 += ( (tLSB >> 6) * 0.25 ); //only care about bits 7 & 8 } else { //oh noes, no data! } return temp3231; } void setup() { Serial.begin(9600); myOLED.begin(); Wire.begin(); /* // установка часов byte second, minute, hour, dayOfWeek, dayOfMonth, month, year; second = 30; minute = 0; hour = 14; dayOfWeek = 3; // день недели dayOfMonth = 1; // день month = 4; year = 14; setDateDs1307(second, minute, hour, dayOfWeek, dayOfMonth, month, year); */ } void loop(){ byte second, minute, hour, dayOfWeek, dayOfMonth, month, year; char week[8][10] = {"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"}; getDateDs1307(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year); char time[10]; char data[11]; snprintf(time, sizeof(time),"%02d:%02d:%02d", hour, minute, second); snprintf(data, sizeof(data), "%02d/%02d/%02d", dayOfMonth, month, year); myOLED.setFont(SmallFont); myOLED.print(time, LEFT, 0); myOLED.print(data, LEFT, 15); myOLED.printNumF(get3231Temp(), 2, LEFT, 30); myOLED.print("C", 32, 30); myOLED.update(); delay(1000); } ////// конец