Altijd bij de tijd met de DS1307 en DS3231 real-time clock modules
Geplaatst op Real time clock modules
Real time clock versies
De real time clock serie bevat veel verschillende typenummers met allen vergelijkbare functionaliteit. In deze serie zijn maar 2 versies 'mainstream', namelijk de DS1307 en de DS3231. Deze chips hebben beiden de mogelijkheid om een batterij aan te sluiten en hebben een sqw output pin, waarmee de controller een clockpuls van (1Hz, 1.024kHz, 4.096kHz, 8.192kHz) kan ontvangen. Ook hebben beide ic's een One-Wire interface, waardoor het mogelijk is deze over I2C aan te spreken.DS1302 Realtime klokmodule - SPIDe DS1302 Real Time Clock Module heeft een SPI-interface waarmee hij de tijd kan aflezen. Direct leverbaar € 1,85
Real time clock module DS3231Real time clock module met de DS3231 chip. Deze module zorgt ervoor dat de Arduino op ieder moment het exacte tijdstip weet. Door de Arduino op de ´sqw´ pin aan te sluiten, is het mogelijk om iedere seconde een interrupt te genereren waarmee sensorwaardes of een display kan worden aangesproken. Direct leverbaar € 3,95
De RTC module aansluiten op de Arduino UNO
De RTC modules komen in verschillende vormen en maten, de verbinding met de Arduino is echter voor alle modules gelijk. De module moet in ieder geval gevoed worden met 5V, verder zal de I2C interface verbonden moeten worden met de SDA (Serial data) SCL (Serial clock) pinnen van de Arduino (dit zijn pinnen A4 en A5 bij de Arduino UNO). Verder kan de SQW output worden aangesloten op een willekeurige pin van de Arduino om een klokpuls van de RTC te ontvangen. DS1307 aansluiting Arduino UNO
BCD Code
De numerieke waardes in de RTC chips zijn in BCD formaat opgeslagen. BCD code is op hardware niveau makkelijker in gebruik dan decimale getallen, echter zijn deze codes in de software niet erg handig. De getallen van en naar de chip moeten dus gecodeerd en gedecodeerd worden zodat de controller en RTC elkaar begrijpen.// Convert decimal to BCD
byte decToBcd(byte val)
{
return( (val/10*16) + (val%10) );
}
//Convert BCD to decimal
byte bcdToDec(byte val)
{
return( (val/16*10) + (val%16) );
}
De huidige tijd naar de RTC schrijven
De tijd hoeft maar 1 keer naar de RTC worden geschreven wanneer deze aan de batterij is verbonden. De RTC houd zelf de tijd bij en telt verder, zelfs wanneer deze niet is aangesloten aan de controller.x
#include "Wire.h"
#define DS3231_I2C_ADDRESS 0x68
void setDS3231time(
byte second,
byte minute,
byte hour,
byte dayOfWeek,
byte dayOfMonth,
byte month,
byte year)
{
Wire.beginTransmission(DS3231_I2C_ADDRESS);
//set next input to start at the seconds register
Wire.write(0);
//set seconds
Wire.write(decToBcd(second));
//set minutes
Wire.write(decToBcd(minute));
//set hours
Wire.write(decToBcd(hour));
//set day of week (1=Sunday, 7=Saturday)
Wire.write(decToBcd(dayOfWeek));
//set date (1 to 31)
Wire.write(decToBcd(dayOfMonth));
//set month
Wire.write(decToBcd(month));
//set year 20(0 to 99)
Wire.write(decToBcd(year));
Wire.endTransmission();
}
Hard drive clock
De tijd van de RTC lezen
xxxxxxxxxx
27
#include "Wire.h"
#define DS3231_I2C_ADDRESS 0x68
void readDS3231time(
byte *second,
byte *minute,
byte *hour,
byte *dayOfWeek,
byte *dayOfMonth,
byte *month,
byte *year)
{
Wire.beginTransmission(DS3231_I2C_ADDRESS);
//set DS3231 register pointer to 00h
Wire.write(0);
Wire.endTransmission();
//request seven bytes of data from DS3231
Wire.requestFrom(DS3231_I2C_ADDRESS, 7);
*second = bcdToDec(Wire.read() & 0x7f);
*minute = bcdToDec(Wire.read());
*hour = bcdToDec(Wire.read() & 0x3f);
*dayOfWeek = bcdToDec(Wire.read());
*dayOfMonth = bcdToDec(Wire.read());
*month = bcdToDec(Wire.read());
*year = bcdToDec(Wire.read());
}
De tijd weergeven
Met deze functies samen kan de tijd worden bepaald door de Arduino. Met onderstaande functie word deze data naar de serial monitor geschreven, maar de mogelijkheden voor het weergeven van de tijd zijn eindeloos.xxxxxxxxxx
53
void setup()
{
Wire.begin();
Serial.begin(9600);
//set the initial time (only once, not every startup)
//seconds, minutes, hours, dayofweek, day, month, year
//11:00:00, Saturday, 2016-07-16
setDS3231time(00,00,11,7,16,7,16);
}
void displayTime()
{
byte second, minute, hour;
byte dayOfWeek, dayOfMonth, month, year;
//retrieve data
readDS3231time(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);
//Hour
Serial.print(hour, DEC);
Serial.print(":");
//Minute (+0 if needed)
if (minute<10)
{
Serial.print("0");
}
Serial.print(minute, DEC);
Serial.print(":");
//Second (+0 if needed)
if (second<10)
{
Serial.print("0");
}
Serial.print(second, DEC);
Serial.print(" ");
//Day
Serial.print(dayOfMonth, DEC);
Serial.print("/");
//Month
Serial.print(month, DEC);
Serial.print("/");
//Year
Serial.print(year, DEC);
}
void loop()
{
displayTime();
delay(1000);
}
SQW frequentie instellen
xxxxxxxxxx
23
#include "Wire.h"
#define DS3231_I2C_ADDRESS 0x68
void setup()
{
Wire.begin();
Serial.begin(9600);
Wire.beginTransmission(DS3231_I2C_ADDRESS);
//move pointer to SQW address
Wire.write(0x07);
//set output clock speed
//0x00 = Off
//0x10 = 1Hz
//0x11 = 4.096Hz
//0x12 = 8.192Hz
//0x13 = 32.768Hz
Wire.write(0x10);
Wire.endTransmission();
}
Met deze code kan een complete klok worden gebouwd, welke de tijd kan weergeven. Dit kan op een 7-segment display, als analoge klok, met rooksignalen of deze kan zelfs worden uitgesproken wanneer hierom wordt gevraagd. Daarnaast kan de tijd ook worden gebruikt in de domotica / huis automatisering, koffiezetter gaat 's ochtends om 8 uur aan, de magnetron 's avonds om 17.15 en de gordijnen gaan dicht om 19.01:05. Werkelijk alles is mogelijk.