DCF77-Signale dekodieren (Anzeige auf LCD)

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
}

 

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.