LED Echtzeituhr mit dem 4 Bit Digital Tube LED Display (Teil 1)

Hallo und willkommen zu einem neuen spannenden Blog in der Welt der Mikroelektronik.

Im heutigen ersten Teil einer mehrreihigen Blogreihe befassen wir uns mit einem Re-Work eines bereits erschienen Blogartikels mit dem Aufbau einer Echtzeituhr. Die Uhrzeit ist jederzeit bequem mit zwei Tastern einstellbar, bringt einen animierten Sekundenanzeiger (blinkenden Doppelpunkt) mit und ist darüber hinaus auch sehr preiswert aufzubauen, da auf eine externe RTC Uhr verzichtet werden kann. 

Der Nachteil besteht in diesem Teil des Blogs noch jedoch daraus, dass bei einem Stromausfall die Uhr wieder neu gestellt werden muss. Dies werden wir noch in den kommenden Teilen mit Erweiterungen unserer Uhr ändern. Für viele Anwendungen steht jedoch mit dem Code bereits ein solides Grundgerüst bereit. Darüber hinaus ist die Teileliste sehr übersichtlich:

Wir verdrahten die Teile wie auf folgendem Bild ersichtlich miteinander:

Bevor wir nun zur eigentlichen Programmierung schreiten können, müssen wir uns noch die TM1637 Driver by AKJ Bibliothek zur Ansteuerung des TM1637 installieren. Nur diese unterstützt bei gleichzeitigem kleinem Speicherbedarf die einfache alternierende Ansteuerung der Doppelpunkte durch einen Befehl.

Fritzing Schaltung

 

Die beiden Taster dienen zum Einstellen der Uhr.

 

Anschluss Tabelle

 

Bevor wir nun zur eigentlichen Programmierung schreiten können, müssen wir uns noch die TM1637 Driver by AKJ Bibliothek zur Ansteuerung des TM1637 installieren. Nur diese unterstützt bei gleichzeitigem kleinem Speicherbedarf die einfache alternierende Ansteuerung der Doppelpunkte durch einen Befehl.

 

TM1637 Driver installieren

Sobald die Bibliothek installiert ist, kann folgender Code hochgeladen werden:

 

 

  #include <TM1637.h>
  // Code by Tobias Kuch 2019, License unter GPL 3.0
  
  // Initialisation and pin configuration
  // Pin 4 - > DIO
  // Pin 5 - > CLK
  TM1637 tm1637(4, 5);
  
  
  #define BUTTON_MINUTEUP_PIN   2    // Digital IO pin connected to the button.  This will be
  // driven with a pull-up resistor so the switch should
  // pull the pin to ground momentarily.  On a high -> low
  // transition the button press logic will execute.
  // Used for Setting the Clock Time
  
  #define BUTTON_HOURUP_PIN   3    // Digital IO pin connected to the button.  This will be
  // driven with a pull-up resistor so the switch should
  // pull the pin to ground momentarily.  On a high -> low
  // transition the button press logic will execute.
  // Used for Setting the Clock Time
  
  
  // interrupt Control
  bool SecInterruptOccured = true;
  bool A60telSecInterruptOccured = true;
  byte A60telSeconds24 = 0;
  
  
  // Clock Variables
  byte Seconds24;
  byte Minutes24 ;
  byte Hours24;
  bool DisableSecondDisplay = false;
  bool MinSetQuickTime = false;
  bool HourSetQuickTime = false;
  bool ButtonDPress = false;
  bool ButtonEPress = false;
  
  //Interrupt Routines
  
  ISR(TIMER1_COMPA_vect)
  {
    A60telSeconds24++;
    tm1637.switchColon();
    if ((A60telSeconds24 > 59) and !(MinSetQuickTime))
    {
      A60telSeconds24 = 0;
      //Calculate Time 24 Stunden Format
      SecInterruptOccured = true;
      Seconds24++;
      if (Seconds24 > 59)
      {
        Seconds24 = 0;
        Minutes24++;
      }
      if (Minutes24 > 59)
      {
        Minutes24 = 0;
        Hours24++;
      }
      if (Hours24 > 23)
      {
        Hours24 = 0;
      }
    }
  
    if  (MinSetQuickTime)
    {
      A60telSeconds24 = 0;
      //Calculate Time 24 Stunden Format
      SecInterruptOccured = true;
      Seconds24++;
      if (Seconds24 > 59)
      {
        Seconds24 = 0;
        Minutes24++;
      }
      if (Minutes24 > 59)
      {
        Minutes24 = 0;
        Hours24++;
      }
      if (Hours24 > 23)
      {
        Hours24 = 0;
      }
    }
  
    TCNT1 = 0;      // Register mit 0 initialisieren
  
  
    if  (HourSetQuickTime)
    {
      OCR1A =  200;
    } else
    {
      OCR1A =  33353;      // Set Output Compare Register
    }
    A60telSecInterruptOccured = true;
  }
  
  
  
  
  //Interrupts ende
  
  void CheckConfigButtons ()    // InterruptRoutine
  
  {
  
    bool PressedZ;
  
    PressedZ = digitalRead(BUTTON_MINUTEUP_PIN);
    if ((PressedZ == LOW) and (ButtonDPress == false))
    {
      ButtonDPress = true;
      delay(100);
      Minutes24++;
      Seconds24 = 0;  // Reset Seconds to zero to avoid Randomly time
      DisableSecondDisplay = true ;   // Disable Seconds While Clock Set
      MinSetQuickTime = true; //Enable Quick Tmime Passby
  
    }
    if ((PressedZ == HIGH) and (ButtonDPress == true))
    {
      ButtonDPress = false;
      delay(100);
      DisableSecondDisplay = false ;   // Enable Seconds While Clock Set
      MinSetQuickTime = false;
      Seconds24 = 0;  // Reset Seconds to zero to avoid Randomly time
      A60telSeconds24 = 0;
  
    }
  
    PressedZ = digitalRead(BUTTON_HOURUP_PIN);
    if ((PressedZ == LOW) and (ButtonEPress == false))
    {
      ButtonEPress = true;
      delay(100);
      DisableSecondDisplay = true ;   // Disable Seconds While Clock Set
      MinSetQuickTime = true; //Enable Quick Tmime Passby
      HourSetQuickTime = true;
    }
    if ((PressedZ == HIGH) and (ButtonEPress == true))
    {
      noInterrupts();
      ButtonEPress = false;
      delay(100);
      Minutes24++;
      DisableSecondDisplay = false ;   // Enable Seconds While Clock Set
      MinSetQuickTime = false; //Enable Quick Tmime Passby
      HourSetQuickTime = false;
      Seconds24 = 0;  // Reset Seconds to zero to avoid Randomly time
      A60telSeconds24 = 0;
      interrupts();
    }
  
  
  }
  
  
  
  
  void setup()
  {
    tm1637.init();
    tm1637.setBrightness(8); // Highest Brightness
    pinMode(BUTTON_MINUTEUP_PIN, INPUT_PULLUP);
    pinMode(BUTTON_HOURUP_PIN, INPUT_PULLUP);
    digitalWrite(LED_BUILTIN, LOW);
    noInterrupts();
    TCCR1A = 0x00;
    TCCR1B =  0x02;
    TCNT1 = 0;      // Init Register
    OCR1A =  33353;      // Output Compare Register vorbelegen
    TIMSK1 |= (1 << OCIE1A);  // Timer Compare Interrupt aktivieren
    interrupts();
    Seconds24 = 1;
    Minutes24 = 1;
    Hours24 = 0;
    tm1637.dispNumber(Minutes24 + Hours24 * 100);
  }
  
  
  void DisplayClockOnLedTM1637()
  
  {
    tm1637.switchColon();
    tm1637.dispNumber(Minutes24 + Hours24 * 100);
  }
  
  void loop()
  {
    bool PressedC;
    if (A60telSecInterruptOccured)
    {
      A60telSecInterruptOccured = false;
    }
    if (SecInterruptOccured)
    {
      SecInterruptOccured = false;
      DisplayClockOnLedTM1637();
    }
    CheckConfigButtons();
  }

 

 

In den nachfolgenden Teilen werden wir unserer Uhr noch ein paar schöne Features spendieren.


Ich wünsche viel Spaß und bis zum nächsten Mal.

 

Letzter Artikel LED Echtzeituhr mit alternierender Temperatur und Luftfeuchteanzeige (Teil 2)
Neuer Artikel IR-Thermometer

Kommentar

Mirko Voigtländer - Januar 5, 2020

Hallo Leute
nachdem ich die vertauschten Anschlüsse im Griff hatte, habe ich jetzt einen Schnellläufer.
Die Minuten laufen im Sekundentakt und einstellen ist kaum möglich.
Woran liegts??
Hat jemand ähnliche Probleme?

Ronny - Dezember 15, 2019

Hallo,

könnt Ihr bitte einmal einen Warenkorb für alle benötigten Bauteile dieses Kurses vorbereiten, damit ich nur noch auf bestellen klicken brauche?

Das Projekt ist sehr interessant, ich hätte nur gerne einmal alles auf einer Liste, damit ich alle Bauteile kaufen kann, um das Gesamtprojekt nachbauen zu können..

Vielen Dank,
Ronny

Frank Cordes - Dezember 13, 2019

Antwort auf meine Fragevom Dezember 11, 2019

CLK und DIO Pin 4 und 5 sind im Sketch vertauscht…

Thomas Schimmer - Dezember 12, 2019

Hallo Frank,
ich habe das gleiche Problem.
Hoffe, wir bekommen da einen Tipp um das Problem zu beseitigen.
Gruß
Thomas

Tobias - Dezember 12, 2019

Hallo Frank,

Leider leuchtet die LED Anzeige ohne korrekte Ansteuerung selbst bei anliegen von VCC nicht von alleine. Ohne Details zu erfahren ist auch eine Fehler Diagnose von der Ferne schwer zu stellen. Sind alle Bauteile korrekt verdrahtet worden, liegt überall die korrekte Spannung an ? ( ggf. mit einem Spannungsprüfer testen) Ist der Code korrekt kompiliert worden und auf den Nano übertragen worden ? (Hier mal mit einem einfachen Programm vorab testen)
Viele Grüße

Frank Cordes - Dezember 11, 2019

Hallo!

Hab alle Einzelteile bestellt und bin total zufrieden, aber nachdem ich alles, soweit ich das beurteilen kann, korrekt zusammen gebaut habe, sehe ich leider keine Reaktion bzw. nicht eine LED der 7-Segment-Anzeige leuchten.

Hab ich was falsch gemacht? Oder ist die Anzeige defekt?
Kann man die Anzeihe ohne programmierte Ansteuerung testen? Muss ein Teil der 7-Segement-Anzeige bei VCC und GND 5V an sein?

Schade, dass dies heute nicht auf anhieb geklappt hat.

mfg

Frank C. aus D.

PS: dagegen war der LED-Weihnachtsbaum kein Problem… :-)

Manfred - Dezember 7, 2019

Hallo, ich wünsche mir, das immer der elektrische Schaltplan bei den Projekten gleich dabei ist. Da viele Teile schon in der Bastelkiste vorhanden sind, möchte ich nichts neues kaufen sondern die vorhandenen Teile verwerten und auch anpassen. Beispielsweise der Taster-Baustein kann einfach selbst gelötet werden. Danke und Grüße

Roger - Dezember 7, 2019

Hallo zusammen,
Warum nutzt ihr den Nano und nicht einen preiswerten ESP?
Es macht m.E. keinen wirklichen Sinn, nicht sofort einen ESP zu nutzen, ganz besonders schön wegen des Preises und der Möglichkeit, die benötigten Daten aus dem Netz zu holen.
Gruß,
Roger

Neuroplant - Dezember 7, 2019

Hallo,
Wenn man statt dem nano einen esp nimmt, kann man sich die Buttons sparen und die Zeit via ntp stellen.
Gruß
Neuroplant

Hinterlasse einen Kommentar

Kommentare müssen vor der Veröffentlichung überprüft werden

Erforderliche Angabe