Portierung auf den XIAO ESP32-C3 (MicroPython)
Die Kette laeuft auf dem Geraet gegen den Mock auf dem Mac. Getestet mit MicroPython 1.28.0 (ESP32_GENERIC_C3): alle Module importieren, Telegrammbau und Koordinaten-Formatierung sind byte-identisch zum Mac (inkl. Gradzeichen), Poll-Schleife 22 Abfragen in 20 s ohne Aussetzer, Ausfall und Reconnect verhalten sich wie vorgesehen. Offen bleibt allein die RS232-Strecke zur Anzeige -- der Steckbrettaufbau mit MAX3232 fehlt noch. Gemeinsamer Kern statt zweier Programme: - displayloop.py: die Poll-Schleife, herausgeloest aus run_display. Mac und ESP32 fahren jetzt denselben Ablauf; drumherum liegt nur die Kommandozeile (run_display.py) bzw. das WLAN-Setup (run_esp32.py). - ticks.py: Timeouts fuer beide Plattformen. time.ticks_ms() laeuft nach ~12 Tagen ueber; das bisherige "jetzt + Timeout" haette eine Warteschleife danach tagelang haengen lassen. Jetzt ueber ticks_diff. - wifi.py, run_esp32.py, wifi_config.py (gitignored, Vorlage dabei), deploy.sh. Pinbelegung aus dem KiCad-Schaltplan uebernommen, nicht geraten: UART1 mit TX=GPIO21 (Pad 7/D6) und RX=GPIO20 (Pad 8/D7) ueber den MAX3232, LDR an GPIO2 (Pad 1/A0). UART0 bleibt die REPL. LDR-Kennlinie ist auf der Platine umgekehrt: der Teiler lautet 3V3-[2k]-A0-[LDR]-GND, die Spannung faellt also mit steigender Helligkeit -- andersherum als beim MSP430, auf den die Schwellen zugeschnitten sind. Wird im Code gespiegelt (config.LDR_INVERTED, brightness.raw_to_ldr). Die Schwellen selbst muessen am realen Aufbau noch nachgemessen werden. Am Geraet gefundene Fehler, die den Attrappen-Tests entgehen mussten, weil CPython sie nicht hat: - MicroPython kennt kein str.ljust (auch kein rjust/center/zfill). display._emit_line fuellt von Hand auf. - NOLINK_LINES hatte 10 Zeichen bei 9 Zeichen Zeilenbreite und erschien als "MONTIERUN". Jetzt "KEIN LINK"/"TELESKOP". Dagegen: TestMicropythonVertraeglichkeit prueft die deployten Dateien statisch auf solche Methoden und auf modulweites argparse/threading und haelt die Dateiliste mit deploy.sh synchron; test_display.py prueft die Breite fester Anzeigetexte. Weitere Portabilitaet: mount_client nutzt getaddrinfo und eine Sendeschleife statt sendall (MicroPython laesst dessen Verhalten mit Timeout offen); argparse in brightness wandert in die Funktion; migra._digits und die Hex-Ausgabe verlassen sich nicht mehr auf %0*d bzw. bytes.hex(). Beides kann 1.28 zwar doch -- am Geraet nachgeprueft, die Kommentare sagen es jetzt richtig. Widerspruch in der Dokumentation bereinigt: die Zeichenbreite stand an vier Stellen als 9 oder 10. Gemessen sind 9; die Erklaerung duerfte sein, dass die Sperrschrift 7 px pro Zelle braucht (9*7 = 63 von 64 px) und nicht 6, wie es eine 5x7-Matrix mit 1 px Luecke waere. Nachgeprueft ist das nicht -- dafuer gibt es jetzt "probe.py pitch", das den Auto-Vorschub gegen feste Pixelabstaende stellt, statt am Umbruch abzuzaehlen. mount_mock.py --lan bindet auf 0.0.0.0 und nennt die einzutragende LAN-IP, damit der ESP32 den Mock erreicht. 92 Tests gruen. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,16 +1,38 @@
|
||||
"""Zentrale Einstellungen fuer die Ansteuerung der Grossanzeige."""
|
||||
"""Zentrale Einstellungen fuer die Ansteuerung der Grossanzeige.
|
||||
|
||||
Laeuft unveraendert unter CPython (Mac) und MicroPython (XIAO ESP32-C3); was
|
||||
sich zwischen beiden unterscheidet, haengt an MICROPYTHON.
|
||||
"""
|
||||
|
||||
import sys
|
||||
|
||||
import migra
|
||||
|
||||
# True auf dem ESP32-C3, False auf dem Mac. Steuert, welchen Transport
|
||||
# display.open_display waehlt und ob der LDR ueber den ADC gelesen werden kann.
|
||||
MICROPYTHON = sys.implementation.name == "micropython"
|
||||
|
||||
# -- Serielle Schnittstelle -----------------------------------------------
|
||||
# Auslieferzustand der Anzeige laut Handbuch (Kap. 4.1) und identisch zur
|
||||
# UART-Init des alten MSP430-Programms: 19200 8E1.
|
||||
PORT = "/dev/cu.usbserial-120" # Mac; auf dem ESP32-C3 spaeter die UART-Nummer
|
||||
BAUDRATE = 19200
|
||||
PARITY = "E"
|
||||
BYTESIZE = 8
|
||||
STOPBITS = 1
|
||||
|
||||
# CPython: Geraetedatei des USB-RS232-Wandlers.
|
||||
PORT = "/dev/cu.usbserial-120"
|
||||
|
||||
# ESP32-C3: UART1 mit frei zugeordneten Pins. Die Nummern stammen aus dem
|
||||
# Schaltplan (Hardware/KiCad/Grossanzeige) -- am XIAO ist Pad 7 = D6 = GPIO21
|
||||
# und Pad 8 = D7 = GPIO20. Von dort geht es an den MAX3232:
|
||||
# GPIO21 (TX) -> T2IN, T2OUT -> J5 Pin 3 -> Anzeige RxD (Sub-D Pin 2)
|
||||
# GPIO20 (RX) <- R2OUT, R2IN <- J5 Pin 2 <- Anzeige TxD (Sub-D Pin 3)
|
||||
# UART0 bleibt frei, das ist die REPL-Konsole ueber USB.
|
||||
UART_ID = 1
|
||||
UART_TX = 21
|
||||
UART_RX = 20
|
||||
|
||||
# -- Telegramm ------------------------------------------------------------
|
||||
DISPLAY_ADDR = 1 # Zieladresse der Anzeige (DA = 0x81)
|
||||
HOST_ADDR = 0 # unsere Quelladresse (SA = 0x80)
|
||||
@@ -26,14 +48,21 @@ QUIET_TIME = 0.4 # Pause zwischen Telegrammen, wenn ohne Antwort gefahren
|
||||
# Zeichensatz 0, Zeile 1 ab Pixelzeile 0, Zeile 2 ab Pixelzeile 9 (aus dem alten
|
||||
# C-Programm). Am echten Geraet ausgemessen (2026-07-15):
|
||||
# CHARSET_SPACED=True -> ESC z (Sperrschrift, alle Zeichen gleich breit) -- vom
|
||||
# Nutzer bevorzugt, weil sich sonst schmale Ziffern beruehren. In dieser Schrift
|
||||
# passen mind. 10 Zeichen pro Zeile (RA/DEC brauchen max. 10).
|
||||
# Nutzer bevorzugt, weil sich sonst schmale Ziffern beruehren.
|
||||
# CHARSET_SPACED=False -> ESC Z (proportional, schmaler, ~11 Zeichen, aber die "1"
|
||||
# klebt an Nachbarn).
|
||||
CHARSET = 0
|
||||
CHARSET_SPACED = True
|
||||
LINE_Y = (0, 9)
|
||||
CHARS_PER_LINE = 9 # in Sperrschrift am Geraet ausgemessen (2026-07-15)
|
||||
|
||||
# 9 Zeichen: am Geraet ausgemessen (2026-07-15). Die Anzeige ist 64 px breit;
|
||||
# eine reine 5x7-Matrix mit 1 px Luecke waere 6 px pro Zelle und ergaebe 10
|
||||
# Zeichen. Dass es nur 9 sind, passt zu 7 px pro Zelle -- die Sperrschrift
|
||||
# sperrt eben, sie hat 2 px Luecke (9*7 = 63 von 64 px). Das ist die Erklaerung,
|
||||
# nicht die Messung: "probe.py pitch 6" bzw. "pitch 7" entscheidet es direkt,
|
||||
# indem es den Auto-Vorschub gegen feste Pixelabstaende stellt.
|
||||
# Faende sich doch 6 px, passt die DEC-Form mit abschliessendem " (10 Zeichen).
|
||||
CHARS_PER_LINE = 9
|
||||
|
||||
COLOR = migra.RED # einfarbig rote Anzeige
|
||||
BACKGROUND = migra.BLACK
|
||||
@@ -52,7 +81,7 @@ DEGREE_FALLBACK = "d" # Ersatz, falls DEGREE_CHARSET = None
|
||||
# -- Montierung (Phase 2) -------------------------------------------------
|
||||
# 10Micron GM4000 HPS II: LX200-Protokoll ueber TCP. Die IP der Montierung
|
||||
# eintragen, sobald sie erreichbar ist; Port 3490 ist die Vorgabe von 10Micron.
|
||||
MOUNT_HOST = "192.168.1.115" # PLATZHALTER -- echte IP der Montierung eintragen
|
||||
MOUNT_HOST = "192.168.1.115" # echte IP der Montierung (eingetragen 2026-07-18)
|
||||
MOUNT_PORT = 3490
|
||||
MOUNT_TIMEOUT = 3.0 # Sekunden fuer Verbindung/Antwort
|
||||
POLL_INTERVAL = 1.0 # Sekunden zwischen zwei Koordinatenabfragen
|
||||
@@ -65,4 +94,27 @@ POLL_INTERVAL = 1.0 # Sekunden zwischen zwei Koordinatenabfragen
|
||||
HIGH_PRECISION = False
|
||||
|
||||
# Anzeige, wenn die Montierung (noch) nicht erreichbar ist.
|
||||
NOLINK_LINES = ("KEIN LINK", "MONTIERUNG")
|
||||
# Achtung: hoechstens CHARS_PER_LINE Zeichen, sonst wird abgeschnitten --
|
||||
# "MONTIERUNG" stand hier zuerst und erschien am Geraet als "MONTIERUN".
|
||||
NOLINK_LINES = ("KEIN LINK", "TELESKOP")
|
||||
|
||||
# -- WLAN (nur ESP32-C3) --------------------------------------------------
|
||||
# Zugangsdaten stehen in wifi_config.py (nicht im Git, siehe
|
||||
# wifi_config_example.py). Hier nur das Zeitverhalten.
|
||||
WIFI_TIMEOUT = 20.0 # Sekunden aufs Verbinden warten
|
||||
WIFI_RETRY = 5.0 # Pause vor einem neuen Verbindungsversuch
|
||||
|
||||
# Anzeige, solange noch kein WLAN steht.
|
||||
NOWIFI_LINES = ("KEIN WLAN", " ... ")
|
||||
|
||||
# -- Helligkeitssensor (LDR, nur ESP32-C3) --------------------------------
|
||||
# LDR an Pad 1 (D0/A0) = GPIO2, auf dem C3 ein Kanal von ADC1.
|
||||
LDR_PIN = 2
|
||||
|
||||
# Der Spannungsteiler auf der Platine ist 3V3 --[R2 2k]-- A0 --[LDR]-- GND.
|
||||
# Der LDR wird bei mehr Licht niederohmiger, die Spannung an A0 sinkt also mit
|
||||
# steigender Helligkeit -- genau andersherum als beim alten MSP430-Aufbau, auf
|
||||
# den die Schwellen in brightness.py zugeschnitten sind. Deshalb wird der
|
||||
# Rohwert gespiegelt (siehe brightness.raw_to_ldr).
|
||||
LDR_INVERTED = True
|
||||
LDR_MAX = 4095 # 12-bit-ADC, voller Ausschlag
|
||||
|
||||
Reference in New Issue
Block a user