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:
2026-07-27 15:56:15 +02:00
parent 42fc7f52d4
commit 4f7375add3
8 changed files with 292 additions and 106 deletions
+34 -15
View File
@@ -52,10 +52,18 @@ class Display:
def show_lines(self, *lines, clear=False):
"""Zeilen ab Zeile 1 auf die Anzeige schreiben.
Baut ein einziges Telegramm: pro Zeile Cursor setzen und den Text
schreiben. Das Gradzeichen (config.DEGREE_MARKER) wird ueber einen kurzen
Pro Zeile ein eigenes Telegramm: Cursor setzen und Text schreiben. Das
Gradzeichen (config.DEGREE_MARKER) wird ueber einen kurzen
Zeichensatzwechsel eingefuegt.
Frueher war das ein einziges Telegramm fuer beide Zeilen. Seit jedes
Zeichen einzeln positioniert wird (10 statt 9 Zeichen, siehe _emit_line),
kostet eine Zeile rund 100 Bytes -- beide zusammen kaemen mit Gradzeichen
und Vollbild-Loeschen auf 224 der erlaubten 230 Bytes (migra.MAX_DATA_UNIT).
Das ist zu wenig Reserve fuer ein Geraet, das monatelang durchlaeuft;
getrennte Telegramme halten jedes bei rund der Haelfte. Die Flusskontrolle
ueber das Antworttelegramm macht die zweite Sendung unproblematisch.
Jede Zeile wird mit Leerzeichen auf volle Breite (CHARS_PER_LINE)
aufgefuellt und damit *an Ort und Stelle* ueberschrieben -- ohne die
Anzeige vorher komplett zu loeschen. Das vermeidet das sichtbare Blitzen
@@ -72,13 +80,15 @@ class Display:
if len(lines) > len(config.LINE_Y):
raise ValueError("Anzeige hat nur %d Zeilen" % len(config.LINE_Y))
du = migra.DataUnit()
if clear:
du.fill(config.BACKGROUND)
du.attributes(fg=config.COLOR, bg=config.BACKGROUND, blink=migra.STATIC)
first = True
for i in reversed(range(len(lines))):
du = migra.DataUnit()
if clear and first:
du.fill(config.BACKGROUND)
du.attributes(fg=config.COLOR, bg=config.BACKGROUND, blink=migra.STATIC)
self._emit_line(du, config.LINE_Y[i], lines[i])
self.send(du)
self.send(du)
first = False
def show_line(self, index, text, clear=False):
"""Nur eine einzelne Zeile aktualisieren (eigenes, kurzes Telegramm).
@@ -98,17 +108,26 @@ class Display:
self.send(du)
def _emit_line(self, du, y, text):
"""Eine Zeile bei Pixelzeile y ausgeben, auf volle Breite aufgefuellt."""
# Ohne str.ljust: das kennt MicroPython nicht (am Geraet aufgefallen).
"""Eine Zeile bei Pixelzeile y ausgeben, auf volle Breite aufgefuellt.
Jedes Zeichen wird einzeln auf x = i*CELL_WIDTH gesetzt, statt den
Auto-Vorschub der Anzeige laufen zu lassen. Der Vorschub der Sperrschrift
ist 7 px und liesse nur 9 Zeichen zu; die Zeichenmatrix ist aber nur 6 px
breit, sodass 10 Zeichen sauber nebeneinander passen (am Geraet gemessen
2026-07-27, siehe config.CHARS_PER_LINE).
"""
# Ohne str.ljust/center: die kennt MicroPython nicht (am Geraet aufgefallen).
text = text[:config.CHARS_PER_LINE]
text += " " * (config.CHARS_PER_LINE - len(text))
rest = config.CHARS_PER_LINE - len(text)
links = rest // 2 if config.CENTER_LINES else 0
text = " " * links + text + " " * (rest - links)
du.charset(config.CHARSET, spaced=config.CHARSET_SPACED)
du.cursor(0, y)
for i, part in enumerate(text.split(config.DEGREE_MARKER)):
if i > 0:
for i in range(len(text)):
du.cursor(config.LINE_X + i * config.CELL_WIDTH, y)
if text[i] == config.DEGREE_MARKER:
self._emit_degree(du)
if part:
du.text(part)
else:
du.text(text[i])
def _emit_degree(self, du):
"""Das Gradzeichen einfuegen -- ueber Zeichensatzwechsel oder als Fallback."""