Files
appRobotRoom/firmware/info.md
2026-06-16 10:06:05 +02:00

12 KiB
Raw Permalink Blame History

⚠️ 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 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 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 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 0x010x7E) 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):
{
  "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.