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>
This commit is contained in:
@@ -191,6 +191,8 @@ festgehalten sind (`test_esp32.py`, `test_display.py`):
|
||||
- **Feste Anzeigetexte müssen in `CHARS_PER_LINE` passen.** `NOLINK_LINES` hieß
|
||||
zuerst „MONTIERUNG" (10 Zeichen) und erschien als „MONTIERUN"; `_emit_line`
|
||||
schneidet stillschweigend ab. `test_display.py` prüft die Breite jetzt.
|
||||
(Seit `CHARS_PER_LINE = 10` würde „MONTIERUNG" wieder passen — die Texte sind
|
||||
aber bei „KEIN LINK"/„TELESKOP" geblieben.)
|
||||
|
||||
Was MicroPython 1.28 entgegen der Erwartung **doch** kann (am Gerät nachgeprüft):
|
||||
`%0*d` mit dynamischer Feldbreite, `%-11s`, `bytes.hex()`, `str.strip`/`lstrip`,
|
||||
@@ -245,9 +247,6 @@ Mac:
|
||||
|
||||
## Offene Punkte
|
||||
|
||||
- **RS232-Strecke zur Anzeige.** Als einziges Stück der Kette noch nicht am
|
||||
ESP32 erprobt: Der Aufbau mit MAX3232 und Anzeige fehlt. Alles davor ist
|
||||
bestätigt, die Telegramme stimmen byteweise — es geht nur noch um die Pegel.
|
||||
- **LDR-Schwellen nachmessen.** Die Grenzen in `brightness.py` stammen vom alten
|
||||
MSP430-Aufbau. Sobald der LDR am ESP32 hängt, die Rohwerte bei Tag und Nacht
|
||||
ablesen und `HELL_LOW`/`HELL_HIGH`/`HELL_MAX` anpassen. Bis dahin läuft die
|
||||
@@ -265,40 +264,55 @@ 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.
|
||||
**Fallstrick:** Ein Zeichensatzwechsel beschädigt die Home-Zelle (0,0) — das erste
|
||||
Zeichen der obersten Zeile wird zerstört. Deshalb schreibt `show_lines` die Zeilen
|
||||
**von unten nach oben** (oberste Zeile zuletzt), damit sie diese Zelle überschreibt.
|
||||
Das gilt weiterhin, seit jede Zeile ihr eigenes Telegramm bekommt: dann entscheidet
|
||||
die Reihenfolge der Telegramme statt der Reihenfolge innerhalb eines Telegramms.
|
||||
|
||||
## Geometrie und Darstellung
|
||||
|
||||
- **9 Zeichen pro Zeile** in Sperrschrift (`CHARSET_SPACED = True`, am Gerät
|
||||
ausgemessen 2026-07-15).
|
||||
- **10 Zeichen pro Zeile zu 6 px** (`CHARS_PER_LINE = 10`, `CELL_WIDTH = 6`), am
|
||||
Gerät entschieden mit `probe.py pitch 6` (2026-07-27).
|
||||
|
||||
Das widerspricht der naheliegenden Rechnung: Die Anzeige ist 64 px breit, und
|
||||
eine 5×7-Matrix mit 1 px Lücke wäre 6 px pro Zelle — das gäbe 10 Zeichen
|
||||
(60 px). Die Erklärung ist vermutlich, dass die Sperrschrift eben sperrt:
|
||||
bei 2 px Lücke sind es 7 px pro Zelle und damit 9 Zeichen (63 von 64 px).
|
||||
Dazu passt auch die Beobachtung, dass die *proportionale* Schrift `ESC Z`
|
||||
rund 11 Zeichen schafft (≈ 5,8 px/Zelle).
|
||||
Vorher stand hier 9 — das war am Zeilenumbruch abgezählt und maß etwas
|
||||
anderes, als es zu messen schien. `probe.py pitch` stellt den Auto-Vorschub
|
||||
der Anzeige gegen feste Pixelpositionen `x = i·cell` und trennt damit beides:
|
||||
|
||||
**Nachgeprüft ist das nicht.** `probe.py pitch` entscheidet es direkt, statt
|
||||
am Umbruch abzuzählen: Es schreibt zehn Ziffern einmal mit dem Auto-Vorschub
|
||||
der Anzeige und einmal auf feste Pixelpositionen `x = i·cell`. Ein Unterschied
|
||||
von 1 px summiert sich über zehn Zeichen auf 9 px und ist unübersehbar.
|
||||
- Der **Auto-Vorschub** der Sperrschrift `ESC z` ist **7 px**. Eine Zeile in
|
||||
einem Stück geschrieben bricht deshalb nach 9 Zeichen um (9·7 = 63 von 64 px).
|
||||
- Die **Zeichenmatrix** ist aber nur **6 px** breit. Zehn Ziffern, einzeln auf
|
||||
`x = i·6` gesetzt, stehen sauber getrennt nebeneinander (60 von 64 px).
|
||||
|
||||
Deshalb positioniert `display._emit_line` jedes Zeichen selbst, statt den
|
||||
Auto-Vorschub laufen zu lassen. Der Preis sind längere Telegramme (rund 10 Byte
|
||||
je Zeichen statt 1), der Gewinn ein volles Zeichen mehr pro Zeile.
|
||||
|
||||
```bash
|
||||
python3 probe.py pitch 6 # stehen beide Zeilen untereinander -> 10 Zeichen
|
||||
python3 probe.py pitch 7 # ... -> 9 Zeichen
|
||||
python3 probe.py pitch 6 # stehen beide Zeilen untereinander -> 6 px/Zelle
|
||||
python3 probe.py pitch 7 # ... -> 7 px/Zelle
|
||||
```
|
||||
|
||||
Sollten es doch 6 px sein, passt die Deklination mit abschließendem `"` in
|
||||
voller Form (`+38°47'01"`, 10 Zeichen) — `coords.format_dec` wählt sie dann
|
||||
von selbst, es genügt `CHARS_PER_LINE = 10`.
|
||||
- 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.
|
||||
- **Ein Telegramm je Zeile.** Früher gingen beide Zeilen in einem Telegramm raus.
|
||||
Mit Einzelpositionierung kämen sie mit Gradzeichen und Vollbild-Löschen auf
|
||||
224 der erlaubten 230 Bytes (`migra.MAX_DATA_UNIT`) — zu wenig Reserve für ein
|
||||
Gerät, das monatelang durchläuft. Getrennte Telegramme halten jedes bei rund
|
||||
der Hälfte; die Flusskontrolle über das Antworttelegramm macht die zweite
|
||||
Sendung unproblematisch. Die Reihenfolge bleibt **unten vor oben** (Home-Zelle).
|
||||
|
||||
- Die Deklination passt damit in **voller Form mit abschließendem `"`**
|
||||
(`+38°47'01"`, 10 Zeichen). `coords.format_dec` wählt automatisch die breiteste
|
||||
Form, die in `CHARS_PER_LINE` passt — bei Niedrigpräzision entsprechend
|
||||
`+38°47'` ohne Sekunden.
|
||||
|
||||
- **Zeilen werden zentriert** (`CENTER_LINES = True`). Das wirkt auf zwei Ebenen:
|
||||
`LINE_X` rückt den Zeichenblock in die Mitte (10·6 = 60 px lassen je 2 px Rand),
|
||||
und kürzere Texte werden beidseitig mit Leerzeichen aufgefüllt. Der Block bleibt
|
||||
dabei immer gleich breit und an derselben Stelle — so überschreibt er bei jedem
|
||||
Durchlauf denselben Bereich und lässt keine Reste stehen. Ein pixelgenau
|
||||
mitwandernder Offset könnte das nicht; dafür ist die Zentrierung nur auf eine
|
||||
halbe Zelle (3 px) genau, wenn die Restbreite ungerade ist.
|
||||
|
||||
- **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
|
||||
@@ -380,12 +394,18 @@ gegeneinander (verschliffener ~3-V-Pegel am Oszi). `loopback.py` grenzt so etwas
|
||||
|
||||
## Erledigt
|
||||
|
||||
- **RS232-Strecke ESP32 → MAX3232 → Anzeige bestätigt (2026-07-27).** Das war das
|
||||
letzte ungetestete Kettenglied. Die Anzeige quittiert jedes Telegramm mit
|
||||
Fehlercode 0, die volle Kette (Mock → WLAN → ESP32 → UART1 → MAX3232 → Anzeige)
|
||||
läuft im Sekundentakt ohne Aussetzer. Damit ist die Portierung funktional
|
||||
komplett; offen sind nur noch Betriebsthemen (LDR, Netzwerk, Autostart).
|
||||
- **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`), 9 Zeichen/Zeile.
|
||||
(Hier stand ursprünglich „10 Zeichen/Zeile" — das war die Annahme vor der
|
||||
Messung vom 15.07., siehe *Geometrie und Darstellung*.)
|
||||
Die schmale `1` wirkt dadurch etwas luftig — Font-Eigenschaft, nur per eigenem
|
||||
- Schrift: Sperrschrift (`ESC z`, `CHARSET_SPACED = True`), **10 Zeichen/Zeile**
|
||||
bei fester Positionierung auf 6 px (gemessen 27.07., siehe *Geometrie und
|
||||
Darstellung*). Zwischenzeitlich stand hier 9 — das war am Umbruch abgezählt und
|
||||
traf den Auto-Vorschub (7 px), nicht die Zeichenbreite.
|
||||
Die schmale `1` wirkt etwas luftig — Font-Eigenschaft, nur per eigenem
|
||||
Font (microSYST-PC-Software) änderbar.
|
||||
|
||||
Reference in New Issue
Block a user