196 lines
12 KiB
Markdown
196 lines
12 KiB
Markdown
> ⚠️ **Funktioniert nicht. Konflikt zwischen mehreren SPI nicht von Claude in
|
||
> angemessener Zeit lösbar.**
|
||
|
||
# VL53L5CX an ESP32-C3 (0.42" OLED Board) anschließen
|
||
|
||
Diese Anleitung beschreibt die Verkabelung des VL53L5CX (8×8 Time-of-Flight
|
||
Multizonen-Sensor) an das **ESP32-C3 0,42-Zoll OLED Development Board**
|
||
(Type-C, Keramikantenne — verschiedene Hersteller/AliExpress-Listings, häufig
|
||
unter "01Space ESP32-C3 0.42 OLED" geführt) für die [firmware.ino](firmware.ino)
|
||
in diesem Verzeichnis.
|
||
|
||
## Wichtig: dieses Board hat nur EINEN I2C-Bus
|
||
|
||
Das eingebaute 0,42″-OLED (72×40 Pixel sichtbar, SSD1306-Controller,
|
||
I2C-Adresse `0x3C`) ist auf diesem Exemplar intern fest auf **GPIO5 (SDA) /
|
||
GPIO6 (SCL)** verdrahtet (so verlötet, OLED läuft damit). Der ESP32-C3 hat
|
||
aber nur eine I2C-Hardware-Peripherie — es gibt **keinen zweiten, freien
|
||
I2C-Bus** für den externen Sensor.
|
||
|
||
**Lösung (Versuch):** Der VL53L5CX wurde an die **gleichen** Pins (GPIO5/GPIO6)
|
||
gehängt wie das OLED. Das sollte funktionieren, weil beide Geräte
|
||
unterschiedliche I2C-Adressen haben (OLED `0x3C`, VL53L5CX `0x29`) — mehrere
|
||
Geräte am selben I2C-Bus sind Standard, kein Konflikt. **In der Praxis bisher
|
||
ohne Erfolg** — der Sensor wird über `/i2c` (Adresse `0x29`) nicht gefunden,
|
||
trotz korrekt verlötetem LPN (3.3V) und geprüften Lötstellen.
|
||
|
||
## Benötigte Hardware
|
||
|
||
- ESP32-C3 0.42" OLED Development Board (Type-C, wie oben beschrieben)
|
||
- VL53L5CX Breakout-Board mit I2C/Qwiic-Anschluss (z.B. SparkFun SEN-18642
|
||
oder vergleichbar). **Wichtig:** ein Breakout-Board verwenden, kein nacktes
|
||
VL53L5CX-Die — das Breakout enthält den nötigen 3.3V-Spannungsregler.
|
||
|
||
## Pin-Belegung
|
||
|
||
| VL53L5CX Pin | ESP32-C3 Pin | Beschreibung |
|
||
|----------------|----------------|------------------------------------------------------------|
|
||
| `VIN` / `3V3` | `3V3` | Versorgungsspannung (3.3 V) |
|
||
| `GND` | `GND` | Masse |
|
||
| `SDA` | `GPIO5` | I2C Datenleitung — **gleicher Pin wie das eingebaute OLED** |
|
||
| `SCL` | `GPIO6` | I2C Taktleitung — **gleicher Pin wie das eingebaute OLED** |
|
||
| `LPN` | `3V3` | Enable, **active-LOW** (LOW = I2C deaktiviert). Viele Breakouts haben hier schon einen 47kΩ-Pull-up; feste 3.3V-Verbindung ist trotzdem robuster |
|
||
| `INT` | *offen / nicht verbunden* | Interrupt-Pin — wird in dieser Firmware nicht benötigt (Polling per `isDataReady()`) |
|
||
|
||
> **Anderes Board?** Falls du statt des 0.42"-OLED-Boards ein anderes
|
||
> ESP32-C3-Devboard verwendest (ohne eingebautes Display), prüfe dessen
|
||
> Pinout-Diagramm und passe `SDA_PIN`/`SCL_PIN` ganz oben in
|
||
> [firmware.ino](firmware.ino) entsprechend an.
|
||
|
||
> **Pull-up-Widerstände:** Die meisten VL53L5CX-Breakout-Boards haben bereits
|
||
> Pull-up-Widerstände (4.7 kΩ) für SDA/SCL integriert. Bei kurzen Kabeln
|
||
> (< 20 cm) sind keine zusätzlichen Widerstände nötig.
|
||
|
||
## ASCII-Schaubild
|
||
|
||
```
|
||
ESP32-C3 0.42" OLED Board VL53L5CX Breakout (I2C / Qwiic)
|
||
┌─────────────────────────┐ ┌───────────────────────────┐
|
||
│ ┌─────────┐ │ │ │
|
||
│ │ 0.42" │ │ │ │
|
||
│ │ OLED │◄── intern ─┼─ GPIO5 (SDA) │ │
|
||
│ │ 0x3C │◄── intern ─┼─ GPIO6 (SCL) │ │
|
||
│ └─────────┘ │ │ │
|
||
│ │ │ │
|
||
│ 3V3 ●────────────────┼───────────────► VIN / 3V3 │
|
||
│ GND ●────────────────┼───────────────► GND │
|
||
│ GPIO5 ● ┼─── (selber Pin wie OLED-SDA) ──► SDA (Adresse 0x29) │
|
||
│ GPIO6 ● ┼─── (selber Pin wie OLED-SCL) ──► SCL │
|
||
│ │ │ │
|
||
│ │ 3V3 ──────► LPN (Enable, high) │
|
||
│ │ offen ────► INT (nicht verwendet) │
|
||
└─────────────────────────┘ └───────────────────────────┘
|
||
▲
|
||
USB-C (5V, 3.3V wird onboard erzeugt)
|
||
```
|
||
|
||
I2C-Bus mit zwei Teilnehmern an denselben Leitungen (GPIO5/GPIO6), unterschieden
|
||
durch ihre Adresse:
|
||
|
||
```
|
||
GPIO5/SDA ───┬─────────────────┬──────────────► OLED (0x3C)
|
||
GPIO6/SCL ───┤ │
|
||
└─────────────────┴──────────────► VL53L5CX (0x29)
|
||
```
|
||
|
||
### Draufsicht / Übersicht des Aufbaus
|
||
|
||
```
|
||
┌────────────┐ I2C-Bus (GPIO5/6 + 3V3/GND) ┌──────────────┐
|
||
│ ESP32-C3 │ ════════════════════════════════════════ │ VL53L5CX │
|
||
│ + 0.42" │ ════════════════════════════════════════ │ (8x8 ToF) │
|
||
│ OLED │ └──────┬───────┘
|
||
└─────┬──────┘ │
|
||
│ │
|
||
│ WLAN (STA → vorhandenes Netz, oder AP → eigenes Netz) │ Sichtfeld
|
||
▼ ▼
|
||
┌────────────┐ ░░░░░░░░░░░░░░
|
||
│ Browser │ <─ WS Push (Port 81, sofort) ──────────── 64 (od. 16)
|
||
│ (Landing- │ <─ HTTP Fallback ──────────────────────── Distanzwerte
|
||
│ Page) │ GET /api/points (JSON-Array) (mm), 8x8/4x4
|
||
└────────────┘
|
||
```
|
||
|
||
## Software / Bibliotheken (Arduino IDE)
|
||
|
||
1. **Boardverwalter:** „esp32“ von Espressif Systems installieren, Board
|
||
**„ESP32C3 Dev Module“** auswählen.
|
||
2. **Bibliotheksverwalter:** folgende Bibliotheken installieren:
|
||
- „**SparkFun VL53L5CX**“ von SparkFun Electronics
|
||
- „**WebSockets**“ von Markus Sattler (Links2004) — für den Push-Kanal auf Port 81
|
||
- „**U8g2**“ von oliver (olikraus) — für das eingebaute 0.42"-OLED
|
||
3. In [firmware.ino](firmware.ino) ganz oben anpassen (nur als Erst-Boot-Default,
|
||
siehe „Inbetriebnahme“ unten — danach alles über `/config` änderbar):
|
||
- `DEFAULT_WIFI_SSID` / `DEFAULT_WIFI_PASSWORD` — das WLAN, das zuerst versucht wird
|
||
- `AP_SSID` / `AP_PASSWORD` — Name/Passwort des Fallback-Access-Points
|
||
- `SDA_PIN` / `SCL_PIN` — auf `5`/`6` voreingestellt (passend zum 0.42"-OLED-Board); nur ändern, wenn ein anderes Board ohne eingebautes Display verwendet wird
|
||
|
||
## Inbetriebnahme (Provisioning) ohne erneutes Flashen
|
||
|
||
WLAN-Zugangsdaten, Sensor-Frequenz und Sensor-Auflösung sind **nicht mehr nur
|
||
Compile-Konstanten**, sondern werden persistent im Flash (Preferences/NVS)
|
||
gespeichert und über die Konfigurationsseite geändert:
|
||
|
||
1. Erstes Flashen mit den `DEFAULT_*`-Werten (oder einfach Default lassen).
|
||
2. Findet der ESP32 das hinterlegte WLAN nicht, startet er den Access Point
|
||
`VL53L5CX-ESP32` (Passwort `tofsensor`).
|
||
3. Mit diesem AP verbinden, Browser öffnen: `http://192.168.4.1/config`
|
||
4. Dort echtes WLAN, Sensor-Auflösung (8×8/4×4) und Frequenz eintragen,
|
||
**Speichern & Neustart** klicken — der ESP32 bootet neu und verbindet
|
||
sich mit dem eingetragenen WLAN.
|
||
5. Ab da ist die Seite jederzeit über `/config` (im STA-Modus z.B.
|
||
`http://vl53l5cx.local/config`) erreichbar, um Werte zu ändern.
|
||
|
||
> Die Konfigurationsseite läuft über **unverschlüsseltes HTTP ohne
|
||
> Login** — nur fürs lokale (Heim-)Netz gedacht, nicht ins Internet exponieren.
|
||
|
||
## Verhalten der Firmware (Kurzfassung)
|
||
|
||
- **Boot-Log:** Über die serielle Schnittstelle (115200 Baud) wird beim Start
|
||
ausführlich geloggt: Chip-Infos, geladene Konfiguration, alle gefundenen
|
||
WLAN-Netze inkl. RSSI/Kanal (mit Markierung `[ZIEL]` falls das konfigurierte
|
||
Netz dabei ist), gewählter Modus (STA/AP) mit IP/MAC, sowie der
|
||
Sensor-Initialisierungsstatus.
|
||
- Der VL53L5CX wird **nur dann aktiv ausgelesen**, wenn in den letzten 5
|
||
Sekunden jemand die Landing-Page (`/`) oder die API (`/api/points`)
|
||
aufgerufen hat, **oder** mindestens ein WebSocket-Client verbunden ist.
|
||
Ist niemand da, wird das Ranging gestoppt.
|
||
- **WebSocket-Push (Port 81):** Jeder verbundene Client (`ws://<ip>:81/`)
|
||
bekommt jeden neu ausgelesenen Frame **sofort** nach dem Lesen als JSON
|
||
gepusht — kein Polling-Delay. Die Landing-Page nutzt diesen Kanal
|
||
automatisch und fällt nur bei Verbindungsabbruch auf HTTP-Polling
|
||
(`/api/points`) zurück.
|
||
- Die Landing-Page zeigt die Distanzwerte als farbiges Grid (Größe passt sich
|
||
automatisch an 8×8 oder 4×4 an) sowie als rohes JSON-Array an.
|
||
- **Eingebautes OLED:** zeigt durchgehend WLAN-Modus (`STA`/`AP`), die aktuelle
|
||
IP-Adresse und den Sensor-Status (`aktiv` / `idle` / `---` falls nicht
|
||
gefunden) an. Wird einmal direkt nach WLAN-Verbindung/Sensor-Init aktualisiert
|
||
und danach jede Sekunde aufgefrischt, damit "aktiv"/"idle" live mitgeht.
|
||
- **I2C-Übersicht (`/i2c`):** Debug-Seite, scannt beim Aufruf den gesamten
|
||
I2C-Bus (Adressen `0x01`–`0x7E`) und listet alle antwortenden Geräte auf
|
||
(bekannte Adressen wie `0x3C` = OLED, `0x29` = VL53L5CX werden benannt).
|
||
Zeigt zusätzlich den aktuellen `sensorFound`-Status und bietet einen Button
|
||
„Sensor erneut initialisieren“, der `myImager.begin()` neu auslöst — ohne
|
||
dass das Gerät neu starten muss. Aktueller Befund: hier erscheint nur
|
||
`0x3C` (OLED), `0x29` (VL53L5CX) fehlt.
|
||
- API-Antwort von `GET /api/points` bzw. WebSocket-Push (Beispiel, 8×8):
|
||
|
||
```json
|
||
{
|
||
"active": true,
|
||
"ranging": true,
|
||
"sensorFound": true,
|
||
"hz": 10,
|
||
"resolution": 64,
|
||
"rows": 8,
|
||
"cols": 8,
|
||
"wsClients": 1,
|
||
"timestampMs": 123456,
|
||
"wifiMode": "STA (ZyXEL7A9E80)",
|
||
"ip": "10.0.0.54",
|
||
"distanceMm": [1200, 1185, ...],
|
||
"status": [5, 5, ...]
|
||
}
|
||
```
|
||
|
||
### Hinweis zur bestehenden Node.js-Bridge (`room.config`)
|
||
|
||
Das übergeordnete Projekt (`server.js` / `room.config`) erwartet aktuell einen
|
||
ESP32-WebSocket unter `ws://<ip>/ws` (Port 80, Pfad `/ws`, CSV-Frames). Diese
|
||
Firmware nutzt bewusst einen **eigenständigen** WebSocket auf **Port 81**
|
||
(Pfad `/`, JSON statt CSV), da das die einfachste/stabilste Bibliothek auf dem
|
||
ESP32-C3 ist. Falls die bestehende Node-Bridge direkt mit dieser Firmware
|
||
sprechen soll, müsste entweder `room.config` (`esp.wsUrl`) auf
|
||
`ws://<ip>:81/` angepasst werden, oder die Firmware auf Port 80 + Pfad `/ws`
|
||
+ CSV-Format umgestellt werden — sag Bescheid, falls das gewünscht ist.
|