Arduino základy 4 – modul hodin DS3231

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.

modul DS3231 a arduino UNO

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.

Jedna myšlenka na “Arduino základy 4 – modul hodin DS3231”

  1. 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

Napsat komentář

Vaše emailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *