Nr.05 – Arduino-RTC

Uhrzeitmodul für Arduino: RTC – Real Time Clock

Aufbau

Mit der Arduino kompatiblen DS1307 I2C Real Time Clock kann man Uhrzeit und Datum nahezu in Echtzeit anzeigen lassen.

Material: Mikrocontrollerboard (In diesem Beispiel UNO R3), ein Drehregler (bzw. Potentiometer), Breadboard, LCD Display, DS1307 I2C Real Time Clock, Jumperkabel

Materialbeschaffung: www.funduinoshop.com

Verkabelung:

Das LCD Display wird im Prinzip wie in der Anleitung Nr. 13 verkabelt. Dazu kommt dann noch die RTC, welche einmal mit 5V und GND verbunden wird, der SDA-Kontakt an den Analogen Eingang A4 und der SCL-Kontakt an den Analogen Eingang A5.

Achtung!: Bei dem MEGA2560 R3 Microcontroller gibt es für die SDA – und SCL- Kontakte eigene Eingänge auf dem Board unter 20 und 21.

MEGA

Steckeransicht für Aufbau mit UNO R3:

 

rtc-steckeransicht-neu-korrigiert

Wenn alles richtig verkabelt ist kann auch schon fast mit dem Programmieren begonnen werden. Vorher müssen, für die Programmierung notwendige, Libraries heruntergeladen und in der Arduino Software hinzugefügt werden.

Bei den benötigten Libraries handelt es sich einmal um die Time Library, welche z.B. Unter folgendem Link : http://www.pjrc.com/teensy/td_libs_Time.html als .ZIP Datei heruntergeladen werden kann und um die DS1307RTC Library, welche zB. Unter http://www.pjrc.com/teensy/td_libs_DS1307RTC.html als .ZIP Datei heruntergeladen werden kann.

Wenn man beide Libraries runtergeladen hat muss man diese noch in der Arduino Software zu den bereits vorhandenen Libraries hinzufügen. Dazu öffnet man die Arduino Software und wählt unter dem Punk „Sketch“ das Feld „Include Libraby“ aus. Danach kann man „Add .ZIP Library“ auswählen und die vorher heruntergeladenen Time und DS1307RTC Library hinzufügen.

Auf diese kann jetzt in einem Code zurückgegriffen werden.

Als nächstes muss man den sogennanten „Set-Time“ Sketch hochladen um die Zeit und das Datum vom Gerät (Computer, Laptop etc.) an dem der Microcontroller angeschlossen ist, auf der Real-Time-Clock einzustellen.

Dies macht man, indem man unter „Datei“ auf „Beispiele“ dann „DS1307RTC“ den Punkt „Set Time“ auswählt. Es öffnet sich der entsprechende Sketch, welchen man nun auf den UNO R3 hochlädt.

Wenn man das alles erledigt hat kann man zum eigentlichen Code kommen.

Code:

#include <Time.h> Bibliotheken laden
#include <Wire.h>
#include <DS1307RTC.h>
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2); //In dieser Zeile wird festgelegt, welche Pins des Mikrocontrollerboards für das LCD verwendet wird

void setup() 
{
lcd.begin(16, 2); //Im Setup wird angegeben, wie viele Zeichen und Zeilen werwendet werden.
Serial.begin(9600); //Öffnet den seriellen Port und legt die Baud Rate (9600) für die serielle Übertragung fest.
setSyncProvider(RTC.get); //Dies ist die Funktion um die Zeit- und Datumsangabe von der RTC zu bekommen
}

void loop() 
{
Serial.print(hour()); //Serial.print ist der Befehl etwas im seriellen Monitor anzuzeigen (Stunde, Minute, Sekunde, Leerzeichen, Tag, Leerzeichen, usw.)
printDigits(minute()); //bei den Minuten und Sekunden wird der Befehl
printDigits(second()); //printDigits angegeben welcher am Ende des Codes noch festgelegt wird.
Serial.print(" ");
Serial.print(day());
Serial.print(" ");
Serial.print(month());
Serial.print(" ");
Serial.print(year());
Serial.println();
delay(1000); //warte eine Sekunde
lcd.setCursor(2, 0); //setCursor gibt an wo der Text beginnen soll. In diesem Fall beim dritten Zeichen in der ersten Reihe.
lcd.print(hour()); //Hier soll jetzt die Uhrzeit angezeigt werden, also „hour“ „:“ „minute“ usw..
lcd.print(":");
lcd.print (minute());
lcd.print(":");
lcd.print(second());
lcd.print(" ");
lcd.print("Uhr"); //Hier soll nach der Uhrzeit noch das Wort „Uhr“ angezeigt werden, dazu müssen noch3 Leerzeichen folgen, sonst würde bei Zahlen <10 immer ein weiteres „r“ hinter Uhr angezeigt werden. Das liegt daran, dass in der LCD Library der Befehl eine 0 vor Zahlen <10 anzuzeigen nicht vorhanden ist.
lcd.print(" ");
lcd.print(" ");
lcd.print(" "); 
lcd.setCursor(1, 1); // Der nächste „Text“ soll nun beim zweiten Zeichen in der zweiten Reihe beginnen.
lcd.print(day()); // Das Datum soll nun als
lcd.print("."); // „Tag“, „.“ „Monat“ usw. angegeben werden.
lcd.print(month());
lcd.print(".");
lcd.print(year());
}

void printDigits(int digits) //In diesem Abschnitt wird festgelgt, dass bei Zahlen <10 im seriellen Monitor automatisch eine 0 vor den Ziffern angezeigt wird. Das gilt nur für den seriellen Monitor und nicht für LCD Display.Serial.print(":"); 
if(digits < 10) 
Serial.print('0'); 
Serial.print(digits); 
}

Hinweis: Die DS1307 Real Time Clock ist nicht auf die Sekunde genau. Das liegt daran, dass zwischen Hochladen des Set Time Sketch und dem Hochladen des endgültigen Sketch eine gewissen Zeit von ca. 15 Sekunden, die die RTC nicht ausgleichen kann.

Zusätzlich kann man vor dem Datum noch den Wochentag anzeigen lassen.

Hierzu muss vor dem Datum im lcd.print Abschnitt der Befehl printDay(); gegeben werden und nach dem Loop folgender Code eingefügt werden:

void printDay() // Hier wird wird für den vorher im Code schon verwendeten Befehl printDay eine Bedeutung festgelegt
{	
int day;
day = weekday(); // Die Wochentage sollen abhängig vom Datum angezeigt werden.
if(day == 1){lcd.print("So, ");} // Wenn es sich um Tag 1 handelt soll „So“ usw. angezeigt werden.
if(day == 2){lcd.print("Mo, ");}	
if(day == 3){lcd.print("Di, ");}
if(day == 4){lcd.print("Mi, ");}
if(day == 5){lcd.print("Do, ");}
if(day == 6){lcd.print("Fr, ");}
if(day == 7){lcd.print("Sa, ");}
}

 

Erweiterung:

Zwei I²C Bauteile gleichzeitig ansteuern: Uhrzeit und Datum mit einer Real Time Clock mit I²C Bus, auf einem I²C LCD anzeigen lassen.

Um zwei I²C Komponenten gleichzeitig ansteuern zu können, muss eins der Bauteile eine andere I²C Adresse als das andere. In unserem Fall können wir nur die Adresse des LCDs ändern. Sofern es die drei Lötstellen A0, A1 und A2 auf der Rückseite des I²C Moduls hat
(s. Bild).

zweiLCDrueckseite

Die I²C Adresse der Real Time Clock ist festgelegt und kann nicht geändert werden.

Um die Adresse des LCDs zu ändern, müssen die Lötstellen anders verbunden sein als zu Beginn (alle drei Lötstellen getrennt). So ändert sich die HEX Adresse des LCDs (s. Tabelle) (I = verbunden, := nicht verbunden):

I2CDeutsch

Kann ggf. mit dem „Scanner“ aus der Anleitung „Zwei Displays mit I²C Modul gleichzeitig ansteuern“ geprüft werden.

Wenn die Adresse des LCDs verändert wurde, können wir nun zur Verkabelung kommen:

I2C-RTC

Zum Programmieren werden wie oben schon erwähnt, die Time und die DS1307RTC Library benötigt. Außerdem wird für das I²C LCD die NewliquidCrystal_1.3.4 Library benötigt, welche hier heruntergeladen werden kann: https://bitbucket.org/fmalpartida/new-liquidcrystal/downloads

Alle Bibliotheken müssen der Arduino Software hinzugefügt werden:

Sketch > Include Library > Add ZIP library > vorher heruntergelandene Datei auswählen

Als nächstes muss man den sogennanten „Set-Time“ Sketch hochladen um die Zeit und das Datum vom Gerät (Computer, Laptop etc.) an dem der Microcontroller angeschlossen ist, auf der Real-Time-Clock einzustellen.
Dies macht man, indem man unter „Datei“ auf „Beispiele“ dann „DS1307RTC“ den Punkt „Set Time“ auswählt. Es öffnet sich der entsprechende Sketch, welchen man nun auf den UNO R3 hochlädt.
Wenn man das alles erledigt hat kann man zum eigentlichen Code kommen.

Code:


#include <Time.h>

#include <Wire.h>

#include <DS1307RTC.h>

#include <LiquidCrystal_I2C.h> //Bibliotheken laden

LiquidCrystal_I2C lcd(0x3D, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); //Das I²C Display bennen und die HEX Adresse //eingeben (bei uns 0x3D)

void setup() {

lcd.begin(16, 2); //Das Display starten, festlegen dass es sich um ein Display mit 16 Zeichen in 2 Zeilen //handelt

lcd.backlight(); //Beleuchtung des Displays einschalten

Serial.begin(9600); //Seriellen Verbindung mit Baudrate 9600 starten

setSyncProvider(RTC.get); //Daten von der RTC abrufen

}

void loop() {

Serial.print(hour()); //Serial.print ist der Befehl etwas im seriellen Monitor anzuzeigen (Stunde, Minute, //Sekunde,Leerzeichen, Tag, Leerzeichen, usw.)

printDigits(minute()); //bei den Minuten und Sekunden wird der Befehl

printDigits(second()); //printDigits verwendet, welcher am Ende des Codes noch festgelegt wird

Serial.print(“ „);

Serial.print(day());

Serial.print(“ „);

Serial.print(month());

Serial.print(“ „);

Serial.print(year());

Serial.println();

delay(1000); //eine Sekunde warten

lcd.setCursor(2, 0); // setCursor gibt an wo der Text beginnen soll. In diesem Fall beim dritten Zeichen in //der ersten Reihe.

lcd.print(hour()); //Die Uhrzeit soll angezeigt werden im Format:

lcd.print(„:“); //Stunden:minuten:sekunden

lcd.print (minute());

lcd.print(„:“);

lcd.print(second());

lcd.print(“ „);

lcd.print(„Uhr“); //Dahinter soll das Wort „Uhr“ angezeigt werden

lcd.print(“ „);

lcd.print(“ „);

lcd.print(“ „);

lcd.setCursor(1, 1); //In der zweiten Zeile soll das Datum angezeigt //werden

lcd.print(day());

lcd.print(„.“);

lcd.print(month());

lcd.print(„.“);

lcd.print(year());

}

void printDigits(int digits){ //Der printDigits Befehl für den seriellen Monitor

Serial.print(„:“);

if(digits < 10)

Serial.print(‚0‘);

Serial.print(digits);

}