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