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.