Update MEMORY.md, MEMORY.md, bachelor-thesis-summary.md, and 76 more files

This commit is contained in:
erik committed 2026-02-13 21:07:55 +01:00
commit 4426388063
79 files changed
+6169

No files matched your search

+161
View File
@@ -0,0 +1,161 @@
# ESP32 iBeacon Code-Analyse
Analyse des ESP32-Codes (`ESP32_iBeacon/ESP32_iBeacon.ino`) auf mögliche Ursachen
für instabile RSSI-Messwerte in der Android-App.
Datum: 2026-02-09
---
## Quelle: Gemini-Analyse
Die folgenden Probleme wurden von Google Gemini identifiziert:
### 1. KRITISCH: Advertising-Konflikt zwischen Service und iBeacon
**Gemini-Befund:** `init_service()` und `init_beacon()` überschreiben sich gegenseitig
das Advertising-Paket. `init_service()` startet Advertising mit Service-UUID, dann
stoppt `init_beacon()` alles und überschreibt es mit iBeacon-Daten. Das Service-Advertising
geht verloren. Beim Reconnect nach Disconnect wird `pAdvertising->start()` aufgerufen,
aber es ist unklar, welche Advertising-Daten dann aktiv sind.
**Gemini-Empfehlung:** Kombinierte Funktion nutzen, die iBeacon-Daten ins Haupt-Paket
und die Service-UUID ins Scan-Response-Paket legt.
**Eigene Einschätzung:** Bestätigt. Im Code wird in Zeile 78 (`init_service`) Advertising
gestartet, in Zeile 85 (`init_beacon`) sofort wieder gestoppt und neu konfiguriert.
Das ist zwar für den reinen iBeacon-Betrieb kein Problem (das letzte Paket gewinnt),
aber der `onDisconnect`-Callback (Zeile 29) startet Advertising erneut, ohne die
iBeacon-Daten neu zu setzen. Nach einer Verbindung könnten also fehlerhafte
Advertising-Pakete gesendet werden.
### 2. HOCH: Kein explizites Advertising-Intervall gesetzt
**Gemini-Befund:** Ohne explizites Intervall nutzt der ESP32 den BLE-Stack-Default.
Unregelmäßige Pakete führen zu variierenden Abtastraten auf der Android-Seite und
damit zu instabilen RSSI-Werten.
**Gemini-Empfehlung:** Festes Intervall von 100ms setzen:
```cpp
pAdvertising->setMinInterval(0xA0); // 160 * 0.625ms = 100ms
pAdvertising->setMaxInterval(0xA0);
```
**Eigene Einschätzung:** Bestätigt und sehr relevant. Der Default-Intervall liegt
typischerweise bei 100-1280ms, was für Indoor-Positioning zu unregelmäßig ist.
Ein festes, kurzes Intervall (100ms) sorgt für konsistente Datenrate auf der
Android-Seite. Die Android-App scannt bereits mit `SCAN_MODE_LOW_LATENCY`
(BleScanner.kt:165), profitiert aber nur davon, wenn der ESP32 auch regelmäßig sendet.
### 3. HOCH: TX-Power nicht explizit konfiguriert
**Gemini-Befund:** Die Sendeleistung wird nicht festgelegt, was zu variierender
Ausgangsleistung führen kann.
**Gemini-Empfehlung:**
```cpp
BLEDevice::setPower(ESP_PWR_LVL_P9); // +9 dBm
```
**Eigene Einschätzung:** Bestätigt. Ohne fixe TX-Power kann der ESP32 die Leistung
dynamisch anpassen. Für RSSI-basierte Distanzschätzung ist eine konstante
Sendeleistung zwingend notwendig, da die gesamte Berechnung auf dem
Log-Distance Path Loss Model basiert. Hinweis: Der Seeed XIAO ESP32-C3 unterstützt
bis zu +21 dBm – der korrekte Enum-Wert muss ggf. angepasst werden.
### 4. MITTEL: setSignalPower nicht kalibriert
**Gemini-Befund:** Der Wert `0xc5` (-59 dBm) im iBeacon-Paket ist ein Standardwert
und nicht für die verwendete Hardware kalibriert.
**Gemini-Empfehlung:** RSSI bei exakt 1m Abstand messen (60s Durchschnitt) und
den gemessenen Wert als Signed Byte in Hex setzen.
**Eigene Einschätzung:** Teilweise relevant. Der `signalPower`-Wert wird in der
Android-App aktuell nicht für die Distanzberechnung verwendet – stattdessen wird
`BeaconData.RSSI_AT_ONE_METER = -65.0` in Kotlin hardcoded (BeaconData.kt:37).
Die App liest zwar `txPower` aus dem Paket (BleScanner.kt:145), nutzt ihn aber
nicht im PositionCalculator. Trotzdem sollte der Wert korrekt sein, falls er
zukünftig genutzt wird.
### 5. MITTEL: Advertising-Flags
**Gemini-Befund:** Flags `0x1A` statt Standard-iBeacon `0x06`.
**Gemini-Empfehlung:** `0x06` verwenden (LE General Discoverable + BR/EDR Not Supported).
**Eigene Einschätzung:** Geringes Risiko. `0x1A` setzt zusätzlich das Bit für
"Simultaneous LE and BR/EDR (Controller)" – bei einem reinen BLE-Beacon unnötig,
aber in der Praxis unproblematisch. `0x06` wäre sauberer.
### 6. NIEDRIG: Manufacturer ID Byte-Order
**Gemini-Befund:** ESP32 sendet `0x004C` (Little-Endian, korrekt laut BLE-Spec).
Android-App parst mit `0x4C00`.
**Gemini-Empfehlung:** Android-App prüfen.
**Eigene Einschätzung:** Kein Problem. Android's `getManufacturerSpecificData()`
erwartet den Company Identifier in Host-Byte-Order. Der Wert `0x4C00` in der
Android-App (BeaconData.kt:12) ist korrekt für Apple's Company ID und funktioniert
nachweislich (die App empfängt ja Beacons). Die ESP32-Bibliothek übernimmt die
Konvertierung intern.
---
## Eigene Zusatzanalyse (Claude)
Über die Gemini-Analyse hinaus sind folgende Punkte aufgefallen:
### 7. HOCH: loop() sendet Notifications alle 2 Sekunden
In `loop()` (Zeile 114-123) wird bei bestehender Verbindung alle 2 Sekunden eine
Notification gesendet. Das ist für den iBeacon-Betrieb irrelevant, aber: Wenn sich
ein Gerät verbindet, könnte das Advertising unterbrochen oder verlangsamt werden.
Der ESP32 BLE-Stack kann nicht gleichzeitig eine aktive Verbindung bedienen und
mit voller Rate advertisen.
**Empfehlung:** Für reinen Beacon-Betrieb den gesamten Service-Teil entfernen
(init_service, MyCallbacks, MyServerCallbacks, Notification-Code in loop).
Der ESP32 soll nur advertisen, keine Verbindungen annehmen.
### 8. MITTEL: Kein Deep-Sleep / Light-Sleep zwischen Advertisements
Für Akkubetrieb fehlt jegliche Energiespar-Logik. Der ESP32 läuft permanent
im aktiven Modus, auch zwischen den Advertising-Events.
**Empfehlung:** Für den Seeed XIAO ESP32-C3 im Akkubetrieb Light-Sleep aktivieren
oder den ESP32 zwischen Advertisements in den Deep-Sleep schicken und per Timer
aufwecken.
### 9. NIEDRIG: PositionSmoother Alpha-Wert Diskrepanz
In der CLAUDE.md und im PositionSmoother-Defaultwert steht alpha=0.25, aber
in BleScanner.kt:52 wird `PositionSmoother(alpha = 0.15)` instanziiert.
Der tatsächlich verwendete Wert ist 0.15 (reaktiver als dokumentiert).
---
## Zusammenfassung: Prioritäten
| # | Priorität | Problem | Quelle |
|---|-----------|--------------------------------------|---------|
| 1 | KRITISCH | Advertising-Konflikt Service/iBeacon | Gemini |
| 2 | HOCH | Kein Advertising-Intervall gesetzt | Gemini |
| 3 | HOCH | TX-Power nicht fixiert | Gemini |
| 7 | HOCH | Verbindungen stören Advertising | Claude |
| 4 | MITTEL | SignalPower nicht kalibriert | Gemini |
| 5 | MITTEL | Advertising-Flags suboptimal | Gemini |
| 8 | MITTEL | Kein Energiesparmodus | Claude |
| 9 | NIEDRIG | Alpha-Wert Diskrepanz Doku vs Code | Claude |
| 6 | NIEDRIG | Manufacturer ID Byte-Order | Gemini |
## Empfohlene Maßnahmen (Reihenfolge)
1. Service-Teil komplett entfernen (nur iBeacon-Advertising, keine Verbindungen)
2. Festes Advertising-Intervall setzen (100ms)
3. TX-Power explizit auf Maximum fixieren
4. SignalPower im iBeacon-Paket kalibrieren (RSSI @ 1m messen)
5. Flags auf 0x06 ändern
6. Light-Sleep für Akkubetrieb implementieren
7. Alpha-Wert in CLAUDE.md korrigieren (0.15 statt 0.25)