Files
grossanzeige/README.md
T
admin 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>
2026-07-16 17:27:32 +02:00

149 lines
7.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Großanzeige
Ansteuerung einer microSYST **migra SC/MC Seriell** LED-Großanzeige mit den
Koordinaten (Rektaszension / Deklination) einer 10Micron GM4000 HPS II.
Endziel ist ein XIAO ESP32-C3, der die Montierung per WLAN abfragt und die
Koordinaten über UART/RS232 auf die Anzeige schreibt. **Phase 1** (dieser Stand)
ist das Testprogramm auf dem Mac: Koordinaten von Hand übergeben, Ausgabe über
einen USB-RS232-Wandler.
## Benutzung
```bash
# Phase 1 -- Koordinaten von Hand:
python3 show_coords.py 12h34m56s +45d12m30s # Koordinaten anzeigen
python3 show_coords.py 12:34:56 -07:15:00 # Trennzeichen sind egal
python3 show_coords.py --clear # Anzeige löschen
python3 show_coords.py 12h34m56s +45d12m30s --dry-run # nur Telegramm als Hex
# Phase 2 -- Koordinaten von der Montierung (10Micron GM4000):
python3 run_display.py # Montierung aus config.py pollen
python3 run_display.py --host 10.0.0.42 # andere IP
python3 run_display.py --mock --move # ohne Teleskop: lokaler Mock, RA läuft
python3 mount_mock.py --move # Mock separat starten
python3 -m unittest test_migra test_lx200 # alle Tests
python3 probe.py ruler # Geometrie der Anzeige ausmessen
```
Einzige Abhängigkeit auf dem Mac ist `pyserial`.
## Aufbau
| Datei | Zweck |
|---|---|
| `migra.py` | Protokoll: Telegrammrahmen, Prüfsumme, ESC-Sequenzen. Ohne Abhängigkeiten, **läuft unverändert unter MicroPython**. |
| `transport.py` | UART: `pyserial` (Mac), `machine.UART` (ESP32-C3), `FakeTransport` (Trockenlauf). |
| `display.py` | Treiber: Telegramm senden, Antwort auswerten. |
| `coords.py` | Koordinaten einlesen und auf die Zeilenbreite formatieren. |
| `config.py` | Port, Adresse, Geometrie, Helligkeit — alles an einer Stelle. |
| `show_coords.py` | Das Testprogramm. |
| `probe.py` | Testmuster zum Ausmessen von Zeilenbreite und Zeilenposition. |
| `test_migra.py` | Tests, u. a. gegen die Beispieltelegramme aus dem Handbuch. |
## Protokoll (Kurzfassung)
Referenz: Benutzerhandbuch `X-M31-9AXX5X-006 (V4.20)`, Kapitel 3.53.9.
**Schnittstelle:** 19200 Baud, 8 Datenbits, **Even Parity**, 1 Stopbit.
9-pol. Sub-D: Pin 2 = RxD, Pin 3 = TxD, Pin 5 = GND.
**Telegramm:**
```
STX | DA | SA | FC | [LEN-H LEN-L] | Data-Unit | [CHK-H CHK-L] | ETX
02 81 80 81 03
```
- `DA`/`SA`: Adressen mit gesetztem Bit 7 → Anzeige = 1 (`0x81`), Host = 0 (`0x80`).
- `FC`: Bit 7 fest 1, Bit 1 = Prüfsumme, Bit 0 = Antwort anfordern.
`0x81` = ohne Prüfsumme, mit Antwort (so fuhr auch das alte MSP430-Programm).
- Ohne Prüfsumme dürfen `LEN-H/L` und `CHK-H/L` **nicht** mitgesendet werden.
- Prüfsumme = Low-Byte der Summe aus `DA, SA, FC, LEN-H, LEN-L` und allen Datenbytes,
als zwei Nibbles mit gesetztem High-Nibble (`0xF0 | nibble`).
**Antwort:** `02 80 81 80 <Fehlercode> 03`, Fehlercode `'0'` = kein Fehler.
Nach Erhalt der Antwort darf sofort das nächste Telegramm folgen — das ist die
Flusskontrolle. Ohne Antwort muss zwischen den Telegrammen gewartet werden
(Empfangstimeout + ca. 150 ms).
**ESC-Sequenzen** (alle Zahlen ASCII-codiert, Position 123 → `'1' '2' '3'`):
| Sequenz | Bedeutung |
|---|---|
| `ESC z NN` / `ESC Z NN` | Zeichensatz NN (`z` = Sperrschrift, gleiche Zeichenbreite) |
| `ESC C xxxyyy` | Cursor auf **Pixel**position x/y, 0/0 ist links oben |
| `ESC A <fg><bg><blink>` | Attribute; Farbe 0 = schwarz, 1 = grün, 2 = rot, 3 = gelb |
| `ESC F <Farbe>` | Anzeige füllen; `ESC F 0` = löschen |
| `ESC H <Farbe><ppp>` | Helligkeit 0100 % |
| `ESC T <+/-><nnn>` | gespeicherten Text ein-/ausblenden |
Folgt auf eine ESC-Sequenz ein Online-Text, muss **`0x1F` als Trennzeichen**
dazwischen. Data-Unit max. 230 Zeichen. `migra.DataUnit` setzt das Trennzeichen
selbst.
## Offene Punkte
- **Echte Montierungs-IP:** In `config.py` steht `MOUNT_HOST` noch als Platzhalter.
Sobald die GM4000 im Netz erreichbar ist, dort die IP eintragen (Port 3490 ist
Vorgabe). Bis dahin läuft alles gegen den Mock (`run_display.py --mock`).
- Portierung auf den XIAO ESP32-C3 (MicroPython): `migra.py`, `lx200.py`,
`mount_client.py` sind bewusst abhängigkeitsfrei; nur `transport` (UART) und das
WLAN-Setup kommen hinzu.
## Gradzeichen
Der Standard-Zeichensatz 0 der Anzeige hat **kein** `°`. Der von der Sternwarte
geladene **Zeichensatz 1** enthält an Position `/` (0x2F) ein hochgestelltes
Gradzeichen (deckt sich mit dem alten Programm, `asciitaf.h`: Code 0xAF → per
`& 0x7F` = 0x2F in Zeichensatz 1). Zur Ausgabe wird für dieses eine Zeichen kurz
auf Zeichensatz 1 umgeschaltet und wieder zurück (`config.DEGREE_*`, `display._emit_degree`).
**Fallstrick:** Ein Zeichensatzwechsel mitten im Telegramm beschädigt die Home-Zelle
(0,0) — das erste Zeichen der obersten Zeile wird zerstört. Deshalb zeichnet
`show_lines` die Zeilen **von unten nach oben** (oberste Zeile zuletzt), damit sie
diese Zelle überschreibt.
## Geometrie und Darstellung
- **9 Zeichen pro Zeile** in Sperrschrift (`CHARSET_SPACED = True`, am Gerät
ausgemessen). `probe.py ruler` misst es nach.
- Die Deklination wird deshalb als **9-Zeichen-Form ohne abschließendes `"`**
ausgegeben (`+38°47'01`) — Gradzeichen und Bogenminuten bleiben, die Bogensekunden
stehen als Ziffern da. `coords.format_dec` wählt automatisch die breiteste Form,
die in `CHARS_PER_LINE` passt.
- **Zyklische Updates flimmerfrei:** `show_lines` löscht nicht bei jeder Aktualisierung,
sondern überschreibt die Zeilen an Ort und Stelle (auf volle Breite aufgefüllt).
`clear=True` nur beim ersten Bild. Wichtig: Zeilen dürfen **nicht breiter** als
`CHARS_PER_LINE` aufgefüllt werden, sonst bricht das Füll-Leerzeichen um und
beschädigt die andere Zeile.
## Antwortleitung (RX)
Der Rückkanal ist verdrahtet und verifiziert (2026-07-16): Anzeige Pin 3 (TxD) →
MAX232-Empfängereingang (R_IN) → R_OUT → Adapter RxD. Die Anzeige quittiert jedes
Telegramm mit `02 80 81 80 30 03` (Fehlercode `0` = kein Fehler). `WANT_RESPONSE = True`
ist damit aktiv: Nach der Antwort darf sofort das nächste Telegramm folgen, der
Fehlercode wird ausgewertet. `resp_test.py` prüft den Rückweg (sendet mit Antwort-
Anforderung und zeigt die empfangenen Antworten).
Wichtig: `SerialTransport.write` leert vor jedem Senden den Empfangspuffer, damit
`read_response` nur die frische Antwort sieht (sonst können Störbytes zwischen den
Telegrammen das Parsen stören). `run_display` fängt Anzeige-Fehler ab und zeichnet
beim nächsten Durchlauf neu, statt abzustürzen.
Diagnose-Historie: Der Rückweg war anfangs falsch verdrahtet — Pin 3 lag an einem
MAX232-*Sender*ausgang statt einem Empfängereingang; zwei Ausgänge trieben
gegeneinander (verschliffener ~3-V-Pegel am Oszi). `loopback.py` grenzt so etwas ein.
## Erledigt
- **Phase 1 + 2 am Gerät bestätigt (2026-07-15/16):** Koordinaten erscheinen korrekt,
inkl. echtem Gradzeichen; im `run_display`-Betrieb aktualisieren beide Zeilen
laufend, sauber und ohne Flimmern, mit Antwort-Handshake der Anzeige. Protokoll,
19200 8E1, Zeichensatz und Zeilengeometrie stimmen.
- Schrift: Sperrschrift (`ESC z`, `CHARSET_SPACED = True`), 10 Zeichen/Zeile.
Die schmale `1` wirkt dadurch etwas luftig — Font-Eigenschaft, nur per eigenem
Font (microSYST-PC-Software) änderbar.