Pokud chceme stavět zařízení které potřebuje znát aktuální čas, můžeme k arduinu připojit hodiny reálného času například s obvodem DS1307 nebo DS3231, modul s DS3231 je přesnější než modul s DS1307.
Objednal jsme si modul I2C RTC DS1307 AT24C32 na www.aliexpress.com za 14,- Kč. Součástí tohoto modulu je i EEPROM paměť s kapacitou 4kB. Co v dodávce nebylo byla baterie.
Propojení s arduinem je jednoduché, prostě jenom propojíte GND,SDA,SCL z modulu na stejně označené vývody na arduinu, vývod VCC z modulu připojíte na 5V nebo 3.3V na arduinu.
Program pro komunikaci s modulem potřebuje knihovnu RTClib.zip, odkaz na zdroj je https://github.com/adafruit/RTClib.
#include "RTClib.h" RTC_DS1307 rtc; void setup () { Serial.begin(9600); rtc.begin(); if (! rtc.isrunning()) { Serial.println("RTC nebezi!"); rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); } } void loop () { DateTime now = rtc.now(); Serial.print(now.hour(), DEC); Serial.print(':'); Serial.print(now.minute(), DEC); Serial.print(':'); Serial.print(now.second(), DEC); Serial.print(' '); Serial.print(now.day(), DEC); Serial.print('.'); Serial.print(now.month(), DEC); Serial.print('.'); Serial.print(now.year(), DEC); Serial.println(); delay(3000); }
Jak vidíte největší část kódu zabírá výpis na terminál. Pokud modul připojíte poprvé nebo po výměně záložní baterie tak modul neběží a čeká až mu nastavíte správný čas. Proto je v programu v procedůře setup kontrola rtc.isrunning(), pokud modul neběží je nastaven čas na čas kdy byl program překládán a nahrán do arduina. Popřípadě lze čas nastavit takto:
rtc.adjust(DateTime(2016, 1, 21, 17, 59, 59));
Příklad jak je možné uložit data do EEPROM a zase je přečíst.
#include <Wire.h> #define EEPROM 0x50 void i2c_eeprom_write_byte( int deviceaddress, unsigned int eeaddress, byte data ) { int rdata = data; Wire.beginTransmission(deviceaddress); Wire.write((int)(eeaddress >> 8)); Wire.write((int)(eeaddress & 0xFF)); Wire.write(rdata); delay(10); Wire.endTransmission(); } byte i2c_eeprom_read_byte( int deviceaddress, unsigned int eeaddress ) { byte rdata = 0xFF; Wire.beginTransmission(deviceaddress); Wire.write((int)(eeaddress >> 8)); Wire.write((int)(eeaddress & 0xFF)); Wire.endTransmission(); delay(10); Wire.requestFrom(deviceaddress, 1); delay(10); if (Wire.available()) rdata = Wire.read(); return rdata; } void setup() { Wire.begin(); Serial.begin(9600); i2c_eeprom_write_byte(EEPROM, 4000, 81); delay(5); byte a = i2c_eeprom_read_byte(EEPROM, 4000); Serial.println(a); } void loop() { }
Data z EEPROM čteme a zapisujeme po stejné I2C sběrnici jako informace o čase. Při práci s EEPROM jen programu řekneme že budeme komunikovat se zařízením na adrese 0x50. Hodiny reálného času zase mají jinou adresu. Program uloží na pozici 4000 číslo 81 a pak ho z této pozice zase přečte.