main
14 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
4461035777 |
Adresse der Montierung per MQTT umstellbar und gespeichert
Zwischen Mock und echter GM4000 umschalten, ohne zu deployen und ohne Neustart:
mosquitto_pub -t grossanzeige/set/mount_host -m 192.168.1.115
mosquitto_pub -t grossanzeige/set/mount_host -m 192.168.178.26
mosquitto_pub -t grossanzeige/set/mount_host -m ''
Die Adresse liegt in settings.json auf dem Geraet und uebersteht damit
Stromausfall und Watchdog-Neustart. deploy.sh kopiert die Datei bewusst nicht
mit, die Einstellung ueberlebt also auch ein Deployen.
**Leer heisst: config.MOUNT_HOST gilt.** mount_client.resolve_host loest auf in
der Reihenfolge: ausdruecklich mitgegebener Host (REPL, run_display --host) ->
mount_host aus settings.json -> config.MOUNT_HOST. Ohne diesen Rueckweg wuerde
eine einmal per MQTT gesetzte Adresse die Zeile in config.py fuer immer
verdecken, auch nach einem Deployen mit geaendertem Code.
Pruefung: settings._pruefe unterscheidet jetzt Zahl und Text am Typ der Vorgabe
in DEFAULTS -- eine neue Einstellung wird weiterhin an genau einer Stelle
eingetragen. Fuer mount_host sind nur Buchstaben, Ziffern, Punkt und
Bindestrich erlaubt, hoechstens 63 Zeichen: Der Wert geht ungeprueft in
socket.getaddrinfo, und von MQTT kommt alles Moegliche. Ungueltiges wird
verworfen, settings.json bleibt unberuehrt.
Sofort wirksam: Der Rueckruf traegt die neue Adresse in den MountClient ein und
trennt nur die bestehende Verbindung -- neu verbindet die Poll-Schleife im
naechsten Durchlauf, mit der gewohnten Fehlerbehandlung. Antwortet dort niemand,
steht "KEIN LINK", und eine weitere Nachricht holt das Geraet zurueck.
grossanzeige/status/mount_host meldet, welche Adresse gerade abgefragt wird --
die Rueckmeldung steht direkt hinter bridge.check() und nicht im Erfolgspfad,
kommt also auch dann, wenn die Montierung schweigt.
Der on_change-Rueckruf ist als run_esp32.make_on_change aus main() herausgeloest.
test_mqtt.py prueft ihn bisher als Abschrift ("Dieselbe Logik wie in
run_esp32.main"); jetzt laeuft der echte Code durch die Tests.
201 Tests gruen. Neu, unter anderem:
- TestUmschaltenImLaufendenBetrieb faehrt die ganze Kette an echten Sockets:
erst "KEIN LINK" an einer toten Adresse, nach dem set/mount_host die
Koordinaten vom Mock.
- TestAdresswahl (test_lx200) haelt die Reihenfolge von resolve_host fest.
- test_esp32: main() ohne host nimmt nach einem Neustart, was gespeichert ist.
Nicht angefasst: run_display.py auf dem Mac behaelt config.MOUNT_HOST als
Vorgabe fuer --host. Dort gibt es keine MQTT-Bruecke, und settings.json ist
Zustand des Geraets, nicht des Macs.
Am Geraet bestaetigt (2026-07-29), am Broker mitgeschnitten. Umschalten im
laufenden Betrieb, mit dem Mock auf dem Mac als Ausgangslage:
0.0s status/mount_host 192.168.178.26 Ausgangslage, link = 1
-> set/mount_host = 192.168.178.99
5.1s status/mount_host 192.168.178.99 Rueckmeldung
5.9s status/link 0 dort antwortet niemand
-> set/mount_host = ''
17.8s status/mount_host 192.168.178.26 Vorgabe aus config.py
18.6s status/link 1 Koordinaten laufen wieder
Und ueber den Neustart hinweg -- der eigentliche Zweck des Speicherns:
-> set/mount_host = 192.168.178.99
1.6s status/mount_host 192.168.178.99
settings.json auf dem Geraet:
{"hysterese": 150, "mount_host": "192.168.178.99", "schwelle": 1800, ...}
-> Hardware-Reset
8.6s status/online 0 Last Will
15.5s status/online 1 Autostart durch
15.5s status/mount_host 192.168.178.99 aus der Datei, nicht aus config.py
Die alte settings.json ohne mount_host wird beim Laden einfach um die Vorgabe
ergaenzt; die eingestellten Helligkeiten bleiben unberuehrt. Eine Migration war
nicht noetig.
set/mount_host wird ohne Retain-Flag geschickt: Das ist ein Befehl, kein
Zustand. Retained laege er im Broker und wuerde bei jedem Reconnect erneut
zugestellt.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
||
|
|
142a621066 |
Dauerbetrieb: Autostart (main.py) und Watchdog
MicroPython fuehrt main.py nach jedem Reset selbst aus -- nach Stromausfall oder Watchdog-Neustart laeuft die Anzeige damit ohne Notebook wieder an. Bisher gab es die Datei bewusst nicht, weil am Aufbau gearbeitet wurde. **Das Abbruchfenster ist kein Komfort, sondern die Notbremse.** Ohne es waere ein Geraet, dessen Programm beim Start haengt, nur noch durch Neuflashen erreichbar: Die Endlosschleife belegt die REPL sofort nach dem Reset. main.py wartet deshalb erst AUTOSTART_DELAY (3 s), in denen Ctrl-C zurueck an die REPL fuehrt -- dann laeuft auch kein Watchdog. Watchdog (WDT_TIMEOUT = 120 s): startet das Geraet neu, wenn die Poll-Schleife stehenbleibt. Gefuettert wird zu Beginn *jedes* Durchlaufs, auch nach einem Fehler -- "KEIN LINK" ist kein Stillstand, die Schleife laeuft ja weiter. Der Wert muss ueber allem liegen, was regulaer blockieren darf (WLAN 20 s, Montierung 3 s, dazu ein MQTT-Versuch); knapper waere er eine Neustart-Schleife. Ein gestarteter Watchdog laesst sich nicht mehr abschalten. Deshalb legt ihn nur main.py an -- im Handbetrieb ueber die REPL startete das Geraet sonst neu, waehrend man nachdenkt. Weiteres: - Nach einem Watchdog-Neustart meldet main.py das beim Start (machine.reset_cause()), sonst saehe er aus wie ein Stromausfall. - Eine Ausnahme faengt main.py ab und startet nach RESTART_DELAY (10 s) neu, statt in die REPL zu fallen und die Anzeige einzufrieren. Die Pause verhindert eine Neustart-Schleife im Sekundentakt. - Autostart faehrt mit Helligkeitsregelung (with_ldr=True, Nutzerentscheidung). Am Geraet bestaetigt: Autostart nach Reset laeuft durch (Watchdog aktiv, WLAN, MQTT), ein absichtlich herbeigefuehrter Stillstand loest den Watchdog aus und das Geraet kommt von allein wieder hoch -- mit der Meldung "Vorheriger Lauf wurde vom Watchdog beendet". Ctrl-C im Startfenster gibt die REPL frei. Beim Geraetetest aufgefallen: make_watchdog wurde ohne log aufgerufen, im Startprotokoll stand also nichts vom Watchdog. Behoben und durch einen Test festgehalten. 178 Tests gruen (neu: test_main.py). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
433c53aabd |
RA in Zehntelminuten mit Beschriftung: "RA 18h36.9m" / "DE +38°47'"
Die GM4000 liefert im Auslieferzustand keine Sekunden, sondern Zehntelminuten.
Bisher wurde daraus eine Sekundenanzeige gerechnet -- die sprang in
6-Sekunden-Schritten, weil die Rohdaten sie gar nicht hergeben. Die Zehntelform
ist ehrlicher und kuerzer, und der gewonnene Platz traegt die Beschriftung:
RA 18h36.9m
DE +38°47'
Bei Hochpraezision entfaellt die Beschriftung, dort braucht die Deklination mit
+38°47'01" alle Zellen.
Der Mock konnte das gar nicht nachstellen -- er sendete immer das
Hochpraezisionsformat. Neu: "mount_mock.py --low" bildet den Auslieferzustand ab
(RA als HH:MM.T, DEC ohne Bogensekunden). Vorgabe bleibt hoch, damit die
bestehenden Tests mit ihren festen Erwartungen unveraendert durchlaufen.
Zur Darstellung, alles am Geraet ausprobiert:
- **Schmale Zeichen** (config.CELL_NARROW): Dezimalpunkt und der Abstand
zwischen Beschriftung und Wert bekommen 3 statt 6 px -- in der Sperrschrift
standen sie sonst sehr luftig. Fuer die Leerzeichen am Zeilenende gilt das
nicht, die sollen den Rest der Zeile ueberschreiben.
- Damit entscheidet die **Pixelbreite** ueber das Abschneiden, nicht mehr die
Zeichenzahl: "RA 18h36.9m" sind 11 Zeichen und trotzdem nur 60 px.
- **Linksbuendig ab LINE_X = 0**, der Schalter zum Zentrieren ist entfallen.
Zentriert standen die Zeilen um wenige Pixel gegeneinander versetzt, weil die
RA-Zeile mit ihrem schmalen Punkt kuerzer ist als die DEC-Zeile.
Ein Zwischenschritt, der wieder verworfen wurde und als Warnung im Code steht:
Ein Doppelpunkt als Trenner ("RA:18h36.9m") sah in Zeichensatz 0 zu wuchtig aus;
der aus Zeichensatz 1 ist schlanker, steht aber mitten in der obersten Zeile --
und jeder Zeichensatzwechsel zerstoert die Home-Zelle. Das erste Zeichen danach
noch einmal zu schreiben machte es schlimmer: Das nachgezogene Zeichen bemalt
GLYPH_WIDTH Pixel und frisst die linke Spalte seines rechten Nachbarn. Deshalb
steht in der obersten Zeile jetzt bewusst kein Sonderzeichen.
161 Tests gruen, am Geraet bestaetigt.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
||
|
|
dae7694a07 |
Nur geaenderte Zellen schreiben -- gegen das Flackern im Sekundentakt
Seit der Einzelpositionierung blitzten bei jeder Aktualisierung willkuerliche Pixel auf, in beiden Zeilen. Ursache ist die Telegrammlaenge: Eine volle Zeile kostet mit einzeln gesetzten Zeichen rund 100 Bytes statt 20, bei 19200 Baud und 8E1 (11 Bit je Byte) dauerte ein kompletter Bildwechsel damit rund 300 ms. Die Anzeige stellt schon waehrend des Empfangs dar, also war der Aufbau zu sehen -- im Sekundentakt ein Drittel der Zeit. Von einer Sekunde zur naechsten aendert sich aber fast nichts: "18h36m56s" -> "18h36m57s" ist eine einzige Ziffer, die Deklination steht meist still. show_lines vergleicht deshalb gegen den zuletzt dargestellten Inhalt und schreibt nur die betroffenen Zellen; eine unveraenderte Zeile erzeugt gar kein Telegramm mehr. Am Geraet gemessen: 306 ms -> 66 ms je Bildwechsel. Dabei am Geraet aufgefallen und mitbehoben: Dem "s" hinter den Sekunden fehlten die linken Pixel, dem "m" hinter den Minuten ebenso -- beides Zeichen direkt rechts von einer Stelle, die sich gerade geaendert hatte. Die Anzeige malt je Zeichen 7 px breit (daher auch der 7-px-Auto-Vorschub), gesetzt wird aber auf 6-px-Raster: Ein neu geschriebenes Zeichen loescht die erste Pixelspalte seines rechten Nachbarn. Beim vollstaendigen Neuaufbau fiel das nie auf, weil der Nachbar gleich danach ohnehin neu gemalt wurde. _zelle_faellig zieht ihn jetzt mit. Weitere Details: - clear() verwirft den gemerkten Inhalt, sonst haelt der Vergleich Zellen faelschlich fuer vorhanden und die Anzeige bliebe teilweise leer. - Schlaegt ein Telegramm fehl, wird der gemerkte Inhalt der Zeile verworfen -- was angekommen ist, ist dann ungewiss. - Der Zeichensatz wird nur noch bei der ersten Ausgabe einer Zeile gesetzt. Das spart nicht nur Bytes: Jeder Wechsel beschaedigt die Home-Zelle. Findet doch einer statt (neues Gradzeichen), wird die oberste Zeile vollstaendig nachgezogen. Zu beiden Befunden gibt es Tests mit Gegenprobe (mit der alten Fassung schlagen sie fehl). 155 Tests gruen, am Geraet bestaetigt: ruhig, keine fehlenden Pixel. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
41f5eb1821 |
Per MQTT gesetzte Helligkeit sofort an die Anzeige senden
Am echten Broker aufgefallen: "hell_prozent = 100 uebernommen" stand im Log, die Anzeige blieb aber auf 50 %. Der Wert landete korrekt in settings.json und der Dimmer las ihn per reload() auch nach -- nur ging kein Helligkeitstelegramm raus. Grund: Ein Telegramm wird nur beim *Wechsel* der Stufe gesendet (so war es schon im alten MSP430-Programm gedacht, und fuer die LDR-Regelung ist das richtig). Aendert man die Helligkeit von aussen, waehrend die Stufe dieselbe bleibt, gibt es keinen Wechsel -- die Aenderung waere erst beim naechsten zufaelligen Stufenwechsel sichtbar geworden. run_esp32.main setzt nach dem reload() jetzt die Helligkeit der aktuellen Stufe neu. Ohne Dimmer (kein LDR) gilt weiterhin direkt hell_prozent. test_mqtt.TestHelligkeitWirdSofortSichtbar haelt das fest. Gegenprobe gemacht: mit der alten Fassung schlaegt der Test fehl (keine Helligkeit gesendet), mit der neuen geht genau ein Telegramm mit dem gesetzten Wert raus. Am Geraet bestaetigt, Broker "nuccy": Verbindung steht, Status (ra/dec/ldr/ helligkeit/link/online) kommt retained an, Einstellungen werden uebernommen, ungueltige Werte (500, Text) abgelehnt ohne settings.json anzufassen, und die Anzeige reagiert jetzt sichtbar auf 100 % -> 15 % -> 50 %. 145 Tests gruen. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
bf39b75ac1 |
MQTT: Einstellungen empfangen, Zustand veroeffentlichen
Topics (Praefix aus mqtt_config.py, Vorgabe "grossanzeige"):
<PREFIX>/set/hell_prozent 60 eingehend, schreibt settings.json
<PREFIX>/set/dunkel_prozent 5
<PREFIX>/set/schwelle 1800
<PREFIX>/set/hysterese 150
<PREFIX>/status/ra 18h36m56s ausgehend, retained
<PREFIX>/status/dec +38°47'01"
<PREFIX>/status/ldr 2453
<PREFIX>/status/helligkeit 50
<PREFIX>/status/link 1
<PREFIX>/status/online 1 mit Last Will auf 0
Eine empfangene Einstellung wird sofort wirksam: dieselbe Pruefung wie sonst
(settings.update), dann laedt der laufende BrightnessController sie per reload()
nach -- kein Neustart noetig.
Leitgedanke des Moduls: **MQTT darf die Anzeige nie aufhalten.** Die Anzeige ist
der Zweck des Geraets, MQTT ist Beiwerk. Deshalb faengt mqtt.py jeden Fehler
selbst ab und meldet ihn nur:
- Broker nicht erreichbar -> Versuch scheitert, Schleife laeuft weiter.
Wiederholung mit wachsendem Abstand (5..120 s), sonst kostet ein dauerhaft
toter Broker in jedem Schleifendurchlauf Zeit.
- Verbindungsabriss -> beim naechsten Senden/Empfangen bemerkt, Verbindung wird
verworfen und spaeter neu aufgebaut. Danach geht der gesamte Status erneut
raus, damit der Broker nicht auf veralteten Werten sitzenbleibt.
- Unsinniger Wert von aussen -> verworfen, settings.json bleibt unberuehrt.
- Geraet faellt aus -> Last Will meldet online=0. Ohne das bliebe online=1
stehen, obwohl niemand mehr da ist.
Der Empfang blockiert nicht (check_msg). Statuswerte gehen nur bei Aenderung
raus -- die Koordinaten aendern sich staendig, LDR und Helligkeit kaum.
mqtt_config.py ist optional und gitignored (Vorlage mqtt_config_example.py);
fehlt sie, laeuft alles wie bisher ohne MQTT. deploy.sh weist nur darauf hin.
test_mqtt.py haengt einen Fake-Broker ein und prueft auch die Faelle, die man
mit einem echten Server schwer herbeifuehrt: Abriss beim Senden, Muell im Topic,
Broker der nicht antwortet. 143 Tests gruen.
Am Geraet bestaetigt ist bisher der Fall OHNE Broker: mqtt.py importiert,
connect_from_config liefert None, ein unerreichbarer Broker wirft keine
Ausnahme. Der Test gegen einen echten Broker steht noch aus.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
||
|
|
0a893d0684 |
Helligkeit: zwei Werte und eine Schwelle, zur Laufzeit aenderbar
Die vier abgestuften Helligkeiten des alten MSP430-Programms (5/15/50/100 %)
entfallen. Fuer die Sternwarte genuegt der Wechsel Tag/Nacht: unterhalb der
Schwelle laeuft die Anzeige mit dunkel_prozent, oberhalb mit hell_prozent.
Die Werte stehen nicht mehr im Code, sondern in settings.json auf dem Geraet --
Vorbereitung fuer die spaetere MQTT-Anbindung:
settings.load() # mit Vorgaben aufgefuellt
settings.update({"hell_prozent": 60}) # aendern und speichern
Vorgaben: dunkel 5 %, hell 50 %, Schwelle 1800, Hysterese 150. Die Schwelle liegt
mit Abstand zwischen den gemessenen Lagen (abgedeckt 0, Raumlicht 2453).
Beibehalten, weil die Messung vom 27.07. sie verlangt: der gleitende Mittelwert
und eine Hysterese um die Schwelle. Der ADC rauscht mit +/-32 (nach Mittelung,
1 Sigma) -- ohne Hysterese wuerde die Anzeige am Umschaltpunkt springen.
settings.py prueft jeden Wert beim Laden UND beim Schreiben auf Typ und Bereich.
Das ist der eigentliche Zweck: Mit MQTT kommen die Werte von aussen, und ein
Helligkeitswert von 500 % oder eine Schwelle von -1 wuerde die Anzeige sonst
unbrauchbar machen. Eine fehlende oder beschaedigte Datei faellt auf die Vorgaben
zurueck, ein einzelner kaputter Wert verwirft nur diesen -- ein Geraet in der
Sternwarte soll sich nicht an seiner Konfigurationsdatei aufhaengen.
settings.json wird von deploy.sh bewusst NICHT mitkopiert und steht in
.gitignore: Es ist Laufzeitzustand, kein Quellcode. Sonst waeren die
eingestellten Werte nach jedem Deployen weg.
Am Geraet bestaetigt: schreiben, wiederlesen, Controller uebernimmt die Werte,
beide Helligkeiten auf der Anzeige sichtbar. 119 Tests gruen.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
||
|
|
e8a5b5d5e3 |
LDR-Schwellen am realen Aufbau gemessen statt vom MSP430 uebernommen
Gemessen am XIAO ESP32-C3 mit dem LDR an GPIO2, je 200 Werte, Median
(Angaben nach raw_to_ldr, also in Zaehlrichtung "gross = hell"):
abgedeckt roh 4095 (ADC-Anschlag) -> 0
Raumlicht roh 1642 -> 2453
angeleuchtet roh 543 -> 3552
Zwei Fehler in den alten Werten, die erst die Messung zeigt:
- Stufe 3 (100 %) war unerreichbar. Sie begann bei 3650, selbst eine Taschenlampe
direkt auf dem Sensor kam nur auf 3552. Die Anzeige haette nie voll aufgedreht.
- Die Hysterese von 30 am untersten Uebergang lag unter dem Rauschen. Der Rohwert
streut bei Raumlicht um +/-270, nach dem gleitenden Mittel bleiben rund +/-32
(1 Sigma) -- die unterste Stufe haette geflattert.
Neu: Mitten 1200/2400/3200, Hysterese einheitlich 150. Die Aufteilung haelt den
5-%-Bereich bis 1200 (Nutzerwunsch "nachts laenger dunkel", schont die
Dunkeladaption der Beobachter). Die gestaffelten Hysteresen des alten Programms
entfallen -- die gemessene Streuung ist an allen Grenzen dieselbe.
Bekannte Grenzlage, in test_brightness festgehalten: Raumlicht (2453) liegt nur
53 Zaehler ueber HELL_HIGH und damit innerhalb der Hysterese, faellt also auf
Stufe 1 statt 2. Ob das so gewollt ist, entscheidet sich in der Sternwarte.
Am Geraet bestaetigt: Regelung laeuft stabil ohne Flattern, Abdecken schaltet
herunter, Freigeben wieder hoch, Helligkeitstelegramm wird quittiert. Die
Schwellen sind aber am Schreibtisch gemessen -- with_ldr bleibt deshalb auf
False, bis sie vor Ort bestaetigt sind. 101 Tests gruen.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
||
|
|
4f7375add3 |
10 Zeichen pro Zeile: Zellenbreite am Geraet gemessen, Zeilen zentriert
Die RS232-Strecke ESP32 -> MAX3232 -> Anzeige ist am Geraet bestaetigt; damit war "probe.py pitch" moeglich und hat die offene Zeichenbreiten-Frage geklaert. Das Ergebnis korrigiert eine Annahme: Bisher stand CHARS_PER_LINE = 9, abgezaehlt am Zeilenumbruch. Gemessen wurde damit aber der Auto-Vorschub der Sperrschrift (7 px), nicht die Zeichenbreite. Die Zeichenmatrix ist 6 px breit -- zehn Ziffern, einzeln auf x = i*6 gesetzt, stehen sauber getrennt nebeneinander. - display._emit_line positioniert jedes Zeichen selbst, statt den Auto-Vorschub laufen zu lassen. CHARS_PER_LINE = 10, CELL_WIDTH = 6. - Die Deklination passt dadurch in voller Form: +38°47'01" statt +38°47'01. - show_lines sendet ein Telegramm je Zeile. Mit Einzelpositionierung kaemen beide zusammen auf 224 der erlaubten 230 Bytes -- zu wenig Reserve fuer den Dauerbetrieb. Die Reihenfolge bleibt unten vor oben (Home-Zelle). - Zeilen werden zentriert (CENTER_LINES, LINE_X). Der Zeichenblock bleibt dabei gleich breit und an derselben Stelle, damit keine Reste stehen bleiben. - probe.py kommt mit aufs Geraet: Die Anzeige haengt jetzt am ESP32, nur von dort laesst sich die Geometrie noch ausmessen. Die Tests pruefen nicht mehr auf zusammenhaengenden Text im Telegramm -- den gibt es nicht mehr -- sondern rechnen ueber die Cursor-Sequenzen zurueck, was wirklich auf welcher Zelle landet. 97 Tests gruen, Kette am Geraet im Sekundentakt bestaetigt. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|
|
42fc7f52d4 |
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> |
||
|
|
d8a9953b73 |
Niedrig-/Hochpraezision der Montierung + IP eingetragen
Die GM4000 laeuft in Niedrigpraezision (keine Sekunden): RA HH:MM.T, DEC sDD°MM. Anzeige daran angepasst: - config.HIGH_PRECISION (Vorgabe False) steuert die DEC-Darstellung: False -> ohne Sekunden (-00°55'), True -> mit Sekunden (+38°47'01) - RA immer mit Sekunden (11h36m54s); bei Niedrigpraezision aus den Zehntel-Minuten abgeleitet (6-Sekunden-Schritte), kein Dezimalpunkt (der wirkt in der Sperrschrift zu luftig) - coords.format_ra/format_dec nehmen high_precision= - MOUNT_HOST auf die echte IP (192.168.1.115) Hinweis: Das 'ß' in der Konsole ist nur der Rohwert (Grad-Byte 0xDF); auf der Anzeige erscheint korrekt der Gradring. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|
|
4cb8ea32d5 |
Helligkeitsregelung (LDR -> Stufe/Prozent) ergaenzt
- brightness.py: BrightnessController + CLI, portiert aus DoDimmen_V/main.h (gleitender Mittelwert, Hysterese). Schwellen 300/2500 aus altem Code, Prozente 5/15/50/100 - verallgemeinert auf 4 Stufen: 100% jetzt erreichbar (alter Code max 50%); neue obere Grenze HELL_MAX=3500 (anpassbar), Rest wie im Original - run_display: --ldr bindet die Regelung in die Hauptschleife ein (sendet nur bei Stufenwechsel) - test_brightness.py: Schwellen, Hysterese, Mittelung - README dokumentiert die Regelung; .gitignore: Hardware/ Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|
|
4acec81657 |
Antwortleitung (RX) verdrahtet und Flusskontrolle aktiviert
- WANT_RESPONSE=True: Anzeige-Antworttelegramm als Handshake, Fehlercode wird ausgewertet (Rueckweg verifiziert: 02 80 81 80 30 03) - transport: Empfangspuffer vor jedem Senden leeren, damit read_response nur die frische Antwort sieht (Stoerbytes zwischen Telegrammen) - run_display: Anzeige-/Antwortfehler abfangen statt abzustuerzen - resp_test.py: Pruefwerkzeug fuer den Rueckkanal - PORT auf /dev/cu.usbserial-120 - .gitignore ergaenzt, __pycache__ aus der Versionierung entfernt Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|
|
81e0e1a036 | First commit |