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>
This commit is contained in:
@@ -25,9 +25,9 @@ python3 run_display.py --mock --move --ldr 2000 # zusätzlich mit Helligkeitsre
|
||||
python3 mount_mock.py --move # Mock separat starten
|
||||
|
||||
# Helligkeit aus einem LDR-Wert setzen:
|
||||
python3 brightness.py --ldr 1500 # LDR-Rohwert -> Stufe/Prozent -> senden
|
||||
python3 brightness.py --ldr 1500 # LDR-Rohwert -> Helligkeit -> senden
|
||||
|
||||
python3 -m unittest test_migra test_lx200 test_brightness test_display test_esp32
|
||||
python3 -m unittest discover -p 'test_*.py' # alle Tests
|
||||
python3 probe.py ruler # Geometrie der Anzeige ausmessen
|
||||
```
|
||||
|
||||
@@ -56,9 +56,10 @@ beiden Startprogrammen.
|
||||
| `ticks.py` | Timeouts, die unter CPython und MicroPython gleich funktionieren. | ✓ |
|
||||
| `display.py` | Treiber: Telegramm senden, Antwort auswerten. | ✓ |
|
||||
| `coords.py` | Koordinaten einlesen und auf die Zeilenbreite formatieren. | ✓ |
|
||||
| `config.py` | Port/Pins, Adresse, Geometrie, Helligkeit, WLAN — alles an einer Stelle. | ✓ |
|
||||
| `config.py` | Port/Pins, Adresse, Geometrie, WLAN — fest, ändert sich nur beim Deployen. | ✓ |
|
||||
| `settings.py` | Zur Laufzeit änderbare Werte (Helligkeiten, Schwelle) in `settings.json`. | ✓ |
|
||||
| `displayloop.py` | Die Poll-Schleife: abfragen, formatieren, anzeigen, Fehler abfangen. | ✓ |
|
||||
| `brightness.py` | Helligkeitsregelung: LDR-Wert → Stufe/Prozent. | ✓ |
|
||||
| `brightness.py` | Helligkeit: LDR-Wert → dunkel/hell, Schwelle aus `settings.json`. | ✓ |
|
||||
| `mount_client.py` | TCP-Client zur GM4000 (LX200). | ✓ |
|
||||
| `lx200.py` | LX200-Kommandorahmen. | ✓ |
|
||||
| `wifi.py` | WLAN-Anbindung des ESP32 (verbinden, Verbindung halten). | ✓ |
|
||||
@@ -69,7 +70,7 @@ beiden Startprogrammen.
|
||||
| `mount_mock.py` | Simulator der Montierung (LX200) fürs Testen ohne Teleskop. | |
|
||||
| `probe.py` | Testmuster zum Ausmessen von Zeilenbreite und Zeilenposition. | |
|
||||
| `deploy.sh` | Kopiert die ESP32-Dateien per `mpremote` auf das Gerät. | |
|
||||
| `test_migra.py` / `test_lx200.py` / `test_brightness.py` / `test_display.py` / `test_esp32.py` | Tests. | |
|
||||
| `test_*.py` | Tests (migra, lx200, brightness, settings, display, esp32). | |
|
||||
|
||||
## Protokoll (Kurzfassung)
|
||||
|
||||
@@ -247,11 +248,14 @@ Mac:
|
||||
|
||||
## Offene Punkte
|
||||
|
||||
- **LDR-Schwellen in der Sternwarte gegenprüfen.** Die Grenzen sind am realen
|
||||
Aufbau gemessen (2026-07-27, siehe *Helligkeitsregelung*), aber am Schreibtisch.
|
||||
Vor Ort bei Tag und Nacht die Rohwerte ablesen und `HELL_LOW`/`HELL_HIGH`/
|
||||
`HELL_MAX` bestätigen — besonders die Grenzlage bei 2400. Bis dahin läuft die
|
||||
Anzeige mit fester Helligkeit (`run_esp32.main()` ohne `with_ldr`).
|
||||
- **Umschaltschwelle in der Sternwarte gegenprüfen.** Die Schwelle (1800) ist am
|
||||
realen Aufbau gemessen (2026-07-27, siehe *Helligkeitsregelung*), aber am
|
||||
Schreibtisch. Vor Ort bei Tag und Nacht die Rohwerte ablesen und die Schwelle in
|
||||
`settings.json` bestätigen. Bis dahin läuft die Anzeige mit fester Helligkeit
|
||||
(`run_esp32.main()` ohne `with_ldr`).
|
||||
- **MQTT-Anbindung.** Die Einstellungen liegen bereits zur Laufzeit änderbar in
|
||||
`settings.json` (`settings.update(...)`, geprüft auf Typ und Bereich); der
|
||||
MQTT-Client, der sie von außen setzt, fehlt noch.
|
||||
- **Netzwerk zur echten Montierung.** Die GM4000 steht in `192.168.1.115`, das
|
||||
Heimnetz des ESP32 ist `192.168.178.x` — der Mac erreicht sie per VPN, der
|
||||
ESP32 so nicht. Muss geklärt werden, bevor es an die echte Montierung geht.
|
||||
@@ -343,51 +347,75 @@ zerlegt (Trennzeichen `:`, `*`, `0xDF`, `'` sind alle egal).
|
||||
|
||||
## Helligkeitsregelung
|
||||
|
||||
Portiert aus dem alten MSP430-Programm (`DoDimmen_V`). Ein LDR-Rohwert
|
||||
(12-Bit-ADC, 0–4095) wird über `raw_to_ldr` in die Zählrichtung „groß = hell"
|
||||
gebracht, über einen gleitenden Mittelwert (8 Werte) geglättet und auf eine
|
||||
Helligkeitsstufe mit Hysterese abgebildet:
|
||||
**Zwei Helligkeiten, ein Umschaltpunkt.** Unterhalb der Schwelle läuft die Anzeige
|
||||
mit `dunkel_prozent`, oberhalb mit `hell_prozent`. Die vier abgestuften Helligkeiten
|
||||
des alten MSP430-Programms (5/15/50/100 %) sind bewusst aufgegeben — für die
|
||||
Sternwarte genügt der Wechsel Tag/Nacht.
|
||||
|
||||
| Stufe | Helligkeit | erreicht ab (hoch / runter) |
|
||||
|------|-----------|------------------------------|
|
||||
| 0 | 5 % | < 1050 |
|
||||
| 1 | 15 % | ≥ 1350 / < 1050 |
|
||||
| 2 | 50 % | ≥ 2550 / < 2250 |
|
||||
| 3 | 100 % | ≥ 3350 / < 3050 |
|
||||
Ein LDR-Rohwert (12-Bit-ADC, 0–4095) wird über `raw_to_ldr` in die Zählrichtung
|
||||
„groß = hell" gebracht, über einen gleitenden Mittelwert (8 Werte) geglättet und
|
||||
gegen die Schwelle gehalten:
|
||||
|
||||
Schwellen-Mitten `1200 / 2400 / 3200`, Hysterese einheitlich `±150`.
|
||||
| Bereich | Helligkeit | Umschaltpunkt |
|
||||
|---|---|---|
|
||||
| unter der Schwelle | `dunkel_prozent` = 5 % | herunter ab < 1650 |
|
||||
| über der Schwelle | `hell_prozent` = 50 % | hoch ab ≥ 1950 |
|
||||
|
||||
Schwelle `1800`, Hysterese `±150`. Beim allerersten Messwert entscheidet die
|
||||
blanke Schwelle (1800) statt der Kante — sonst startete die Anzeige im Bereich
|
||||
dazwischen fälschlich dunkel und wachte erst später auf.
|
||||
|
||||
### Die Werte stehen in `settings.json`, nicht im Code
|
||||
|
||||
`config.py` ist Programmcode und ändert sich nur beim Deployen. Die Helligkeiten
|
||||
und die Schwelle sollen dagegen im Betrieb verstellbar sein — **später über MQTT**.
|
||||
Sie liegen deshalb als JSON auf dem Gerät und werden über `settings.py` gelesen und
|
||||
geschrieben:
|
||||
|
||||
```python
|
||||
import settings
|
||||
settings.load() # mit Vorgaben aufgefüllt
|
||||
settings.update({"hell_prozent": 60}) # ändern und speichern
|
||||
```
|
||||
|
||||
Ein laufender `BrightnessController` übernimmt Änderungen mit `reload()`.
|
||||
|
||||
Jeder Wert wird beim Laden **und** beim Schreiben geprüft (Typ und Bereich:
|
||||
Prozente 0–100, Schwelle 0–4095). Das ist der Grund, warum die Prüfung überhaupt
|
||||
existiert: Sobald MQTT dazukommt, kommen die Werte von außen, und ein
|
||||
Helligkeitswert von 500 % oder eine Schwelle von −1 würde die Anzeige sonst
|
||||
unbrauchbar machen. Fehlt die Datei oder ist sie beschädigt, gelten die Vorgaben
|
||||
aus `settings.DEFAULTS` — ein Gerät in der Sternwarte soll sich nicht an einer
|
||||
kaputten Konfigurationsdatei aufhängen. Ein einzelner unbrauchbarer Wert verwirft
|
||||
nur diesen, nicht die ganze Datei.
|
||||
|
||||
`settings.json` wird von `deploy.sh` **nicht** mitkopiert und steht in `.gitignore`:
|
||||
Es ist Laufzeitzustand des Geräts, kein Quellcode. Würde es mitkopiert, wären die
|
||||
eingestellten Werte nach jedem Deployen weg.
|
||||
|
||||
### Die Schwelle stammt aus einer Messung
|
||||
|
||||
**Am realen Aufbau gemessen (2026-07-27)**, XIAO ESP32-C3 mit LDR an GPIO2,
|
||||
je 200 Messwerte, Median — Werte nach `raw_to_ldr`:
|
||||
|
||||
| Lichtsituation | roh | nach `raw_to_ldr` | Stufe |
|
||||
|---|---|---|---|
|
||||
| abgedeckt | 4095 (ADC-Anschlag) | 0 | 0 → 5 % |
|
||||
| Raumlicht | 1642 | 2453 | 1 → 15 % |
|
||||
| angeleuchtet (Taschenlampe) | 543 | 3552 | 3 → 100 % |
|
||||
| abgedeckt | 4095 (ADC-Anschlag) | 0 | dunkel → 5 % |
|
||||
| Raumlicht | 1642 | 2453 | hell → 50 % |
|
||||
| angeleuchtet (Taschenlampe) | 543 | 3552 | hell → 50 % |
|
||||
|
||||
Die alten Werte `300 / 2500 / 3500` stammten vom MSP430-Aufbau und passten nicht:
|
||||
Stufe 3 begann bei 3650 und war **unerreichbar** — selbst eine Taschenlampe direkt
|
||||
auf dem Sensor kam nur auf 3552. Die Aufteilung ist jetzt so gewählt, dass der
|
||||
5-%-Bereich bis 1200 reicht („nachts länger dunkel", schont die Dunkeladaption).
|
||||
Die Schwelle 1800 liegt mit Abstand zwischen dem Dunkelwert und dem Raumlicht.
|
||||
|
||||
Auch die **Hysterese war zu klein**: Der Rohwert streut bei Raumlicht um ±270,
|
||||
nach der Mittelung bleiben rund ±32 (1σ). Die früheren `±30` am untersten Übergang
|
||||
lagen darunter — die unterste Stufe hätte geflattert. Jetzt einheitlich ±150 (≈4,7σ)
|
||||
und damit weit unter dem Stufenabstand von 800.
|
||||
|
||||
Ein Helligkeitstelegramm wird nur bei **Stufenwechsel** gesendet (`ESC H 2 <ppp>`),
|
||||
wie im Original. Am Gerät bestätigt: Abdecken schaltet herunter, Freigeben wieder
|
||||
hoch, ohne Flattern.
|
||||
|
||||
> **Bekannte Grenzlage:** Der gemessene Raumlichtwert 2453 liegt nur 53 Zähler über
|
||||
> `HELL_HIGH` (2400) und damit innerhalb der Hysterese — Raumlicht landet deshalb auf
|
||||
> Stufe 1 (15 %), nicht auf 50 %. Ob das so gewollt ist, entscheidet sich erst an den
|
||||
> Lichtverhältnissen in der Sternwarte. `test_brightness.py` hält das Verhalten fest.
|
||||
**Die Hysterese ist nicht optional.** Der Rohwert streut bei Raumlicht um ±270,
|
||||
nach der Mittelung bleiben rund ±32 (1σ). Ohne Hysterese würde die Anzeige am
|
||||
Umschaltpunkt zwischen den beiden Helligkeiten hin- und herspringen; ±150 liegt
|
||||
sicher darüber (≈4,7σ). Ein Helligkeitstelegramm wird ohnehin nur bei
|
||||
**Stufenwechsel** gesendet (`ESC H 2 <ppp>`), wie im Original.
|
||||
|
||||
**Im Dunkeln steht der ADC am Anschlag** (4095). Der Teiler treibt A0 über den
|
||||
Messbereich, „Dämmerung" und „stockdunkel" sind daher nicht unterscheidbar. Für die
|
||||
Regelung unkritisch — nachts ist ohnehin die dunkelste Stufe gewollt. Eine feinere
|
||||
Messbereich, „Dämmerung" und „stockdunkel" sind daher nicht unterscheidbar. Bei
|
||||
nur zwei Helligkeiten ist das ohne Belang — unterschieden werden muss nur hell
|
||||
gegen dunkel, und dafür reicht die Auflösung weit. Eine feinere
|
||||
Nachtabstufung ginge nur über den Vorwiderstand: sättigungsfrei wäre
|
||||
`R2 ≥ R_LDR(dunkel) × (3,3 V − U_max)/U_max`, also grob `R2 ≥ 0,32 × R_LDR(dunkel)`.
|
||||
Bei einem typischen LDR (0,5–1 MΩ im Dunkeln) liefe das auf 160–330 kΩ hinaus — dann
|
||||
|
||||
Reference in New Issue
Block a user