MicroPython Uhr

Nach meinen ersten Gehversuchen mit MicroPython/CircuitPython auf ESP8266-Systemen habe ich mir ein praktisches Projekt gesucht. Mit MicroPython auf dem ESP8266 sollte es sehr einfach ein, eine NeoPixel-Reihe anzusteuern, sich per WLAN mit dem Internet zu verbinden und per NTP eine aktuelle Uhrzeit zu ermitteln. Einzig die Zeitzone kann ich so nicht ermitteln.

Überlegung

Im Keller hatte ich noch einen LED-Kreis mit 60 RGB-LEDs, der auf einen Einsatz wartet. Dazu brauche ich dann noch einen ESP8266 mit einem Digitalausgang, der die Neopixel ansteuert. Ich habe nicht vor, alle LEDs gleichzeitig mit voller Helligkeit zu betreiben. Ein paar LEDs für Stunde, Minute, Sekunden sollten ausreichen. Daher habe ich erst einmal kein XXL-Netzteil besorgt. Die 5V-Versorgung der LEDs lasse ich aber nicht über den Spannungsregler des ESP laufen.

Die Beschaltung ist für einen Test mit 3,3V ESP8266 trivial: Einfach nur den Neopixel-Kreis mit Vcc, GND und den GPIO5 verbinden. Alles andere ist auf dem ESP8266 schon da. Beachten Sie aber auch die Hinweise auf LEDs und WS2812 bezüglich Vorwiderständen und Stützkondensatoren.

Wer es noch sparsamer machen möchte, kann einfach einen ESP01 einsetzen. Aber hier kommt es nicht auf Stromsparen an, da die LEDs ja eh den meisten Strom brauchen.

Das Skript holt sich regelmäßig die Uhrzeit per NTP und aktualisiert dann alle LEDs. Wenn Sie genau hinschauen, dann sehen Sie vier Farben:

  • Weiss - Viertel-Anzeige
     Eher schlecht können Sie die vier weißen Markierungen bei 3,6,9 und 12 Uhr erkennen. Die sollten aber absichtlich nicht so hell sein, sondern nur einen Indikator für die Viertel darstellen
  • Blaue Schlange
    Die erste LED ist die aktuell Sekunde und die nachfolgenden sind immer etwas schwächer. Das ergibt so einen "Wischeffekt"
  • Grüner Punkt
    Das sind die Minuten (ca. 15)
  • drei rote LEDs
    Diese kennzeichnen die angefangene Stunde (7/19 Uhr). Bei jeder vollen Stunde springt die Stunde um 5 LEDs weiter.

Die Uhr zeigt also 19:15:49

Konfiguration

Ich habe im Code keine Library o.ä. eingebunden, welche erst einen AccessPoint startet, damit sie eine Konfiguration vornehmen können. Sie müssen ja eh vorher noch MicroPython auf das Gerät flashen und den das Programm drauf kopieren. Da sollte es kein Problem sein, im Code noch schnell die WLAN-Daten (SSID und Kennwort) einzutragen, damit der ESP8266 sich verbinden und per NTP die Uhrzeit abholen kann. Ich nutze meinen Freifunk-Router ohne Kennwort als Default.

Zeitzone

NTP liefert immer nur die "Greenwich Normalzeit" liefert. Ich muss also selbst die Umrechnung in die lokale Zeit vornehmen und idealerweise gleich noch Sommerzeit/Winterzeit berücksichtigen. Das habe ich dann wie folgt gemacht.

def tzoffset(now):
    # Auszuege von https://community.hiveeyes.org/t/berechnung-von-sommerzeit-winterzeit-in-micropython/3183
    year = now[0]       #get current year
    HHMarch   = time.mktime((year,3 ,(31-(int(5*year/4+4))%7),1,0,0,0,0,0)) #Time of March change to CEST
    HHOctober = time.mktime((year,10,(31-(int(5*year/4+1))%7),1,0,0,0,0,0)) #Time of October change to CET
    now=time.time()
    if now < HHMarch :               # we are before last sunday of march
        tzoffset=1                   # CET:  UTC+1H
    elif now < HHOctober :           # we are before last sunday of october
        tzoffset=2                   # CEST: UTC+2H
    else:                            # we are after last sunday of october
        tzoffset=1                   # CET:  UTC+1H
    return(tzoffset)

LED-Steuerung

Bei der Uhr laufen drei Signale im Kreis und überlappen sich auch. Ich habe zwar drei Farben aber muss immer alle drei Farben auch setzen. Ich habe mir daher erst ein Array mit 60 Speicherplätzen a 3 Byte (R+G+B) initialisiert und schreibe dort nacheinander dann die Sekunde, Minute , Stunde, ehe ich dann die Daten zum Nexopixel-Stang sende.

Das der ESP8266 am analogen Port noch einen Helligkeitssensor hat, habe ich den schnell in die Ausgabe mit eingebaut. Das eigentliche "Hauptprogramme "ist eine Endlosschleife mit "while True:", welche am Ende auf die nächste Sekunde wartet.

Mustercode

Mein Mustercode finden sie hier:

micropython_neopixeluhr20210419.txt
Ich speichere den Code in einer eigenen Datei "neopixelclock.py" und wenn er funktioniert, dann addiere ich ein "import neopixelclock" am ende der Datei "boot.py". Alternativ können Sie das Script auch als "main.py" auf dem Device abspeichern.

Weitere Dokumentationen