2014
HOME
Arduino Rheinturmuhr mit 39 LED
Arduino-Simulator und LED-Rheinturmuhr
Arduino Rheinturmuhr auf TFT-Display
Arduino Rheinturmuhr mit TFT/DCF77-Funk
Arduino Rheinturmuhr mit TFT/GPS-Funk

DCF77-Zeit für die Arduino-Uhr
Rheinturmfunkuhr mit Arduino
Schon zur Zeit des Projekts "Rheinturmuhr mit Arduino" mit den 39 Leuchtdioden schlummerte der Wunsch, die Uhr des Funkturms mit einem Funkuhrmodul DCF77 zu versehen. Versandkosten in Höhe des Artikelpreises waren bisher ein zu hoher Anschaffungswiderstand. Heute liegt die Pollin-Variante auf dem Tisch. Die Dimensionen sind viel kleiner als erwartet, aber ein Info-Blatt ist dabei.
Im Netz gibt es viel zu lesen zum Thema "Arduino und DCF77". Verschiedene Module, verschiedene Ausführungen und vor allem verschiedene Spannungspegel. Selbst dieses Pollin-Exemplar sieht wieder anders aus als die zwei bisher gefundenen Varianten im Netz. Sicher ist, dass das hier vorliegende Exemplar eigentlich für den Einbau in eine Uhr gedacht ist. Minimalste Ströme und vermutlich hohe Widerstände für langen Batterielauf. Mancher - so war zu lesen - soll sogar schon aufgegeben haben bei diesem Modul ...

Nach etwas Internet-Suche und Analyse soll die Funkuhr nach folgenden Schritten der Rheinturmuhr mit TFT-Display zugeführt werden:

Die Abbildung zeigt den alten Zustand ohne Datum durch das Funkmodul. In dieser Antennestellung ist kein Empfang möglich.

Hier die Schritte im Detail.


DCF77-Modul Pollin-Variante 2014

Das Modul soll sehr empfindlich auf zu hohe Spannungen reagieren und Langwellen von 77 kHz gehen zwar durch Wände, lassen sich aber auch leicht durch moderne Elektronik stören. Also Handy, PC, Netzteile, Energiesparlampen möglichst weit weg von der Antenne und der Arduino auch. Da die Gesamtschaltung weniger als 90 uA aufnimmt, wird der Data-Ausgang auch nicht sehr belastbar sein. Für solche Zwecke wurde der Impedanzwandler bzw. der nicht-invertierende Verstärker mit Verstärkungsfaktor 1 erfunden. Seine Merkmale sind ein extrem hoher Eingangswiderstand, also keine Last für die Quelle und ein sehr niedriger Ausgangswiderstand und damit hoch belastbar. Ein gängiger Operationsverstärker in Form des 741 ist gerade verfügbar. Auf die bipolare Spannungsversorgung wird wegen der gewünschten Einfachheit verzichtet. Mit 3,3 Volt rührt sich beim 741 nichts, aber 5 Volt reichen dem IC.

Rechts die Abbildung der Testschaltung. Der Arduino wird mit einem Netzteil vom teuren Handy angetrieben, welches ein erfreulich kleines Störfeld produziert. Mit PON auf Masse läuft das Modul hier alleine an und nach ca. 2 bis 5 Sekunden blinkt die LED im Sekundentakt.

Allerdings muss der Ferritstab horizontal in Richtung Frankfurt ausgerichtet sein. In der Abbildung sollte der DCF-Sender aus Richtung "DCF77" strahlen. Somit lebt das Modul und das "Herz" schlägt im Sekundentakt. Allerdings mit Herzrhythmusstörungen, denn der Datenstrom des Senders ist auch bei störungsfreiem Empfang nicht ganz regelmäßig. Die LED leuchtet in jeder Sekunde kurz auf, aber die Dauer ist unterschiedlich. Genau so - quasi wie beim Morsen - werden die einzelnen Bits übertragen. Der Zeitdatenstrom arbeitet demnach mit ca. 1 bps (ein Bit pro Sekunde). Die 59. Sekunde hat allerdings kein "bit" , wodurch die Minuten-Erkennung erfolgt. Zu jeder Minute fehlt immer ein Impuls, was bei LED-Beobachtung schon einen Herzstillstand befürchten lässt. Aber genau dann ist ein Datensatz wieder komplett, falls es keine Störungen gab. Die genaue Bedeutung der einzelnen Bits der Übertragung ist im Netz mehrfach dokumentiert.


Bibliotheken Software-Test
Im Laufe der Jahre haben sich verschiedene kluge Köpfe an diesem Modul abgearbeitet, so dass der Arduino-Patchwork-Programmierer nur noch ernten braucht. Unter playground.arduino.cc ist der Verweis auf den Urheber Thijs Elenbaas der verwendeten Bibliothek, die auf seiner DCF- Seite vorgestellt und erläutert wird. Thijs baut wiederum auf Arbeiten von Matthias Dalheimer auf, da in seinem Standort größere Störungen auftraten. Wird die Bibliothek DCF77 von Thijs Elenbars installiert, erscheinen auch die dazugehörenden Beispiele.

Diese übersichtlichen kleinen Testprogramme dienen dazu, die Kommunikation zwischen Modul und Arduino zu testen. Als erstes zeigt "DCFSignal" das eingelesene Signal an PIN 13, also der eingebauten LED des Arduino an. Außerdem werden die Impulslängen der einzelnen "Bits" im Serial-Monitor dargestellt. So gewinnt man einen ersten Eindruck zur Qualität des Signals. Der Sketch "DCFPulseLength" macht ähnliches auf andere Art und Weise. Erst mit "DCFBinaryStream" wird die Sache richtig datenstromförmig. Wenn die Zeiten der Signale stimmen können die binären Daten "1" und "0" bestimmt werden. Hier werden bereits die Bibliotheken "DCF77" und "Time" eingebunden, wodurch dieses Testprogramm bereits in der Lage ist, die Daten komplett zu dekodieren. Allerdings wird dies in den wenigsten Fällen sofort problemlos ablaufen. Vielfältige Störungen sorgen oft dafür, dass fehlerfreie Daten erst sehr spät oder gar nicht vorliegen. Die Ursachen dafür kann man erforschen indem die "Verbose"-Funktion (die Geschwätzigkeit) der Bibliothek aktiviert wird. Oben im Sketch steht, dass dies durch ein #define VERBOSE_DEBUG 1 in Utils.cpp geschehen kann. Dies ist ausgeschaltet und sollte bei schwierigen Verhältnissen empfangstechnischer Natur immer an bleiben, da so über den Serial-Monitor entsprechende Informationen erfolgen.

Die Bibliothek benutzt einen Interrupt, so dass unabhängig vom eigentlichen Programm in der loop() die einkommenden Bits verarbeitet werden. Dadurch wird die Zuführung des DCF-Signals auf wenige Pins beschränkt. Welcher Arduino welchen Pin und welchen Interrupt benutzen kann ist auf arduino.cc unter attatchInterrupt() beschrieben. Beim Arduino Uno ist Pin 2 mit Intrerrupt 0 verknüpft. Genau so sind die Beispielsketche auch kodiert.

.....


Benötigte Funktionen aus DCF77 und Time
Der Sketch "DCFBinaryStream" enthält alles, was benötigt wird die Rheinturmuhr per Funk zu synchronisieren. Zu Beginn findet man das Einbinden der beiden Bibliotheken. Danach Pin und Interrupt, die dann bei der Initialisierung des Objekts DCF weiter gereicht werden. Eine Struktur "time" enthält Zeitinformationen. In setup() wird dann nur noch der Dekoder gestartet, alles andere bleibt dem Patchwork-Programmierer verborgen.
#include <DCF77.h> 
#include <Time.h>  

#define DCF_PIN 2	        
#define DCF_INTERRUPT 0		 

time_t time;

DCF77 DCF = DCF77(DCF_PIN,DCF_INTERRUPT);

void setup() 
{DCF.Start();
}

In loop() findet nicht sehr viel statt, da sich alles im Untergrund abspielt. Im 1000 ms-Intervall wird mit DCF.getTime() abgefragt, wie der Zustand der Dekodierung ist, um das Ergebnis wenn neue Daten vorliegen zur Anzeige zu bringen.

void loop() 
{delay(1000);
 	time_t DCFtime = DCF.getTime();
	if (DCFtime!=0)		digitalClockDisplay(DCFtime);
}

In der Anzeigeroutine werden die verschiedenen Elemente mit der Funktion breakTime aus der time_t-Struktur in eine einfache Integer-Struktur tmElements_t zurück gewandelt:

void digitalClockDisplay(time_t _time)
{ tmElements_t tm;   
  breakTime(_time, tm);
  Serial.print("Time: ");
  Serial.print(tm.Hour);
  Serial.print(":");
  ....
  Serial.print(tm.Month);
  Serial.print(".");
  Serial.println(tm.Year+1970);
}

										

Quelltextumbau
Würde eine Rheinturmuhr von Anfang an mit einem Funkmodul und dieser Bibliothek geplant worden sein, würde der Quelltext sicher anders aussehen. Hier wird lediglich die Funkuhrzeit in den vorhandenen Quelltext so eingebaut, dass die Uhr so läuft wie vorher, jetzt lediglich von DCF77-Daten gestellt wird, falls diese vorliegen.

Um zu zeigen, dass die Zeit eine genaue Funkzeit ist, werden während einer gewissen Zeit die Positionslampen grün dargestellt. Außerdem erfolgt oben links die Anzeige des aktuellen Datums. Fehlt nach einer gewissen Zeit die Synchronisation, werden die Positionslampen wieder rot, das Datum bleibt stehen, wird aber nicht mehr aktualisiert. Also ist bei Datum und grünen Lampen alles im grünen Bereich - Funkzeit vorhanden. Hier unten sind Änderungen fett aufgeführt:

#include <SPI.h>
#include <Adafruit_GFX.h> 
#include <Adafruit_ST7735.h>

//DCF77
#include <DCF77.h>  
#include <Time.h> 

#define DCF_PIN 2	
#define DCF_INTERRUPT 0		

time_t time;
DCF77 DCF = DCF77(DCF_PIN,DCF_INTERRUPT);

#define TFT_CS    10
#define TFT_RST    8
#define TFT_DC     9

Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS,  TFT_DC, TFT_RST);

int s10=0,s01=0; //ONESECOND TENSECOND BAND
int m10=5,m01=9; // Start mit 23:59:00 Uhr
int h10=2,h01=3; //
#define STIME 60
int sync=STIME; //SyncSignTime

unsigned long t,t0,interval=1000; //TIMEINIT 
unsigned long TIMEREAD(void){return millis()-t0;}
//Colors
#define rgb      Color565
#define BACK     rgb(0,0,255)
#define TOWER    rgb(63,63,63)
#define LAMP_ON  ST7735_YELLOW
#define LAMP_OFF rgb(127,127,127)
#define LAMP_POS rgb(255,0,0)
#define DIGITS   LAMP_ON

void setup(void) {
  Serial.begin(9600);
  Serial.print("Rheinturmuhr auf 1.8 TFT/DCF77 by H.-J. Berndt");
  tft.initR(INITR_BLACKTAB);   
  int w2=tft.width()/2;
  int h=tft.height();
  tft.fillScreen(BACK);
  tft.fillTriangle(w2-15,50,w2+15,50,w2+1,75,TOWER);//V
  tft.fillTriangle(w2+1,5,w2-6,h,w2+8,h,TOWER);// ^
  tft.fillRect(w2-14,43,30,3,TOWER);//=
  tft.fillRect(w2-11,36,24,3,TOWER);//-
  tft.setTextSize(1);
  tft.setTextColor(DIGITS,BACK);
  DCF.Start();
  t0=millis();
}

void loop() 
{char s[80]; int i,x,y,is;
 t=TIMEREAD();
 x=tft.width()>>1;
 y=tft.height()-8;
 i=1; //1-39 Lamps
 do //The Clock
 {switch (i) //Decode Time To Lamp 
  {case  1: case  2: case  3: case  4: 
   case  5: case  6: case  7: case  8: case  9:  
   is=s01>(i-1); break;        
   case 10: case 11: case 12: case 13: 
   case 14:  is=s10>(i-10); break; //Seconds  
   case 15: case 16: case 17: case 18: case 19: 
   case 20: case 21: case 22: case 23: is=m01>(i-15);
   break;
   case 24: case 25: case 26: case 27: case 28:  
   is=m10>(i-24); break; //Minutes
   case 29: case 30: case 31: case 32: case 33: 
   case 34: case 35: case 36: case 37: is=h01>(i-29);
   break;
   case 38: case 39: is=h10>(i-38); break;  //Hours
  }    
  tft.drawFastHLine(x, y, 2, is ? LAMP_ON : LAMP_OFF);
  y-=2;
  if(i==9 || i==9+5 || i==9+5+9 || i==9+5+9+5 || i==9+5+9+5+9)
  {tft.fillCircle(x-2, y-1, 1, 
    (sync < STIME)?rgb(0,255,0):LAMP_POS);
   tft.fillCircle(x+2, y-1, 1, 
    (sync < STIME)?rgb(0,255,0):LAMP_POS);
   y-=4;
  }
 }while(++i<=39); //all done
 //Text Time
 tft.setCursor(3, tft.height()-12);
 sprintf(s,"%0d%0d:%0d%0d:%0d%0d",
            h10,h01,m10,m01,s10,s01);
 tft.print(s);
 
 sync++; 
 time_t DCFtime = DCF.getTime();
 if (DCFtime!=0)
 {char n='0';
  tmElements_t tm;   
  breakTime(DCFtime, tm);
  sprintf(s,"%02d:%02d:%02d",tm.Hour,tm.Minute,tm.Second);
  Serial.println(s);
  h10=s[0]-n;  h01=s[1]-n;
  m10=s[3]-n;  m01=s[4]-n;
  s10=s[6]-n;  s01=s[7]-n;
  tft.setCursor(3, 4);
  sprintf(s,"%02d.%02d.%02d",tm.Day,tm.Month,
          tm.Year+1970-2000);
  tft.print(s);
  sync=0;
 }
 else
 {s01++;                   //s++;
  if(s01>=10){s01=0;s10++;} 
  if(s10>=6){s10=0;m01++;} //m++;
  if(m01>=10){m01=0;m10++;}
  if(m10>=6){m10=0;h01++;} //h++;
  if(h01>=10){h01=0;h10++;}
  if(h10>=2 && h01>=4){h10=0;h01=0;}
}
 //waiting ...
 while(TIMEREAD()<(t+interval));
 //one second
 interval=analogRead(A0)==0?100:1000;
}

Hier dieser Quelltext der grafischen Variante mit DCF77 als Arduino-ino-Datei ab IDE 1.0

										

Testlauf Spannende Minuten
Abbildung (Foto): Alles im grünen Bereich - auch am nächsten Tag.
Wenn die LED sauber blickt kann ein Test erfolgen. Der Sketch setzt die Uhrzeit immer noch auf 23:59:00, also eine Minute vor Mitternacht. Da die Bibliothek mindestens zwei fehlerfreie Minuten braucht, um die Uhrzeit frei zu geben, kann es bei guten Bedingungen nach 2 bis 3 Minuten zur Synchronistaion kommen. Falls der PC nicht sehr stört, kann der Dekoder über den Serial-Monitor beobachtet werden. Zu Testzwecken kann an Ausgang 6 des 741 ein Piezo-Schallgeber angeschlossen werden. Dann sind die Störungen auch noch hörbar. Bei Energiesparlampenbetrieb in der Nähe der Antenne ist während der Impulsdauer ein deutliches "Rattern" (Netz) zu hören. Auch ohne Lampe gab es hier einige 'hörbare' Störungen, die von der Bibliothek aber souverän abgefangen wurden. Pünktlich um 00:02:00 erfolgte die Synchronistation und alles war im grünen Bereich ...

Zum Schluss wurde das Signal DATA des DCF-Moduls direkt an PIN 2 des Arduino angeschlossen. Zur Kontrolle greift der 741 das Signal noch ab, um die LED und das Piezo-Ticken zu erhalten. Die Testschaltung kann jedoch offensichtlich ganz entfallen, zumindest 'tickt' das Modul bisher noch munter weiter. Damit wird der Aufbau nochmals erfreulich einfacher.


											

										

End of Patchwork SD-Karte mit Foto-Datei
Der Einbau dieser Synchronisation in die Fotoanimation der Rheinturmuhr mit TFT-Display gelingt zur Zeit nicht auf die gleiche Art und Weise, da die SD-Bibliothek den 32k-Speicherplatz an seine Grenzen treibt. Zwar wird der Sketch übertragen, die Setup-Routine führt aber teilweise Endlosschleifen aus. Entsprechend gibt es Diskussionen zur Größe der SD-Bibliothek. Für diese Anwendung wären nur Leseroutinen notwendig. Eine neue IDE soll den Speicher besser benutzen, womit diesmal der Patch noch klappen könnte, aber vermutlich müssen irgendwann 'einfach' die Bibliotheken zielgerichtet angepasst werden.

Für die Rheinturmuhr mit den 39 Leuchtdioden müsste PIN 2 frei gemacht werden wegen der Interruptverknüpfung. Da noch drei Analoganschlüsse frei sind könnte das klappen, wenn diese sich auch als Digitalausgang verwenden lassen.


										
Arduino Rheinturmuhr mit 39 LED
Arduino-Simulator und LED-Rheinturmuhr
Arduino Rheinturmuhr auf TFT-Display
Arduino Rheinturmuhr mit TFT/DCF77-Funk
Arduino Rheinturmuhr mit TFT/GPS-Funk

Weitere Software
.
Startseite Bücher Software Digital RTV Musik Kontakt

Für Inhalt und weitere Verzweigung externer Links sind die Betreiber der dortigen Seiten verantwortlich - H.-J. Berndt