Arduino -- Elektronik-Experimentierkasten -- Lectron Lehrsytem -- Jugendarbeit -- Elektronik -- Amateurfunk -- Notfunk -- Shop

Echtzeit-Uhr mit DS1307 und LCD-Anzeige

Eine Uhr basierend auf den "Bordmitteln" eines Arduinos hat einige Nachteile:

Wenn man die Uhr auf einen zusätzlichen Chip auslagert kann man viele dieser Nachteile umgehen.

Der DS1307 von Maxim ist eine Echtzeituhr die über den I2C-Bus an den Arduino angeschlossen wird. Eine Batterie puffert die Uhr auch bei ausgeschaltenem Arudino.

Als Vorlage dient die RTC1307 - Real Time Clock von Combustory.

Verwendete Hardware:



Der DS1307 auf dem SD-Shield Plus ist über den I2C-Bus angeschlossen:

SDA => A4
SCL => A5

Die aktuelle Zeit kann man mittels dieser Schritte auslesen:
  1. I2C-Kommunikation im Schreib-Modus öffnen
  2. Registerzeiger auf 0x00 (erstes Register) setzen
  3. I2C-Kommunikation schliessen
  4. I2C-Kommunikation im Lese-Modus öffnen
  5. Sieben Bytes auslesen
Die Zeit und das Datum wird über die Funktion getDateDS1307() ausgelesen.

0x00
Sekunden
Bit 7 muss mit 0x7f ausmaskiert werden
0x01
Minuten
 
0x02
Stunde
muss für 24h mit 0x3f ausmaskiert werden
0x03
Wochentag
 
0x04
Tag
 
0x05
Monat
 
0x06
Jahr
 

Der Funktion
getDateDS1307() wird ein Zeiger auf ein Array ( int datum[ 7 ] ) übergeben. In der Funktion werden das Array mit den Zeit- und Datumswerten gefüllt. Danach können diese Werte für die Ausgabe usw. verwendet werden.
 

Die restlichen 56 Register ( 0x08 - 0x3f ) könne als gepuffertes RAM genutzt werden.


/****************************************************************************************************
 * RTC DS1307 mit LCD-Display
 *
 *  05.11.2011  Jürgen Mayer, DL8MA
 *
 *  http://www.amateurfunk.de/dl8ma
 *
 *  Dieser Beispielcode ist public domain
 *
 *  Hardware:  Arduino
 *             Arduino SD Shield Plus mit DS1307 (www.avrcontrollers.com)
 *             LCD-Shield 
 */

#include "LCD4Bit_mod.h" #include "Wire.h" #define DS1307_I2C_ADDRESS 0x68                          // I2C Adresse   char buffer[20] = ""; // Speicherbereich für Datenkonvertierung   LCD4Bit_mod lcd = LCD4Bit_mod(2);                        // LCD-Display   /**************************************************************************************************** * Konvertierung BCD-kodierter Dezimalzahl */ byte bcdToDec(byte val) {   return ( (val/16*10) + (val%16) ); } /**************************************************************************************************** * Zeit und Datum aus DS1307 auslesen und konvertieren */ void getDateDs1307(int date[]) {   Wire.beginTransmission(DS1307_I2C_ADDRESS); // I2C-Kommunikation im Schreibmodus starten   Wire.send(0x00); // Registerzeiger auf 0 setzen   Wire.endTransmission(); // I2C-Kommunikation beenden   Wire.requestFrom(DS1307_I2C_ADDRESS, 7); // I2C-Kommunikation im Lesemodus starten     date[ 0 ] = bcdToDec(Wire.receive() & 0x7f); // Sekunden   date[ 1 ] = bcdToDec(Wire.receive()); // Minuten   date[ 2 ] = bcdToDec(Wire.receive() & 0x3f); // Stunden   date[ 3 ] = bcdToDec(Wire.receive()); // Wochentag   date[ 4 ] = bcdToDec(Wire.receive()); // Tag   date[ 5 ] = bcdToDec(Wire.receive()); // Monat   date[ 6 ] = bcdToDec(Wire.receive()); // Jahr }   /**************************************************************************************************** */ void setup() {   Wire.begin(); // I2C-Bus einrichten      lcd.init(); // LCD-Anzeige initialisieren   lcd.clear();   lcd.printIn( "DS1307 - Uhr" ); } /**************************************************************************************************** */ void loop() {   int datum[ 7 ];      getDateDs1307( datum );                            // Datum und Uhrzeit aus DS1307 holen   lcd.cursorTo(2, 0); // Datum und Uhrzeit in 2. Zeile schreiben   if( datum[ 4 ] < 10 )     lcd.printIn( "0" );   lcd.printIn( itoa( datum[ 4 ], buffer, 10 ) );     lcd.printIn( "." );   if( datum[ 5 ] < 10 )     lcd.printIn( "0" );   lcd.printIn( itoa( datum[ 5 ], buffer, 10 ) );     lcd.printIn( "." ); /* if( datum[ 6 ] < 10 )   lcd.printIn( "0" ); lcd.printIn( itoa( datum[ 6 ], buffer, 10 ) ); */   lcd.printIn( " " );   if( datum[ 2 ] < 10 )     lcd.printIn( "0" );   lcd.printIn( itoa( datum[ 2 ], buffer, 10 ) );     lcd.printIn( ":" );   if( datum[ 1 ] < 10 )     lcd.printIn( "0" );   lcd.printIn( itoa( datum[ 1 ], buffer, 10 ) );     lcd.printIn( ":" );   if( datum[ 0 ] < 10 )     lcd.printIn( "0" );   lcd.printIn( itoa( datum[ 0 ], buffer, 10 ) );   lcd.printIn( " " );   delay(1000); // grobes Sekundenraster für Anzeige }
Anmerkung:

Achtung:
Mit diesem Beispielprogramm kann man die Uhrzeit im DS1307 nicht stellen sondern nur auslesen. Zum Stellen kann z.B. dieses Applikation verwendet werden:
RTC1307 - Real Time Clock von Combustory.

Auf der Basis dieser Hardwarekonfiguration ( Arduino SD Shield Plus mit DS1307 ) kann ein Datenlogger mit Zeitstempelfunktion erstellt werden.

Anstatt dem aufwendigen SD-Shield mit DS1307 kann man auch andere Shields bzw. Platinen mit dem Maxim DS1307 verwenden.

Hier ein Beispiel:



Man muss dabei nur darauf achten das die I2C-Anschlüsse der DS1307-Platine an die richtigen Ports des Arduinos angeschlossen werden.



05.11.2011

Dipl.-Ing. (FH) Jürgen Mayer, DL8MA - Weinstadt-Grossheppach
Impressum

zurück zu www.DL8MA.de