139 lines
6.8 KiB
Markdown
139 lines
6.8 KiB
Markdown
# 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.5–3.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 0–100 % |
|
||
| `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
|
||
|
||
- **Antworttelegramm-Pfad (RX) noch offen, absichtlich zurückgestellt.**
|
||
`WANT_RESPONSE = False` ist Default, der Normalbetrieb läuft ohne Rückkanal.
|
||
Diagnose 2026-07-15: Adapter-Loopback ok, aber über den MAX232 und am echten
|
||
Gerät kommt keine Antwort zurück → der Empfangszweig (Anzeige Pin 3 TxD → MAX232
|
||
R_IN → R_OUT → Adapter RxD) leitet nicht. `loopback.py` hilft beim Eingrenzen.
|
||
Die Anzeige *antwortet* nachweislich (das alte MSP430-Programm nutzte die Antwort
|
||
als Handshake); es ist reine Verdrahtung. Wird der RX-Pfad fertig, `WANT_RESPONSE`
|
||
in `config.py` auf True stellen.
|
||
- **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.
|
||
|
||
## Erledigt
|
||
|
||
- **Phase 1 + 2 am Gerät bestätigt (2026-07-15):** Koordinaten erscheinen korrekt,
|
||
inkl. echtem Gradzeichen; im `run_display`-Betrieb aktualisieren beide Zeilen
|
||
laufend, sauber und ohne Flimmern. 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.
|