Montag, 4. Juni 2012

Projekt Analoguhr - Teil 4

Ein weiterer Meilenstein wurde erreicht, die Uhr läuft schonmal. Bisher wurde zwar kein Funkuhrmodul verbaut, dafür wurde jedoch eine sogenannte Real Time Clock eingesetzt. Diese Echtzeituhr ist batteriegepuffert, läuft also unabhängig von der Versorgungsspannung der Uhr permanent im Hintergrund.
Für erste Experimente habe ich mir ein fertiges Modul zum Anschluss an den I2C-Bus schicken lassen: Hier verrichtet ein DS1307 seinen Dienst, sämtliche erforderlichen Komponenten wie Batteriehalter und ein Uhrenquarz sind ebenso auf der Platine enthalten.

Um die Programmierung möglichst übersichtlich zu halten, habe ich darauf geachtet, die einzelnen "Aufgaben" in separate Funktionen zu gliedern.
So gibt es  bspw. die setRTCtime()- und die getRTCtime()-Funktion. Später wird der Sketch um eine Funktion getDCFtime() ergänzt, die in regelmäßigen Zeitabständen aufgerufen wird und das Funkuhrsignal auswertet. Dann erfolgt eine simple Abfrage, ob die RTC-Zeit aus getRTCtime identisch zur DCF77-Zeit ist. Ist dies nicht der Fall, wird die RTC-zeit mittels setRTCtime() neu gesetzt.
Wie es hier zu Abweichungen kommen kann, wird sich der eine oder andere fragen. Zum einen ist eine RTC auch nicht genauer als eine herkömmliche Quarzuhr, denn letzten Endes ist sie ja nichts anderes. Ein anderer Fall ist die Umstellung von Sommer- auf Winterzeit (oder auch umgekehrt), denn das beherrscht die RTC im Gegensatz zur Funkuhr nicht.

Dazu noch das passende Video für die visuell geprägte Leserschaft:


Und zum Abschluss noch ein paar Zeilen Code:

#include "Wire.h"
#define DS1307_ADDRESS 0x68

byte pinMinute = 9;
byte pinStunde = 10;

byte zero = 0x00;
byte sekunde;
byte minute;
byte stunde;
byte am;
byte pm;

void setup(){
  Wire.begin();
  Serial.begin(9600);
  pinMode (pinMinute, OUTPUT);
  pinMode (pinStunde, OUTPUT);
  // setRTCtime(21,57,15);
}

void loop(){
  getRTCtime();
  // printRTCtime(stunde, minute, sekunde);
  showTime(stunde, minute, sekunde);
  delay(500);
}

byte decToBcd(byte val){
  return ((val/10*16)+(val%10));
}

byte bcdToDec(byte val){
  return ((val/16*10)+(val%16));
}

void getRTCtime(){
  Wire.beginTransmission(DS1307_ADDRESS);
  Wire.write(zero);
  Wire.endTransmission();
  Wire.requestFrom(DS1307_ADDRESS, 7);
  sekunde = bcdToDec(Wire.read());
  minute = bcdToDec(Wire.read());
  stunde = bcdToDec(Wire.read() & 0b111111);
  int weekDay = bcdToDec(Wire.read()); 
  int monthDay = bcdToDec(Wire.read());
  int month = bcdToDec(Wire.read());
  int year = bcdToDec(Wire.read());
  if (stunde==0||stunde==12){
    am=0;
    pm=0;
  }
  if (stunde>1&&stunde<=12){
    am=1;
    pm=0;
  }
  if (stunde>12&&stunde<=23){
    am=0;
    pm=1;
  }
}

void setRTCtime(byte h, byte m, byte s){
  byte weekDay =     1; //1-7
  byte monthDay =    1; //1-31
  byte month =       1; //1-12
  byte year  =       0; //0-99

  Wire.beginTransmission(DS1307_ADDRESS);
  Wire.write(zero);
  Wire.write(decToBcd(s));
  Wire.write(decToBcd(m));
  Wire.write(decToBcd(h));
  Wire.write(decToBcd(weekDay));
  Wire.write(decToBcd(monthDay));
  Wire.write(decToBcd(month));
  Wire.write(decToBcd(year));
  Wire.write(zero);
  Wire.endTransmission();
}

void printRTCtime(byte h, byte m, byte s){
  Serial.print(h);
  Serial.print(":");
  Serial.print(m);
  Serial.print(":");
  Serial.println(s);
}

void showTime(byte h, byte m, byte s){
  if (h>12) h=h-12;
  if (h==12) analogWrite (pinStunde, h*20);
    else analogWrite (pinStunde,h*20+m/4); // rechnerisch eigentlich 3
  analogWrite(pinMinute, m*4);  
}

Keine Kommentare:

Kommentar posten