Im letzten Artikel zur Dekodierung der DCF77-Signale wurde das Ergebnis der Dekodierung auf den seriellen Monitor der Arduino IDE ausgegeben. In diesem Sketch beschreibe ich die Ausgabe auf einem zwei-zeiligen LCD-Display. Deshalb habe ich auch einen grundsätzlichen Beitrag zur Ausgabe auf einem LCD eingeschoben.
Die Ausgabe erfolgt auf dem LCD dabei abwechselnd in der ersten und in der zweiten Zeile. Der Wechsel erfolgt im Takt der empfangenen Signale und damit im Sekundentakt.
Eine weitere Möglichkeit besteht darin, die Werte immer in die unterste Zeile zu schreiben und die alte untere Zeile in die erste zu kopieren. Dadurch entsteht so etwas wie scrollen.
Hier der entsprechende Sketch:
/*================================================================================ Einfaches Programm zum Einlesen von digitalen Signalen eines DCF77 Empfängers Die Zeit zwischen zwei Sekundenimpulsen wird gemessen Die Länge des '1' Signals wir gemessen Daraus wird errechnet ob eine logische 1 oder 0 erkannt wurde Ausgabe der Sekundenimpulse auf eine LED Ausgabe der erkannten Binaerwerte auf einem LCD Display ==================================================================================*/ #include <SoftwareSerial.h> // Einbinden der Softseriel Bibliothek SoftwareSerial LCD(4,7); // Name der Schnittstelle(RX, TX) #define DCF77Pin 2 // An diesen Pin wird der DCF77 Empfänger angeschlossen #define LEDPin 13 // Eingelesene Impulse des Empfängers werden hier ausgegeben int vorheriger_DCF_Wert = 0; // Zwischenspeicher für vorherigen Impulswert (dient zur Flankenerkennung) int DCF77Pegel; // aktuell erkannter Wert am DCF77Pin int Flanke_hoch; // Zeitpunkt in millis an dem die ansteigende Flanke erkannt wurde int Dauer_Eins = 0; // Dauer des '1' Signals int Dauer_Sekunde = 0; // Impulslänge der Sekunde int Binaerwert; int Zeilenwechsler = 1; String Aktuelles_Bit = ""; // Aktuell erknnter Binärwert innerhalb des DCF77 Signals String Zeile_1 = " "; // Variable für Text in Zeile 1 String Zeile_2 = " "; // Variable für Text in Zeile 2 void setup() { LCD.begin(9600); // Einstellen der Baudrate auf 9600 Baud (default bei den seriellen Displays) Serial.begin(9600); pinMode(DCF77Pin, INPUT); // DCF77PIN für Eingabe setzen pinMode(LEDPin, OUTPUT); // LEDPin für Ausgabe setzen clearScreen(); // LCD löschen } void loop() { DCF77Pegel = digitalRead(DCF77Pin); // Wert am DCF77Pin einlesen und in DCF77Pegel speichern if (DCF77Pegel == 1 && vorheriger_DCF_Wert == 0 && (millis()-Flanke_hoch) > 50) { // prüfen ob der aktuelle Wert = 1 ist und der vorherige 0 war = aufsteigende Flanke erkannt Dauer_Sekunde = millis() - Flanke_hoch; // Impulslänge der Sekunde ist die Zeitdauer seit der letzten aufsteigenden Flanke Flanke_hoch = millis(); // Zeitpunkt in millis der aktuellen aufsteigenden Flanke vorheriger_DCF_Wert = 1; // aktueller Wert des erkannten Impulses digitalWrite(LEDPin, DCF77Pegel); // LEDPin auf aktuell erkannten Wert nach Flanke setzen if (Dauer_Sekunde > 1200) { // Ausgabe des erkannten Binärwertes Aktuelles_Bit = "Neue Sekunde "; // Alles größer 1200 ms muss dann die 59. Sekunde sein, die eine neue Minute anzeigt } else if (Dauer_Eins > 150) { // Eine logische 1 dauert 200ms daher sollte eine Impulsdauer >150ms eine 1 sein (Reserve eingebaut) Aktuelles_Bit = "Binaerwert = 1 "; } else { Aktuelles_Bit = "Binaerwert = 0 "; // Eine logische 1 dauert 100ms. Wenn es keine 1 ist muss es eine 0 sein:-) } if (Zeilenwechsler == 1){ // Bei ungerademZähler erfolgtdie Ausgabe in Zeile 1 Zeile_1 = Aktuelles_Bit; Zeile_2 = " "; Zeilenwechsler = 2; } else{ // Bei geradem Zähler erfolgt die Ausgabe in Zeile 2 Zeile_1 = " "; Zeile_2 = Aktuelles_Bit; Zeilenwechsler = 1; } selectLineOne(); // Zeile 1 auswählen LCD.print(Zeile_1); // Text in Zeile 1 ausgeben selectLineTwo(); // Zeile 2auswählen LCD.print(Zeile_2); // Text in Zeile 2 ausgeben } if (DCF77Pegel == 0 && vorheriger_DCF_Wert == 1) { // prüfen ob der aktuelle Wert = 0 ist und der vorherige 1 war = absteigende Flanke erkannt Dauer_Eins = millis() - Flanke_hoch; // Dauer des '1' Signals = Zeit von aufsteigender bis abfallender Flanke vorheriger_DCF_Wert = 0; // aktueller Wert des erkannten Impulses digitalWrite(LEDPin, DCF77Pegel); // LEDPin auf aktuell erkannten Wert nach Flanke setzen } delay(3); // ein bisschen warten wegen unsauberer Flanke } /*==================================================================================================== Subroutinen für die Steuerung des Displays Diese können dann vom Hauptprogramm aufgerufen werden =====================================================================================================*/ void clearScreen() // Löscht alle Zeichen im Display (Meistbenutzte Funktion :-) { LCD.write(0xFE); // Befehls-Flag LCD.write(0x01); // 0x01 } void selectLineOne() // Setzt den Cusor an Position 1 von Zeile 1 { LCD.write(0xFE); // Befehls-Flag LCD.write(128); // Position } void selectLineTwo() // Setzt den Cusor an Position 1 von Zeile 2 { LCD.write(0xFE); // Befahls-Flag LCD.write(192); // Position } void moveCursorRightOne() // Bewegt den Cusor um eine Position nach rechts { LCD.write(0xFE); // Befehls-Flag LCD.write(20); // 0x14 } void moveCursorLeftOne() // Bewegt den Cusor um eine Position nach links { LCD.write(0xFE); // Befehls-Flag LCD.write(16); // 0x10 } void turnDisplayOff() // Schaltet das Display aus,die Hintergrundbeleuchtung bleibt an { LCD.write(0xFE); // Befehls-Flag LCD.write(8); // 0x08 } void turnDisplayOn() // schaltet das Display wieder an { LCD.write(0xFE); //Befehls-Flag LCD.write(12); // 0x0C } void underlineCursorOn() // Cursor als Unterstrich einschalten { LCD.write(0xFE); // Befehls-Flag LCD.write(14); // 0x0E } void underlineCursorOff() // Cursor als Untestrich ausschalten { LCD.write(0xFE); // Befehls-Flag LCD.write(12); // 0x0C } void boxCursorOn() // Cursor als Block einschalten { LCD.write(0xFE); //Befehls-Flag LCD.write(13); // 0x0D } void boxCursorOff() // Cursor als Block ausschalten { LCD.write(0xFE); // Befehls-Flag LCD.write(12); // 0x0C } void toggleSplash() // Begrüßungsbildschirm umschalten { // Einschalten bei "Aus" oder Ausschalten bei "Ein" LCD.write(0x7C); // Befehls-Flag hier mal 0x7C LCD.write(9); // 0x09 } void backlight(int brightness) // Hintergrundbeleuchtung einschalten { // 128 = AUS, 157 = höchster Wert 129 bis 156 sind dann die Zwischenwerte LCD.write(0x7C); // Befehls-Flag hier mal 0x7C LCD.write(brightness); // Werte zwischen 128 und 157 oder 0x80 and 0x9D }
DCF77-Signale dekodieren (Anzeige auf LCD)