ZigBee Radar Raum Tracking Bewegungsmelder ESP32-C6 HLK-LD2450

  • Alpha Phase
    Erwerb Juni



    ESP32-C6


    Radarsensor mit bis zu 3 Ziele Erkennung gleichzeitig


    Unbegrenzte Anzahl von Zonenerkennung über Javascript mit html integration

    Helligkeitsanzeige in Lux
    Optionaler Anschlussmöglichkeit für Temperatur und Druck Anzeige.


    Bausatz für Bastler (ESP32-C6)

    Elektronik-Bausatz mit 3m USB Kabel u. optionalem Gehäuse.

    Auf Wunsch löte ich ihn privat fertig zusammen.

    Platine ist Beigabe (ohne CE, keine Gewährleistung).

    ➡️ -->Kauflink für ca. 20,99€ - 27,99€<---


        



        





    Aktuelles Projekt :

    Ein auf dem ESP32-C6 basierendes Zigbee-Gerät mit angeschlossenem HLK-LD2450 3D-Radarsensor zur personenbasierten Präsenz- und Bewegungsanalyse – ideal für Smart Home Automation auf Raumebene.

    Funktionen & Features:

    • Direkte Zigbee-Integration via eigener Firmware (ESP32-C6 + LD2450 per UART)

    • 3 gleichzeitige Personen erkennbar mit Positionsdaten (X/Y), Abstand und Bewegungsrichtung

    • Zigbee-Datenpunkte: distance, x, y, velocity, valid, target_id, resolution – für alle Slots

    • Volle VIS-Unterstützung (ioBroker) mit HTML-Raumansicht:

      • Echtzeit-Visualisierung der Person(en) im Raum

      • Automatische Rotation des Koordinatensystems je nach Sensorlage

      • Grafische Darstellung inkl. Zonenlogik, z. B. zur Licht- oder Heizungssteuerung

    Besonderheiten:

    • Ideal für Multiraum-Setups: Jeder Raum mit einem Sensor möglich

    • Extrem geringe Latenz, keine Cloud nötig, läuft komplett lokal

    • Reduziert Fehlauslösungen gegenüber PIR oder mmWave deutlich

    • Perfekt erweiterbar mit ioBroker-Logik oder Blockly-Automationen

    • Anschluss eines LDR5528 (Lichtsensor) an PIN0. Dadurch Helligkeitsanzeige in Lux

    • Otional an PIN 21,22 Anschlussmöglichkeit eines BMP280

    • Unter Vollast ist der Stromverbrauch bei 5 V ca. 0,28 A (entspricht etwa 1,4 W Leistungsaufnahme)

    Zusammenbau:

    1. Erst den ESP von unten anlöten. Alle Pins an den ESP und danach alle Pins an die Platin!!!

    Schön Luft lassen zwischen ESP und Platine. So wie im Bild die Stifte immer nur ein wenig rausragen lassen, zum anlöten.

    Vor allem bei der Platine. Das da die Pins nicht weit rausgucken. Immer nur ein klein wenig. So das es halt reicht, zum anlöten.


    2. Dann die Bauteile von oben an die schon verlöteten Pins mit dran anlöten.

    Bedeutet, hier im Bild hab ich die Bauteile nur zur Veranschaulichung in die Löcher gesteckt.

    In Wirklichkeit sind da ja schon die Pins vom ESP drin. Einfach an die Pins so mit anlöten.

    Oberhalb der Platine werden die Bauteile so verlötet, das nichts direkt neben oder über dem Radarsensors sich was befindet.

    Das würde den Sensor stören, da Radarwellen nicht Metall durchdringen kann.



    3. Dann den Sensor draufstecken und von unten verlöten.

    Je genauer der Sensor angelötet wird, um so besser.

    Also nicht schief anlöten. Je perfekter er waagereicht und senkrecht und gleicher Abstand hat, um so genauer wird er messen.

      

    !! FERTIG !!


    LDR_PIN(Lichtsensor) an ESP -> 3,3V und ESP -> 0

    10kOhm_Widerstand an ESP -> 0 und ESP -> GND

    Optional(BMP280 3,3V muss selber gekauft werden):

    BMP_SDA_PIN an ESP -> 21

    BMP_SCL_PIN an ESP -> 22

    BMP_VCC an ESP -> 3,3V

    BMP_GND an ESP -> GND


    Verwendete Komponenten:



    Anleitung:

    1.

    Pairing Modus:

    Pairing: wenn es blinkt, ist er im pairing modus.

    Auf der Platine ist ein Loch zu sehen in der nähe vom USB Port.

    Dort mit ein Stift 5 Sekunden drücken. Dann fängt es an zu blinken, für den Pairing Modus


    2.

    Javascript Adapter:

    Kommando "exec" erlauben ein Häkchen setzen in der Adaptereinstellung

    including.js erstellen durch javascript:

    Das script erstellen und starten.

    Dadurch wird in /opt/iobroker/iobroker-data/zigbee_0/ eine including.js Datei erstellt, was benötigt wird, das der Adapter das Gerät findet.

    Falls nötig und der Adapter nicht standardmäßig installiert wurde ganz unten den Pfad anpassen:

    fs.writeFile('/opt/iobroker/iobroker-data/zigbee_0/including.js', inhalt, (err) => {



    3.

    Im Zigbee Adapter including.js eintippen und den Adapter neu starten.


    4.

    Im Zigbee Adapter das Gerät anlernen.

    Danach am Gerät im Zigbee Adapter auf den Namen klicken und dann auf den "reconfigure" Button.

    Dadurch werden die Werte dauerhaft übermittelt.



    5.

    Für jeden Bewegungsmelder dieses Javasricpt erstellen im Javascript Adapter.

    Im Script die Zonen u.s.w. einrichten und das script starten.

    Dadurch werden Datenpunkte erstellt im Javascript Adapter selber.


    6.

    Alle Datenpunkte, die erstellt wurden durch das Javascipt, mit den richtigen Daten bearbeiten/füllen.

    Wie man das macht, steht am Anfang von Javascript.


    7.

    VIS html Widget Code erstellen und Datenpunktverknüpfung javascript.0.arbeitszimmer.widgetHtml anpassen:

    1= HTML Widget

    2= Hier den Quellcode reinkopieren

    3= Raumbreite 1 px = 1cm

    4= Raumlänge 1 px = 1 cm

    Code
    1. <!-- Text‑HTML Widget
    2. Datenpunkt eintragen: javascript.0.wohnzimmer.widgetHtml
    3. Checkbox „Interpret HTML“ aktiv (noEscape = false) -->
    4. {javascript.0.arbeitszimmer.widgetHtml}


    8. Fertig


          


  • Firmware für den ESP32C6

    !!! ACHTUNG !!!

    !!! Immer wieder mal hier gucken, ob es updates gibt!!!!


    Funktioniert nur mit meinen bearbeiteten ESP32C6 Modulen


    Firmware Upgrade: Version 1.0.7.zip <- hier klicken. Unten sind nur ältere Versionen zum download

    Runterladen und entpacken.

    Dabei Antivirenprogramm und/oder Sicherheitshinweise zulassen von Windows.

    Mit dem USB Kabel den ESP verbinden. Port CH343. Unter der Boot Taste. Wo das Loch ist zum Pairing

    Die exe Datei ausführen und flashen.

    In der exe ist auch ein Serial Monitor verbaut.

    So kann man sehen, was das Gerät macht.


    Die Firmware kann man nur mit den von mir bearbeiteten ESP32C6 Module nutzen.

    Eigene funktionieren nicht.


    Versionshistorie:

    13.06.2025: Version 1.0.0.

    02.07.2025: Version 1.0.1.

    05.07.2025: Version 1.0.2. /// Lichtsensor Fix

    05.07.2025: Version 1.0.3 /// BMP280 Hot Fix

    05.07.2025: Version 1.0.4 /// blink led for pairing-hotfixes !!! Änderung der including.js. Einfach ersetzen und starten.

    08.07.2025: Version 1.0.5 /// blink led for pairing-hotfixes + Button !!! Pairing nach Stromausfall fix

    08.07.2025: Version 1.0.6 /// blink led for pairing-hotfixes + Button !!! Restart pairing fix

    08.07.2025: Version 1.0.7 /// Restart pairing fix

  • zigbee2mqtt

    data/external_converters/ld2450.mjs


  • UNGETESTET

    Komplett-How-to: LD2450-Radar in Home Assistant + Zigbee2MQTT

    profil Erweiterter Modus

    mqtt install start

    editor install start


    https://github.com/zigbee2mqtt/hassio-zigbee2mqtt

    zigbee2mqtt


    /homeassistant/configuration.yaml


    Gerät erstellen in

    /homeassistant/zigbee2mqtt/external_converters/LD2450_erforscht.js


    /homeassistant/room/arbeitszimmer/arbeitszimmer_zonen.yaml



    Node red


    subflow


    https://github.com/hacs/addons


  • Danke für die Antwort:

    Ich habe alles so gemacht wie beschrieben, nur habe ich ein Master/Slave System und das Srcipt erstellt die Datei auf dem Master.

    Nun habe ich die Datei auf den Slave kopiert, aber auch kein Erfolg

    Dann habe ich in der Zigbee Instanz den kompletten Pfad eingegeben zu der including.js und siehe da....

    scheint so als ob ich jetzt weiter machen kann...

    Danke für die Hilfe.

  • Moin Moin...

    Ich habe meinen Sensor im Raum auf 12 Uhr und ca. 240cm Höhe, im 45° Winkel angebracht und habe Probleme das der "rote Punkt" sehr viel springt und je näher ich dem Senor komme um so weiter links, im Treppen Bereich (ist auch eine Treppe) werde ich angezeigt. Auf dem 2. Bild stehe ich immer noch mittig im Flur.

    Wo soll ich den Sensor denn am besten anbringen?



    // ---- Vorgabewerte für Kalibrierung ----
    const calibrationDefaults = {
    raumX: 240, // ① Raum breite z.B. 200 cm
    raumY: 450, // ① Raum länge z.B. 400 cm
    sensorX: 120, // ① Sensor Position von links in cm z.B. 100 cm
    sensorY: 440, // ① Sensor Position von unten in cm z.B. 400 cm
    sensorZ: 180     // ① z.B. 180° wenn er oben wäre und nach unten überwachen soll
    };

    const debounceMs = 3000; // ① Verzögerung bis Zone false wird (ms)
    const EMPTY_THRESHOLD_M = 0.01; // ② Max. Abstand (1 cm) für leere Slots
    const zones = [
    { name:'Flur', color:'orange', x1:85, x2:235, y1:10, y2:440 },
    { name:'Treppe', color:'cyan', x1:5, x2:75, y1:10, y2:440 },
       // { name:'vorne rechts', color:'green', x1:131, x2:188, y1:10, y2:210 },
    ];

  • Moin Moin …

    Ich habe meinen Sensor auf 12 Uhr, ca. 240 cm Höhe und 45 ° Neigung angebracht. Der rote Punkt springt stark; je näher ich komme, desto weiter links (Treppe) werde ich angezeigt.

    Das Problem lässt sich super-easy mit ChatGPT analysieren.

    Ohne das wird mehr als schwer.

    Man muss verstehen wie ein Radarsensor funktioniert.

    Was es bedeutet, mitRadarwellen zu messen.

    Wo die hin gehhen. Wie die hingehen.

    Was passiert wenn die auf was treffen u.s.w.


    ChatGPT gefragt:

    "ich hab ein LD2450 mit einem esp32c6. Dort ist diese Script in iobroker als javasript integriert

    (dann den code posten)

    Dann habe ich deine Frage reinkopiert.

    Das ist die Antwort:



    CHATGPT:

    Warum der Punkt springt & „nach links zieht“

    1. Pitch-Fehler
      Die LD2450 rechnet mit waagerechter Antenne. Bei 240 cm Höhe und 45 ° Neigung kippst du das ganze Koordinatensystem.
      Effekt: Je näher die Person steht, desto stärker driftet der Punkt seitlich.
    2. Übersteiler Winkel
      • Zentralstrahl trifft den Boden schon nach 2,4 m (240 cm / tan 45°).
      • Nähere Ziele nur noch im Randbereich ⇒ schwächeres Signal ⇒ Jitter.
    3. Treppen-Reflexionen
      Metallgeländer und Stufen erzeugen Mehrwege-Echos; der Tracker springt zwischen Echo-Peaks.

    Besser aufhängen – zwei erprobte Varianten

    Variante Höhe Neigung (↓) Warum das hilft
    A Decken-Sweet-Spot 220 – 240 cm 25 – 30 ° Zentralstrahl trifft Boden erst ≈ 4 m entfernt → kaum Totzone.
    B Brust-/Kopfhöhe 130 – 150 cm 15 – 20 ° Frontale Sicht → beste Mikro­bewegungs-Erkennung (stöß­anfälliger).
    Zitat
    Praxis-Regel
    Tilt ≈ arctan(H / YMitte)
    Bei H = 240 cm und YMitte ≈ 225 cm ergibt das ≈ 27 °.

    Montage-Checkliste

    1. Exakte Ausrichtung – Sensoroberkante parallel zur Flurwand, Pitch zuletzt einstellen.
    2. Wand statt Decke (falls Treppe stört) – ≥ 20 cm Abstand zu den Stufen.
    3. Reflexionen dämpfen – 20 × 40 cm Sperrholzblende hinter/unter dem Modul.
    4. Kabelzug entkoppeln – Gummi­puffer oder 3-D-Halter gegen Vibrationen.

    Schritt-für-Schritt-Vorgehen

    1. Neigung von 45 ° auf ≈ 28 ° stellen, Flur ablaufen → Punkt sollte mittig bleiben.
    2. Driftet er noch? → Yaw feinjustieren (siehe Code unten) oder Sensorplatte drehen.
    3. Jitter?
      • Geländer testweise mit Pappe abdecken → wenn ruhiger, Blende montieren.
      • Filter (Moving Avg / Kalman) erhöhen.
    4. Grenzfälle prüfen (Treppenantritt, < 1 m vorm Sensor). Totzone < 1 m? → ok; sonst Tilt + 3 °.

    Kurzantwort:
    LD2450 am besten auf 230 cm Höhe mit ~28 ° Tilt montieren (oder 140 cm / 18 ° für Mikro­bewegungen). Ausrichtung exakt einstellen und kleines Moving-Average-Filter aktivieren – schon ist das Hakeln weg.


    1 · Fein-Yaw als separates Kalibrations-Feld

    Statt die 3,5 ° direkt im Code zu verdrahten, leg sie als State an, damit du sie in VIS anpassen kannst:


    Code
    1. // --- NEU: in „Kalibrierung“ aufnehmen -------------
    2. ensure(PREFIX + 'calibration.yawFine', 0,
    3. {type:'number', read:true, write:true});

    Dann im update() die Zeile

    Code
    1. const sz = rad(val(PREFIX + 'calibration.sensorZ') || 0);

    ersetzen durch

    Code
    1. const sz = rad(
    2. (val(PREFIX + 'calibration.sensorZ') || 0) +
    3. (val(PREFIX + 'calibration.yawFine') || 0) // Fein-Offset
    4. );

    Jetzt kannst du den Winkel bequem in 0,1-°-Schritten nachtrimmen, bis der Punkt exakt mittig läuft.


    2 · Sanftes Low-Pass-Filtering pro Slot

    Der Rohwert-Jitter verschwindet, wenn du pro Slot eine exponentielle Glättung (EMA) machst.

    Direkt oberhalb von function update(){ … } ein globales Objekt anlegen:


    Code
    1. // --- NEU: Filterpuffer -----------------------------------------------
    2. const filters = {
    3. 1:{x:null,y:null}, 2:{x:null,y:null}, 3:{x:null,y:null}
    4. };
    5. const alpha = 0.30; // 0…1 (höher = schneller, niedriger = ruhiger)

    Und im Slot-Loop nach const wY = sy + relY; einsetzen:

    Code
    1. / Glättung -------------------------------------------------------------
    2. const id = p.x.match(/slot([1-3])_x$/)[1]; // '1' | '2' | '3'
    3. if(filters[id].x === null){ // erster Wert -> direkt
    4. filters[id].x = wX; filters[id].y = wY;
    5. }else{
    6. filters[id].x = alpha * wX + (1-alpha) * filters[id].x;
    7. filters[id].y = alpha * wY + (1-alpha) * filters[id].y;
    8. }
    9. const wXf = filters[id].x;
    10. const wYf = filters[id].y;

    Danach alle Verwendungen von wX/wY im Slot-Block auf wXf/wYf umstellen (Zonen-Check, Begrenzen & VIS-Position).


    3 · Kleinst-Schwankungen ganz ausblenden

    Gerade wenn du nah am Sensor stehst, schwanken X/Y manchmal um ±1 cm, obwohl du still­stehst.

    Den Schwellenwert kannst du im bestehenden Parameter einfach etwas höher setzen:


    Code
    1. const EMPTY_THRESHOLD_M = 0.03; // 3 cm statt 1 cm

    Damit werden „Pseudo-Leerwerte“ ignoriert und der Punkt bleibt sichtbar, statt ständig zu verschwinden.


    Ergebnis

    • Yaw-Fehler korrigierbar, ohne neu zu flashen.

    • Sprungfreier Punkt dank EMA-Filter (30 % frisch, 70 % alt).

    • Geringe Flackerei entfällt, weil Mini-Schwankungen <3 cm übersehen werden.

    Zitat
    Tipp: Wenn du noch mehr Ruhe möchtest, reduziere alpha z. B. auf 0,15.

    Bei sehr schnellen Bewegungen (z. B. Rennen) dagegen auf 0,5 erhöhen.

    Einfach die drei Abschnitte einbauen, Skript speichern, kurz neu laden – das war’s. Viel Erfolg beim Testen!

    Ganzes script:


    Einbau-Checkliste

    1. Im Skript-Editor des ioBroker einfügen und speichern.

    2. 1 · Schnellvariante – Wert im Admin setzen
      1. Objekte-Tab öffnen.
      2. Zu javascript.0.arbeitszimmer.calibration.yawFine navigieren

        (wird vom Skript automatisch angelegt).
      3. Doppelklick auf den Wert → Gradzahl eintragen (z. B. 3.5) → Speichern.
      Das Skript reagiert sofort, dein Punkt verschiebt sich live.

      Ideal zum einmaligen Nachjustieren.
    3. Optional alpha anpassen, falls du noch mehr (oder weniger) Glättung möchtest.

    Damit bleiben Firmware & Datenpunkte unverändert – nur die Anzeige wird ruhiger und der Drift lässt sich live nachregeln. Viel Erfolg!