ESP
DIYer
32
LAB

Moderní mikrokontrolér v rukou „bastlíře“

Hodiny s modulem DS3231 a OLED displejem

V tomto projektu si ukážeme, jak si postavit jednoduché hodiny se zobrazením času, datem a dne v týdnu. Pro stavbu tohoto zapojení kromě modulu ESP32 použijeme modul reálných hodin RTC DS3231 a 0,96″ I²C OLED displej (SSD1306 I2C). Alternativním obvodem k  DS3231 může být kupříkladu modul DS1307. Výhoda RTC modulu  DS3231 je to, že má vestavěnou funkci budíku a také teplotní senzor. Pokud tedy použijeme tento modul, můžeme jednoduchým způsobem rozšířit své hodiny o další zajímavé funkce.

Modul DS3231 RTC

Modul DS3231 je levný, extrémně přesný modul I²C hodin reálného času (RTC) s integrovaným teplotně kompenzovaným krystalovým oscilátorem. Modul je doplněn baterií, která zabezpečuje chod hodin, i když je přerušeno hlavní napájení.

Real Time Clock DS3231

Modul RTC uchovává informace o sekundách, minutách, hodinách, dnu, datu, měsíci a roce. Datum respektuje počet dní v daném měsíci, včetně oprav pro přestupný rok. Hodiny pracují v 24hodinovém nebo 12hodinovém formátu s aktivním indikátorem AM/PM. K dispozici jsou dva programovatelné alarmy denní doby a programovatelný výstup obdélníkových vln.

Přesný teplotně kompenzovaný referenční a komparační obvod monitoruje stav Vcc, aby detekoval výpadky napájení, poskytl resetovací výstup a v případě potřeby automaticky přepnul na záložní zdroj.

Modul pracuje na napětí 3,3 V a komunikuje sběrnicí I²C. To usnadňuje připojení k modulu ESP32.

0,96palcový OLED displej

OLED displej, který v tomto případě použijeme, je model SSD1306. Jedná se o jednobarevný 0,96″ displej s rozlišením 128×64 pixelů. OLED displej nevyžaduje podsvícení, což má za následek velmi pěkný kontrast v tmavém prostředí. Navíc jeho pixely spotřebovávají energii, pouze když jsou zapnuté, takže OLED displej spotřebovává méně energie než ostatní displeje.

OLED displej SSD1306 I2C

Model, který používáme, má čtyři piny a komunikuje s libovolným mikrokontrolérem pomocí komunikačního protokolu I²C. Pozor, existují i modely, které komunikují prostřednictvím protokolu SPI.

Sestavení obvodu: hodiny s ESP32 a DS3231

Následující obrázek ukazuje schéma propojení modulu DS3231 s ESP32 a OLED. Díky použití komunikační sběrnice I²C, je zapojení poměrně jednoduché.

Circuit Diagram ESP32 DS3231

Pro komunikaci potřebujeme jen 2 piny. U obou modulů, jak displeje, tak modulu reálných hodin, připojíme pin sériových dat (SDA) ke kolíku GPIO21 modulu ESP32 a kolík sériových hodin (SCL) ke kolíku GPIO22 modulu ESP32. Napájení 3,3 V opět u obou modulů (OLED a RTC) spojíme s pinem 3,3 V modulu ESP32. Některé prameny i uvádějí, že můžeme též použít napájení 5 V (pro DS3231 i OLED modul). V tomto případě je ale na pováženou, zda je tato informace správná! Je třeba si uvědomit, že modul ESP32 komunikuje na 3,3V logice a pokud jsou I²C vodiče na straně OLED nebo RTC připojeny zdvihacími rezistory k napájecímu napětí, dochází při 5V napájení k přetěžování vstupů modulu ESP32.

Obvod můžete sestavit poměrně rychle na nepájivém poli.

hotove zapojeni

Zdrojový kód modulu ESP32 je uveden níže. Kód můžete zkopírovat a nahrát přímo na desku ESP32. Ale předtím budete potřebovat nainstalovat do prostředí Arduino IDE několik knihoven.

Nejprve si buď pomocí správce knihoven prostředí Arduino IDE stáhněte a přidejte následující knihovny (od vývojáře Adafruit)

Adafruit_SSD1306:
Adafruit_SSD1306

Adafruit_GFX:
Adafruit_GFX

RTClib:
RTClib

Kód programu pro prostředí Arduino IDE
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include "RTClib.h"

RTC_DS3231 rtc;
char daysOfTheWeek[7][12] = {"Nedele", "Pondeli", "Utery", "Streda", "Ctvrtek", "Patek", "Sobota"};

#define SCREEN_WIDTH 128  // OLED displej - sirka (v pixelech)
#define SCREEN_HEIGHT 64  // OLED displej - vyska (v pixelech)
#define OLED_RESET -1     // Reset pin # (nebo -1 pokud modul nema svuj RESET pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);

void setup(){
   Serial.begin(115200);
   if (! rtc.begin()) {
      Serial.println("Nelze najit RTC");
      while (1);    // STOP, smycka je nekonecna
   }

   if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
      Serial.println("SSD1306 spojeni se nezdarilo");
      while (1);   // STOP, smycka je nekonecna
   }

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

   display.display();
   delay(2);
   display.clearDisplay();

   display.setTextColor(WHITE);
   display.setTextSize(2);
   display.setCursor(0,5);
   display.print("  Clock ");
   display.display();
   delay(3000);
}

void loop() {
   DateTime now = rtc.now();

   display.clearDisplay();
   display.setTextSize(2);
   display.setCursor(75,0);
   display.println(now.second(), DEC);

   display.setTextSize(2);
   display.setCursor(25,0);
   display.println(":");

   display.setTextSize(2);
   display.setCursor(65,0);
   display.println(":");

   display.setTextSize(2);
   display.setCursor(40,0);
   display.println(now.minute(), DEC);

   display.setTextSize(2);
   display.setCursor(0,0);
   display.println(now.hour(), DEC);

   display.setTextSize(2);
   display.setCursor(0,20);
   display.println(now.day(), DEC);

   display.setTextSize(2);
   display.setCursor(25,20);
   display.println("-");

   display.setTextSize(2);
   display.setCursor(40,20);
   display.println(now.month(), DEC);

   display.setTextSize(2);
   display.setCursor(55,20);
   display.println("-");

   display.setTextSize(2);
   display.setCursor(70,20);
   display.println(now.year(), DEC);

   display.setTextSize(2);
   display.setCursor(0,40);
   display.print(daysOfTheWeek[now.dayOfTheWeek()]);

   display.display();
}

Pokud jsme aspoň trochu seznámili s předchozími články, ve kterých jsme si vysvětlovali připojení RTC modulu k modulu ESP, popř. s I²C displejem (i když s trochu jiným typem), měli bychom se v kódu po chvíli zorientovat.

Popis kódu

Po spuštění programu se nejprve inicializují všechny použité knihovny. Ty zajišťují komunikaci jak s RTC modulem (DS3231), tak s OLED displejem (SSD1306). V úvodní funkci setup() funkci probíhá:

  • spuštění sériové komunikace (pro ladění),
  • kontrola připojení RTC modulu,
  • kontrola dostupnosti OLED displeje.

Pokud některé zařízení neodpovídá, program se zastaví v nekonečné smyčce.

Za zmínku stojí výchozí nastavení času. Jistě nás napadne, jak je možné, že naše hodiny po přeložení kódu vědí přesný čas a datum. V případě, že by se modul ESP32 připojoval k internetu, bychom si mohli myslet, že získal tuto informaci například z některého z NTP serverů, ale nyní se modul nikam nepřipojuje.

Tajemství nastavení času se skrývá v následující řádce:

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

Výrazy __DATE__ a __TIME__ jsou informace pro překladač, aby do programu vložil aktuální čas. K nastavení hodin tedy došlo z našeho PC při překladu a zápisu programu do modulu ESP32. A jelikož tuto informaci okamžitě přebere modul RTC, je tato informace dále v zapojení našich hodin udržována. Jen pozor na resetování hodin. Pak opět proběhne funkce setup a nastaví se do hodin čas posledního kódu překladu!

RTC modul jako zdroj přesného času

Modul reálného času RTC DS3231 na rozdíl od interních časovačů modulu ESP32 si udržuje přesný čas i při výpadku napájení (díky své záložní baterii). Modul ESP32 v tomto programu neřeší synchronizaci – pouze se dotazuje na aktuální hodnoty.

Pole: daysOfTheWeek[7][12] slouží k převodu číselného dne v týdnu na textovou podobu.

Zobrazení na OLED displeji

Po inicializaci se na displeji zobrazí krátká uvítací obrazovka („Clock“), což je čistě estetický prvek. Následně se program přesune do hlavní smyčky loop(). Každý průchod smyčkou:

  1. Načte aktuální čas z RTC modulu: DateTime now = rtc.now();
  2. Vymaže displej: display.clearDisplay();
  3. Postupně vykreslí jednotlivé části času a data.

Celý proces se opakuje velmi rychle, takže uživatel vnímá plynule aktualizovaný čas. Protože v kódu není žádné zpoždění (delay()), obnovovací frekvence je dostatečně přirozená díky rychlosti komunikace.

Zobrazení na displeji je řešeno velmi „low-level“ způsobem – každý údaj (hodiny, minuty, sekundy, den, měsíc, rok) má přesně definovanou pozici pomocí setCursor(x, y). To sice dává plnou kontrolu nad layoutem, ale zároveň vyžaduje pečlivé ladění pozic.

hotove zapojeni - funguje

Závěr

Dokončili jsme další provedení hodin s modulem ESP32. Jak jsme zmínili v úvodu, modul DS3231 disponuje dalšími funkcemi – dvojicí budíků a hlavně teplotním čidlem. Určitě by bylo dobré tyto informace získat a zobrazit na připojeném displeji. Určitě by nás mohly zajímat funkce jako je getAlarm1Mode() nebo getTemperature() a podobně. Jako inspiraci pro další možný rozvoj tohoto zapojení přikládáme odkaz na referenční list knihovny RTClib (pro třídu RTC_DS3231)

Článek je upraveným překladem textu: ESP32 & DS3231 Based Real Time Clock (RTC) on OLED.
Pošli signál autorovi: