Je spoustu případů kdy je potřeba znát přesný čas, proto existuje spoustu modulů RTC. Dnes se podíváme na použití modulu DS3231.

Protože veškerá komunikace s modulem probíhá po I2C sběrnici je připojení modulu je velice jednoduché, stačí spojit stejné piny na arduinu a na modulu a je to. Modul obsahuje i EEPROM paměť a zálohovací baterii.
Teď k vlastnímu programu.
Nejdřív je potřeba program kterým nastavíme aktuální čas a datum do modulu.
#include "Wire.h" #define DS3231_adresa 0x68 //I2C adresa DS3231 // konverze desítkového čísla do BCD byte DECdoBCD(byte val){ return( (val/10*16) + (val%10) ); } void setup() { Wire.begin(); // Nastavení hodin // DS3231 (sekundy, minuty, hodiny, den v týdnu, datum, měsíc, rok) nastaveniDS3231(00,26,14,7,4,6,17); //tady se nastaví aktuální hodnoty podle klíče výše } void nastaveniDS3231(byte sekundy, byte minuty, byte hodiny, byte denVt, byte den, byte mesic, byte rok) { // odeslání dat do DS3231 Wire.beginTransmission(DS3231_adresa); Wire.write(0); // nastavení Wire.write(DECdoBCD(sekundy)); // nastavení sekund Wire.write(DECdoBCD(minuty)); // nastavení minut Wire.write(DECdoBCD(hodiny)); // nastavení hodin Wire.write(DECdoBCD(denVt)); // nastavení dne v týdnu (1=sobota, 7=neděle) Wire.write(DECdoBCD(den)); // nastavení data Wire.write(DECdoBCD(mesic)); // nastavení měsíce Wire.write(DECdoBCD(rok)); // nastavení roku (0 to 99) Wire.endTransmission(); } void loop() { }
Když už máme nastaveno stačí v případě potřeby přečíst data dalším programem
#include "Wire.h" #define DS3231_adresa 0x68 //I2C adresa DS3231 // konverze BCD do dekadického čísla byte BCDdoDEC(byte val){ return( (val/16*10) + (val%16) ); } void setup() { Wire.begin(); Serial.begin(9600); } void cteniDS3231casu(byte *sekundy, byte *minuty, byte *hodiny, byte *denVt, byte *den, byte *mesic, byte *rok) { Wire.beginTransmission(DS3231_adresa); Wire.write(0); //nastavení ukazatele registrů v DS3231 na 00h Wire.endTransmission(); Wire.requestFrom(DS3231_adresa, 7); //čtení 7 bytů z DS3231 //čtení 7 bytů dat z DS3231 od registru 00h *sekundy = BCDdoDEC(Wire.read() & 0x7f); *minuty = BCDdoDEC(Wire.read()); *hodiny = BCDdoDEC(Wire.read() & 0x3f); *denVt = BCDdoDEC(Wire.read()); *den = BCDdoDEC(Wire.read()); *mesic = BCDdoDEC(Wire.read()); *rok = BCDdoDEC(Wire.read()); } void loop() { byte sekundy, minuty, hodiny, denVt, den, mesic, rok; //proměnné cteniDS3231casu(&sekundy, &minuty, &hodiny, &denVt, &den, &mesic, &rok); //čtení času Serial.print(hodiny, DEC); Serial.print(":"); Serial.print(minuty, DEC); Serial.print(":"); if (sekundy<10) { Serial.print("0"); } Serial.print(sekundy, DEC); Serial.print(" den:"); Serial.print(denVt, DEC); Serial.print(" "); Serial.print(den,DEC); Serial.print("."); Serial.print(mesic, DEC); Serial.print(".20"); Serial.println(rok, DEC); delay(1000); }
Program načte data a vypíše je na sériový port.
Skoro zbytečně složitý používat pointery v takovýmhle programu. Má to sice i své výhody, ale program pak je celkem složitě zamotanej – navíc, když mají proměnné i pointery stejný jména.
Osobně bych radši deklaroval proměnné (minuty, sekundy, …) globálně a pak je vyčetl pouze ve funkci (proceduře) cteniDS3231casu();
byte sekundy, minuty; //atd… deklarováno globálně
void loop(){
cteniDS3231casu(); //spustí proceduru (funkce bez návratové hodnoty)
}
void cteniDS3231casu(){
sekundy = BCDdoDEC(Wire.read() & 0x7f); //ukládá přímo do globální proměnné
minuty = BCDdoDEC(Wire.read());
}
To já jen tak 🙂 Jinak dobrý. Já tu teď ladil ten barevnej displej 320*240 px s ARM STM32. Už to valí, tak se uvidí co z toho vznikne 🙂 Jinak samozřejmě nemám čas – ladím robota a ohýbačku 😀
Čus, Peťan