Analog-Uhr
Verfasst: Mi 25. Jan 2023, 12:35
Hier stelle ich ein einfaches Programm für eine Analog-Uhr-Anzeige vor. Es eignet sich sowohl für das Modul TTGO T-Display als auch für das Modul T-QT. Je nach Modul muss im Programmtext ein entsprechender Eintrag (board = 0 bzw. board = 1) vorgenommen werden.
Folgende Themenbereiche werden behandelt:
1. Klassen für graphische Objekte definieren und einsetzen
Das Programm stellt ein sehr einfaches Beispiel dafür dar, wie man Klassen für graphische Objekte definieren und einsetzen kann. Die Kommentierungen sollen helfen, es als Vorlage für eigene Programme einzusetzen.
2. Die RTC-Klasse
Mit Hilfe der RTC-Klasse erhält man einen Zugriff auf die Systemzeit des ESP32. Diese Information erhält er übrigens von dem Betriebssystem ihres Rechners, an den Sie ihn angeschlossen haben. Die RTC-Klasse importieren wir zunächst aus dem machine-Modul:
from machine import RTC
Nun bilden wir eine RTC-Instanz mit dem Namen rtc:
rtc = RTC()
Mit der Methode datetime dieses Objekts erhalten wir ein Zahlentupel, welches wie hier timetuple nennen:
timetuple=rtc.datetime()
Ein solche Tupel sieht z. B. so aus:
(2023, 1, 25, 2, 13, 19, 14, 926068)
Die einzelnen Elemente des Tupels haben folgende Bedeutung:
Element 0: Jahr (2023)
Element 1: Monat (1 für Januar)
Element 2: Tag (25)
Element 3: Wochentag (2 für Mittwoch; Zählung beginnt am Montag mit 0)
Element 4: Stunde (13)
Element 5: Minute (19)
Element 6: Sekunde (14)
Auf die Elemente eines Tupels kann man wie bei Listen zugreifen: Der Wert von timetuple[2] ist dann z. B. 25.
Und hier das Programm:
Bitte beachten Sie: Wenn Sie das Programm "stand alone", d. h. nicht von einer Programmierumgebung wie Thonny aus starten, dann beginnt die Uhr bei 00:00:00 Uhr, Samstag 1.1.2000, zu laufen. Es besteht allerdings die Möglichkeit, das Programm so zu erweitern, dass es beim Start über WLAN ein korrektes timetuple von einem entsprechenden Server bezieht (s. https://www.forum.g-heinrichs.de/viewto ... p=251#p251.
Folgende Themenbereiche werden behandelt:
- Klassen für graphische Objekte definieren und einsetzen
- RTC-Klasse
1. Klassen für graphische Objekte definieren und einsetzen
Das Programm stellt ein sehr einfaches Beispiel dafür dar, wie man Klassen für graphische Objekte definieren und einsetzen kann. Die Kommentierungen sollen helfen, es als Vorlage für eigene Programme einzusetzen.
2. Die RTC-Klasse
Mit Hilfe der RTC-Klasse erhält man einen Zugriff auf die Systemzeit des ESP32. Diese Information erhält er übrigens von dem Betriebssystem ihres Rechners, an den Sie ihn angeschlossen haben. Die RTC-Klasse importieren wir zunächst aus dem machine-Modul:
from machine import RTC
Nun bilden wir eine RTC-Instanz mit dem Namen rtc:
rtc = RTC()
Mit der Methode datetime dieses Objekts erhalten wir ein Zahlentupel, welches wie hier timetuple nennen:
timetuple=rtc.datetime()
Ein solche Tupel sieht z. B. so aus:
(2023, 1, 25, 2, 13, 19, 14, 926068)
Die einzelnen Elemente des Tupels haben folgende Bedeutung:
Element 0: Jahr (2023)
Element 1: Monat (1 für Januar)
Element 2: Tag (25)
Element 3: Wochentag (2 für Mittwoch; Zählung beginnt am Montag mit 0)
Element 4: Stunde (13)
Element 5: Minute (19)
Element 6: Sekunde (14)
Auf die Elemente eines Tupels kann man wie bei Listen zugreifen: Der Wert von timetuple[2] ist dann z. B. 25.
Und hier das Programm:
Code: Alles auswählen
# Uhr_1b.py (für TTGO und T-QT)
############################## Beutztes Board #######################################
#
# Tragen Sie hier ein, welches Board Sie benutzen (0 = T-QT, 1 = TTGO):
board = 0
#
#####################################################################################
# Die Systemzeit (inkl. Datum) erhält das ESP32-System aus dem Betriebssysstem des Rechners:
# Wenn Sie z. B. Thonny benutzen, gibt Thonny beim Start diese Informationen vom Betriebssytenm
# an den ESP32 weiter.
# Import für exit()
import sys
# Import für Uhrzeit
from machine import RTC
# RTC-Objekt instanziieren und Systemzeit (inkl. Datum) im Terminal anzeigen
rtc = RTC()
timetupel=rtc.datetime() # now() git es nicht!
h=timetupel[4]
m=timetupel[5]
s=timetupel[6]
print('Systemzeit: ',h ,':',m, ':', s)
print('-------------------------------')
# Importe für Analog-Anzeige der Uhrzeit
from machine import Pin, SPI, RTC
import st7789
import vga1_8x8 as font
from time import sleep
import math
# Eine Klasse für die Uhrzeiger definieren
class Uhrzeiger:
def __init__(self, r, w, display): # r(adius) = Zeigerlänge), (start)w(inkel) in Grad (bezogen auf Nordrichtung)
self.r = r
self.w = w
self.__x0 = 64 # Anfangspunkt des Zeigers ist (64, 64)
self.__y0 = 64
self.__display = display
def draw(self, color=st7789.WHITE): # color = WHITE, wenn keine Parameterangabe
b = math.radians(self.w) # Winkel in Bogenmaß
x1 = self.r * math.sin(b)
y1 = self.r * math.cos(b)
self.__display.line(self.__x0, self.__y0, self.__x0+int(x1), self.__y0-int(y1), color)
def delete(self): # Löschen über fill-Methode zeigt Ruckeln, weil das Ziffernblatt auch immer neu gezeichnet werden muss
self.draw(0)
def circle(x, y, r): # Kreis mit Mittelpunkt und Markierungen für 0, 3, 6 und 9 Uhr
c = st7789.GREEN
y0 = y - r
x0 = x
# Ziffernblatt mit Markierungen
for w in range(0, 360, 2):
b = math.radians(w) # Winkel in Bogenmaß
x1 = x + int(r * math.sin(b))
y1 = y - int(r * math.cos(b))
display.pixel(x1, y1, c) # Kreispunkt
x0 = x1
y0 = y1
display.line(x, y-r, x, y-r+3, c) # Markierungen
display.line(x, y+r-3, x, y+r, c)
display.line(x-r, y, x-r+3, y, c)
display.line(x+r-3, y, x+r, y, c)
display.fill_rect(63,63,4,4,c) # Mittelpunkt
# Display initialisieren
if board == 0: # T-QT
spi = SPI(1, baudrate=20000000, sck=Pin(3), mosi=Pin(2)) # für T-QT
display = st7789.ST7789(spi, 128, 128, reset=Pin(1, Pin.OUT), cs=Pin(5, Pin.OUT), dc=Pin(6, Pin.OUT), backlight=Pin(10, Pin.OUT), rotation=1, color_order=st7789.BGR) # für T-QT
display.init()
display.off() # umgekehrte Logik gegenüber TTGO!
display.fill(0) # Display löschen
elif board == 1: # TTGO:
spi = SPI(1, baudrate=20000000, polarity=1, sck=Pin(18), mosi=Pin(19))
display = st7789.ST7789(spi, 135, 240, reset=Pin(23, Pin.OUT), cs=Pin(5, Pin.OUT), dc=Pin(16, Pin.OUT), backlight=Pin(4, Pin.OUT), rotation=3) # Landscape
display.init()
display.on()
display.fill(0) # Display löschen
else:
print('Keine Passende Board-Kennzeichnung eingegeben!')
sys.exit(0)
# Instanziierung des Zeigers:
minutenzeiger = Uhrzeiger(25, 0, display)
stundenzeiger = Uhrzeiger(15, 0, display)
# Uhrzeit und Datum im Display anzeigen
display.text(font, 'Lilygo-Uhr', 24, 12, st7789.BLUE)
circle(64, 64, 30) # Ziffernblatt
# Uhrzeiten anzeigen:
wochentag_liste = ['Mo ', 'Di ', 'Mi ', 'Do ', 'Fr ', 'Sa ', 'So ']
while True:
timetuple=rtc.datetime() # now() gibt es nicht!
print(timetuple) # zum Testen
jahr = timetuple[0]
monat = timetuple[1]
tag = timetuple[2]
wochentag = timetuple[3]
datum = wochentag_liste[wochentag] + str(tag)+'.'+str(monat)+'.'+str(jahr)
display.text(font, datum, 13, 110, st7789.RED)
minuten = timetuple[5]
stunden = timetuple[4]
minutenzeiger.w = minuten * 6
stundenzeiger.w = stunden * 30 + minuten // 2 # Ganzzahldivision
minutenzeiger.draw()
stundenzeiger.draw()
sleep(10) # Aktualisierung jede 10 s; d. h. die Analoganzeige geht maximal um 10 s falsch
minutenzeiger.delete()
stundenzeiger.delete()