No description
  • C++ 63.6%
  • HTML 34.4%
  • C 2%
Find a file
martin 335af4aaa6 Brückenzähler: ESP32 + LD2450 Personenzähler mit Webinterface
Firmware für einen ESP32 mit HLK-LD2450 mmWave-Radar, die Personen auf
einer Brücke in beide Richtungen zählt.

- LD2450-UART-Parser und Tracking mit Linienzählung, Zonen und Filtern
- Eigenes offenes WLAN mit Captive Portal und Webinterface
  (Live-Radarkarte, Zähler, Einstellungen)
- Durchgangsprotokoll auf SD-Karte (Fallback: interner Flash) mit
  CSV-Archiv, Uhrzeit per Browser-Synchronisierung
- Unity-Tests für Parser und Zähllogik (pio test -e native)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-26 22:44:51 +02:00
src Brückenzähler: ESP32 + LD2450 Personenzähler mit Webinterface 2026-09-26 22:44:51 +02:00
test Brückenzähler: ESP32 + LD2450 Personenzähler mit Webinterface 2026-09-26 22:44:51 +02:00
web Brückenzähler: ESP32 + LD2450 Personenzähler mit Webinterface 2026-09-26 22:44:51 +02:00
.gitignore Brückenzähler: ESP32 + LD2450 Personenzähler mit Webinterface 2026-09-26 22:44:51 +02:00
platformio.ini Brückenzähler: ESP32 + LD2450 Personenzähler mit Webinterface 2026-09-26 22:44:51 +02:00
README.md Brückenzähler: ESP32 + LD2450 Personenzähler mit Webinterface 2026-09-26 22:44:51 +02:00

LD2450 Personenzähler (ESP32)

Firmware für einen ESP32 mit HLK-LD2450 24-GHz-Radar. Sie zeigt die Personen im Erfassungsbereich live an, zählt sie pro Zone und zählt Durchgänge über eine virtuelle Linie in beide Richtungen. Bedient wird alles über ein Webinterface im eigenen WLAN des ESP32.

Verkabelung

LD2450 ESP32
5V 5V/VIN
GND GND
TX GPIO16
RX GPIO17

SD-Kartenmodul (SPI):

SD-Modul ESP32
3V 3V3
GND GND
SCK GPIO18
DO (MISO) GPIO19
DI (MOSI) GPIO23
CS GPIO5

Die Karte muss FAT32 formatiert sein (Karten über 32 GB sind meist exFAT und müssen umformatiert werden).

Der LD2450 braucht 5 V (3,3 V reichen nicht), seine UART-Pegel sind 3,3 V. Die Pins lassen sich beim Bauen überschreiben, z. B. PLATFORMIO_BUILD_FLAGS="-DRADAR_RX_PIN=17 -DRADAR_TX_PIN=16".

Bauen und Flashen (NixOS)

nix shell nixpkgs#platformio nixpkgs#gcc
pio test -e native                       # Unit-Tests für Parser und Zähllogik (Host)
pio run -e esp32dev -t upload            # Firmware inkl. Webinterface flashen
pio device monitor                       # serieller Log, 115200 Baud

Falls das Flashen mit "No serial data received" abbricht: beim Verbinden die BOOT-Taste gedrückt halten.

Der serielle Log gibt jede Sekunde Frames/s, empfangene Bytes, Zähler und die erkannten Ziele aus. bytes=0 heißt, dass vom Sensor nichts ankommt (Strom oder Verkabelung prüfen). Wenn Bytes ankommen, aber keine Frames erkannt werden, stimmt die Baudrate nicht (Standard 256000).

Bedienung

  1. Mit dem WLAN PersonCounter verbinden (Passwort personcounter).
  2. http://192.168.4.1 öffnen (viele Geräte öffnen die Seite automatisch als Captive Portal).
  3. Die Karte zeigt den Blick von oben mit dem Sensor unten in der Mitte (Sichtfeld ±60°, 6 m).
  • Zähllinie: Unter „Auf Karte setzen“ zwei Punkte anklicken. Die Pfeile zeigen, welcher Zähler bei welcher Laufrichtung hochgeht (grün/orange, Namen frei wählbar); mit „Richtung umkehren“ werden sie getauscht. Gezählt wird nur, wenn eine Person das gelbe Hystereseband vollständig durchquert und dabei innerhalb der Linienlänge bleibt.
  • Zonen: bis zu 3 Rechtecke, jeweils mit der Anzahl der Personen darin.
  • Filter: maximale Reichweite und ein Ausschlussbereich für Störquellen (z. B. Ventilator oder Vorhang).
  • Speichern legt die Einstellungen dauerhaft im Flash (NVS) ab. Die Zählerstände werden höchstens alle 30 s gesichert und überstehen so einen Neustart.

Der LD2450 erkennt maximal 3 Ziele gleichzeitig.

Aufbau an einer Brücke

Die Voreinstellung ist für einen Gehweg gedacht, auf dem Personen quer durchs Sichtfeld laufen:

  • Sensor seitlich am Geländer, etwa auf Hüft- bis Brusthöhe, quer über den Gehweg gerichtet.
  • Zähllinie senkrecht durch die Mitte (x = 0) von 0,3 m bis 4 m Abstand. Die Linie sollte die ganze Gehwegbreite abdecken, aber nicht über das gegenüberliegende Geländer hinausreichen.
  • Links → Rechts zählt grün, Rechts → Links orange; „Gesamt“ ist die Summe.

Grenzen: Mehr als 3 Personen gleichzeitig im Bild (Gruppen) werden unterzählt, und wer direkt hinter einer anderen Person geht, kann verdeckt werden. Radfahrer werden mitgezählt.

Durchgangsprotokoll

Jeder Durchgang wird mit Richtung und Zeit gespeichert und im Webinterface unter „Durchgänge“ angezeigt (neueste zuerst, als CSV herunterladbar). Neue Einträge werden spätestens nach 30 s geschrieben, bei Stromausfall können also die letzten Sekunden fehlen.

  • Mit SD-Karte: Das Protokoll liegt auf der Karte. Zusätzlich wird jeder Durchgang an durchgaenge.csv angehängt (Datum;Uhrzeit;Richtung;Start;Sekunden seit Start). Diese Datei wird nie gekürzt oder gelöscht, auch nicht über „Protokoll löschen“; sie lässt sich direkt am PC öffnen. Datum und Uhrzeit fehlen darin, wenn der ESP beim Schreiben die Uhrzeit noch nicht kannte.
  • Ohne SD-Karte: Das Protokoll liegt im internen Flash. Beim nächsten Start mit Karte wird es automatisch auf die Karte übernommen.
  • Karte im Betrieb entfernt: Bis zu 256 Durchgänge werden im RAM gepuffert und beim Wiedereinstecken nachgeschrieben (spätestens nach 30 s).
  • Für das Webinterface werden 50.000 bis 100.000 Einträge vorgehalten; danach fallen dort die ältesten weg.

Uhrzeit: Der ESP32 hat keine Uhr. Jedes Mal, wenn das Webinterface geöffnet wird, übernimmt er die Uhrzeit des Browsers. Durchgänge vor dem Stellen bekommen trotzdem die richtige Zeit, solange der ESP dazwischen nicht neu gestartet ist. Nach einem Stromausfall sollte die Seite deshalb einmal geöffnet werden; Durchgänge aus einer Startphase, in der das nie passiert ist, erscheinen als „Zeit unbekannt“ (mit Start-Nummer und Laufzeit).

API

Methode Pfad Beschreibung
GET /api/settings aktuelle Einstellungen (JSON)
POST /api/settings Einstellungen ändern (auch teilweise, JSON)
POST /api/reset Zähler auf 0 setzen
POST /api/reboot Neustart
GET /api/events Durchgangsprotokoll, binär (Format in src/eventlog.h), ?from=N überspringt die ersten N
POST /api/time Uhrzeit setzen: {"epoch": <Unix-Sekunden>} (macht das Webinterface automatisch)
POST /api/clear-events Protokoll löschen
WS /ws Live-Daten mit ~10 Hz: t = [id,x,y,v] pro Person, z = Anzahl pro Zone, n, in, out, occ, fps, frames, err, up, lc (Einträge im Protokoll), clk (Uhrzeit, 0 = nicht gestellt)

Aufbau

  • src/ld2450.* – UART-Frame-Parser und Befehle für den Sensor
  • src/tracker.* – Tracking, Linienzählung, Zonen, Filter
  • src/settings.* – Einstellungen als JSON in NVS
  • src/eventlog.* – Durchgangsprotokoll auf SD-Karte bzw. LittleFS, CSV-Archiv
  • src/web.* – Access Point, Captive Portal, HTTP-API, WebSocket
  • web/index.html – Webinterface, wird in die Firmware eingebettet
  • test/ – Unity-Tests (pio test -e native)