"""Hauptprogramm auf dem XIAO ESP32-C3 (MicroPython). Das Gegenstueck zu run_display.py: dort die Kommandozeile auf dem Mac, hier das WLAN-Setup auf dem Geraet. Die Poll-Schleife selbst ist dieselbe (displayloop). Am REPL starten: import run_esp32 run_esp32.selftest(host="192.168.178.26") # Bring-up pruefen run_esp32.main(host="192.168.178.26", fake_display=True) # gegen den Mock run_esp32.main() # echte Montierung, echte Anzeige Absichtlich *nicht* main.py genannt: MicroPython startet eine Datei dieses Namens nach jedem Reset von selbst. Solange wir am Aufbau arbeiten, ist der manuelle Start angenehmer -- der Autostart ist spaeter eine main.py mit den zwei Zeilen von oben. Verdrahtung (aus dem Schaltplan, siehe Hardware/KiCad/Grossanzeige): XIAO Pad 7 (D6/GPIO21) --> MAX3232 T2IN, T2OUT --> Anzeige RxD (Sub-D 2) XIAO Pad 8 (D7/GPIO20) <-- MAX3232 R2OUT, R2IN <-- Anzeige TxD (Sub-D 3) XIAO Pad 1 (D0/GPIO2) <-- LDR-Teiler (3V3 --[2k]-- A0 --[LDR]-- GND) MAX3232 VCC = 3V3 vom XIAO, GND gemeinsam """ import config import displayloop import wifi from brightness import BrightnessController, raw_to_ldr from display import open_display from mount_client import MountClient try: # MicroPython from machine import ADC, Pin except ImportError: ADC = Pin = None def make_ldr_reader(): """Funktion liefern, die den LDR als Wert in Zaehlrichtung "hoch = hell" gibt. Gibt None zurueck, wenn kein ADC verfuegbar ist -- dann laeuft die Anzeige einfach mit fester Helligkeit weiter. """ if ADC is None: return None adc = ADC(Pin(config.LDR_PIN)) # Voller Eingangsbereich bis ~3,3 V; ohne Daempfung endet der ADC bei ~1 V. try: adc.atten(ADC.ATTN_11DB) except AttributeError: pass def read(): # read_u16() gibt es auf allen Ports; auf 12 bit zurueckskalieren, weil # die Schwellen in brightness.py aus dem 12-bit-ADC des MSP430 stammen. raw = adc.read_u16() * config.LDR_MAX // 65535 return raw_to_ldr(raw) return read def selftest(host=None, port=None, log=print): """Bring-up in einem Rutsch pruefen, ohne die Dauerschleife zu starten. WLAN aufbauen, IP zeigen, einmal die Montierung (oder den Mock auf dem Mac) abfragen und ein Anzeige-Telegramm bauen -- letzteres nur als Hex, ohne serielle Hardware. Damit laesst sich Stufe fuer Stufe eingrenzen, wo es klemmt, bevor Anzeige und Pegelwandler ueberhaupt dranhaengen. import run_esp32 run_esp32.selftest(host="192.168.178.26") """ log("1) WLAN ...") cfg = wifi.connect(log=log) log(" IP %s, Gateway %s" % (cfg[0], cfg[2])) host = config.MOUNT_HOST if host is None else host port = config.MOUNT_PORT if port is None else port log("2) Montierung %s:%d ..." % (host, port)) client = MountClient(host, port, timeout=config.MOUNT_TIMEOUT) try: client.connect() ra_raw, dec_raw = client.get_coordinates() log(" RA %s DEC %s" % (ra_raw, dec_raw)) finally: client.close() log("3) Anzeige-Telegramm (nur Hex, keine Hardware) ...") d = open_display(fake=True) try: d.show_lines(*displayloop.format_coordinates(ra_raw, dec_raw), clear=True) finally: d.close() log("Selbsttest bestanden.") def main(host=None, port=None, with_ldr=False, fake_display=False, once=False, log=print): """WLAN aufbauen, Anzeige oeffnen und die Poll-Schleife fahren. host/port Montierung; Vorgabe aus config.py. Zum Testen gegen den Mock auf dem Mac dessen LAN-Adresse angeben. with_ldr Helligkeitsregelung ueber den ADC dazuschalten. Die Schwellen sind am realen LDR gemessen (2026-07-27, siehe brightness.py), aber am Schreibtisch, nicht in der Sternwarte -- deshalb bleibt die Vorgabe aus, bis sie vor Ort bestaetigt sind. fake_display Anzeige nur als Hex in die REPL schreiben, statt ueber den UART zu senden -- fuer den Test ohne Pegelwandler und Anzeige. once nur ein Durchlauf, dann zurueck. """ d = open_display(fake=fake_display) client = MountClient(config.MOUNT_HOST if host is None else host, config.MOUNT_PORT if port is None else port, timeout=config.MOUNT_TIMEOUT) dimmer = read_ldr = None if with_ldr: read_ldr = make_ldr_reader() if read_ldr is None: log("LDR: kein ADC verfuegbar, Helligkeitsregelung bleibt aus") else: dimmer = BrightnessController() try: # Einmal vorab verbinden, damit ein Fehler gleich sichtbar wird; danach # haelt ensure_link die Verbindung in der Schleife. try: wifi.connect(log=log) except wifi.WifiError as e: log("WLAN: %s" % e) displayloop.poll_loop(d, client, once=once, read_ldr=read_ldr, dimmer=dimmer, ensure_link=lambda: wifi.ensure(log=log), log=log) except KeyboardInterrupt: log("\nbeendet") finally: client.close() d.close()