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)
