
Erfahre, wie du ein mmWave Präsenzmelder Selbstbauen kannst!
Ein Smarthome braucht so viele Daten wie möglich. Nachdem mein Smarthome mit Bewegungsmeldern in jedem Raum ausgestattet war, konnte ich das Licht beim Betreten des Raumes automatisieren.
Allerdings stand ich schnell vor einem Problem bzw. im Dunkeln. Der Bewegungsmelder erkennt nicht, wenn sich eine Person im Raum befindet, aber z.B. still auf dem Sofa sitzt. Das Licht ging aus – ich saß im dunklen. Hier hilft ein LD2410 mmWave Präsenzmelder!
Wie das Wort schon sagt, reagiert dieser nicht auf Bewegungen, sondern meldet die Anwesenheit im Raum. Dies erschreckend genau. Auf mehrere Meter entfernen wird sogar ein Atmen erkannt.
Diese Aufgabe lösen wir mit einem mmWave-Radarsensor.
Inhalt
Was ist ein mmWave Präsenzmelder
Ein mmWave-Sensor sendet elektromagnetische Wellen im Millimeterwellenbereich aus, die von Objekten in der Umgebung reflektiert oder gestreut werden. Der Sensor empfängt die reflektierten oder gestreuten Wellen und analysiert ihre Eigenschaften wie Laufzeit, Phasenverschiebung und Intensität.
Basierend auf diesen Eigenschaften werden Informationen über die Umgebung, wie Entfernung, Geschwindigkeit, Richtung und Größe von Objekten, gewonnen. Die Laufzeit der Wellen ermöglicht die Messung der Entfernung von Objekten, während die Phasenverschiebung die Messung der Geschwindigkeit ermöglicht.
Die Intensität der reflektierten oder gestreuten Wellen gibt Aufschluss über die Größe oder Beschaffenheit von Objekten. Zusammen ermöglicht die Analyse dieser Welleneigenschaften dem mmWave-Sensor präzise Erfassung und Detektion von Objekten und Informationen über die Umgebung.
Neben der vorgestellten Selbstbaulösung gibt es z.B. das Fertigprodukt Aqara FP1. Eine selbstgebaute Variante hat zum einen den Preisvorteil (ca. 10€). Zum anderen kann diese einfach per MQTT in das Smathome System eingebunden werden.
Was wird benötigt für einen mmWave Präsenzmelder
- Wemos D1 Mini: Ein günstiger, aber leistungsstarker ESP8266-basierter Mikrocontroller
- HLK-LD2410-Modul: ein mmWave Sensor der besonders günstig ist
- Kabel: Zum Verbinden der Komponenten.
- USB-Kabel: Zum Flashen der Firmware auf den Wemos D1 Mini.
- Lötkolben / Lötzinn / Seitenschneider
- Optional: Jumper-Kabel
- Optional: Ein 3D gedrucktes Gehäuse
Schritt 1 – Hardware
Als erstes wird die Platine HLK-LD2410 mit dem Wemos D1 Mini verbunden. Das Herzstück des mmWave Präsenzmelder. Beim Kauf des Moduls empfiehlt es sich, die Platine mit angelöteten Pins zu bestellen.
Der Sensor ist erstaunlich klein. Mit einem Lochabstand von nur 1,27 mm wird es eine knifflige Angelegenheit, die Kabel anzulöten.
- Verbinde den VCC-Pin des HLK-LD2410-Moduls mit dem 5V-Pin des Wemos D1 Mini.
- Verbinde den GND-Pin des HLK-LD2410-Moduls mit dem GND-Pin des Wemos D1 Mini.
- Verbinde den RX-Pin des HLK-LD2410-Moduls mit dem TX-Pin des Wemos D1 Mini.
- Verbinde den TX-Pin des HLK-LD2410-Moduls mit dem RX-Pin des Wemos D1 Mini.
- Verbinde den OUT-Pin des HLK-LD2410-Moduls mit dem D1-Pin des Wemos D1 Mini.
Stelle sicher, dass du die Verbindungen fest und korrekt machst, um eine zuverlässige Kommunikation zwischen den Komponenten sicherzustellen.
Schritt 2 – yaml erstellen
Als nächstes erstellen wir die Firmware für den Wemos. Hier wecken wir den mmWave Präsenzmelder zum leben. Da wir ESPHome verwenden, müssen wir eine yaml-Datei erstellen. Hier kürzen wir ab. Denn im ioBroker Forum bin ich auf einen Beitrag gestoßen, wo ein User das Script bereits erstellt hat.
Neben dem Script wird noch die uart_read_line_sensor_ld2410v3.h benötigt. Diese muss im ioBroker in den Pfad /opt/iobroker/iobroker-data/esphome.0 kopiert werden.
Nachdem dies geschehen ist, öffnen wir ESPHome. Danach erstellen wir eine Standard ESP-Home yaml, welcher nachher auf den mmWave Präsenzmelder gespielt wird.

Anschließend wird dem Sensor ein Name gegeben.

Hier wählen wir ESP8266 für einen Wemos d1 mini.

Bearbeiten und Ersetzen des Codes
Nun editieren wir diese und ersetzen den Code mit dem aus dem ioBroker Beitrag:
esphome:
name: ld2410m3d1
includes:
- uart_read_line_sensor_ld2410v3.h
on_boot:
priority: -100
then:
- script.execute: get_config
esp8266:
board: esp01_1m
# Enable logging
logger:
baud_rate: 0
logs:
sensor: INFO # DEBUG level with uart_target_output = overload!
binary_sensor: INFO
text_sensor: INFO
# Enable Home Assistant API
api:
ota:
wifi:
ssid: "yyyyyyyyy1"
password: "xxxxxxxxxxxxxx2"
use_address: 192.168.178.67
substitutions:
device_name: dev-sensor
mqtt:
broker: 192.168.178.59
port: 1506
topic_prefix: ld2410motion/motion3
web_server:
port: 80
version: 2
include_internal: true
ota: false
captive_portal:
uart:
id: uart_bus
tx_pin:
number: GPIO1
rx_pin:
number: GPIO3
baud_rate: 256000
parity: NONE
stop_bits: 1
switch:
- platform: safe_mode
name: use_safe_mode
- platform: template
name: configmode
id: configmode
optimistic: true
# assumed_state: false
turn_on_action:
# - switch.turn_off: engineering_mode
- lambda: 'static_cast<LD2410 *>(ld2410)->setConfigMode(true);'
- delay: 100ms
- script.execute: clear_targets
turn_off_action:
- lambda: 'static_cast<LD2410 *>(ld2410)->setConfigMode(false);'
- platform: template
name: show_target_stats
id: show_stats
optimistic: true
internal: true
turn_off_action:
- script.execute: clear_targets
text_sensor:
- platform: template
name: uptime_human_readable
id: uptime_human_readable
icon: mdi:clock-start
update_interval: 60s
sensor:
- platform: uptime
name: uptime_sensor
id: uptime_sensor
update_interval: 60s
internal: true
on_raw_value:
then:
- text_sensor.template.publish:
id: uptime_human_readable
state: !lambda |-
int seconds = round(id(uptime_sensor).raw_state);
int days = seconds / (24 * 3600);
seconds = seconds % (24 * 3600);
int hours = seconds / 3600;
seconds = seconds % 3600;
int minutes = seconds / 60;
seconds = seconds % 60;
return (
(days ? to_string(days)+":" : "00:") +
(hours ? to_string(hours)+":" : "00:") +
(minutes ? to_string(minutes)+":" : "00:") +
(to_string(seconds))
).c_str();
- platform: custom # currently crashes ESP32
lambda: |-
auto uart_component = static_cast<LD2410 *>(ld2410);
//return {uart_component->movingTargetDistance,uart_component->movingTargetEnergy,uart_component->stillTargetDistance,uart_component->stillTargetEnergy,uart_component->detectDistance};
return {};
sensors:
- platform: template
name: movingTargetDistance
id: movingTargetDistance
unit_of_measurement: "cm"
accuracy_decimals: 0
internal: true
- platform: template
name: movingTargetEnergy
id: movingTargetEnergy
unit_of_measurement: "%"
accuracy_decimals: 0
internal: true
- platform: template
name: stillTargetDistance
id: stillTargetDistance
unit_of_measurement: "cm"
accuracy_decimals: 0
internal: true
- platform: template
name: stillTargetEnergy
id: stillTargetEnergy
unit_of_measurement: "%"
accuracy_decimals: 0
internal: true
- platform: template
name: detectDistance
id: detectDistance
unit_of_measurement: "cm"
accuracy_decimals: 0
internal: true
custom_component:
- lambda: |-
return {new LD2410(id(uart_bus))};
components:
- id: ld2410
binary_sensor:
- platform: gpio
name: mmwave_presence_ld2410
id: mmwave_presence_ld2410
pin: GPIO5
device_class: motion
on_state:
then:
- if:
condition:
- binary_sensor.is_off: mmwave_presence_ld2410
then:
- delay: 150ms
- script.execute: clear_targets
number:
- platform: template
name: configMaxDistance
id: maxconfigDistance
unit_of_measurement: "M"
min_value: 0.75
max_value: 6
step: 0.75
update_interval: never
optimistic: true
set_action:
- switch.turn_on: configmode
- delay: 50ms
- lambda: |-
auto uart_component = static_cast<LD2410 *>(ld2410);
uart_component->setMaxDistancesAndNoneDuration(x/0.75,x/0.75,id(noneDuration).state);
- delay: 50ms
- lambda: 'static_cast<LD2410 *>(ld2410)->queryParameters();'
- delay: 50ms
- switch.turn_off: configmode
- platform: template
name: "sensitivity_threshold_(%)"
id: allSensitivity
min_value: 10
max_value: 100
step: 5
mode: box
update_interval: never
optimistic: true
set_action:
- switch.turn_on: configmode
- delay: 50ms
- lambda: |-
auto uart_component = static_cast<LD2410 *>(ld2410);
uart_component->setAllSensitivity(x);
- delay: 50ms
- lambda: 'static_cast<LD2410 *>(ld2410)->queryParameters();'
- delay: 50ms
- switch.turn_off: configmode
- platform: template
name: "motion_hold_(sec)"
id: noneDuration
min_value: 0
# max_value: 32767
max_value: 900
step: 1
mode: box
update_interval: never
optimistic: true
set_action:
- switch.turn_on: configmode
- delay: 50ms
- lambda: |-
auto uart_component = static_cast<LD2410 *>(ld2410);
uart_component->setMaxDistancesAndNoneDuration(id(maxconfigDistance).state, id(maxconfigDistance).state, x);
- delay: 50ms
- lambda: 'static_cast<LD2410 *>(ld2410)->queryParameters();'
- delay: 50ms
- switch.turn_off: configmode
button:
- platform: restart
name: "reset/restart_ESP/MCU"
entity_category: diagnostic
on_press:
- switch.turn_on: configmode
- delay: 50ms
- lambda: 'static_cast<LD2410 *>(ld2410)->factoryReset();'
- delay: 150ms
- lambda: 'static_cast<LD2410 *>(ld2410)->reboot();'
- delay: 150ms
script:
- id: get_config
then:
- switch.turn_on: configmode
- delay: 500ms
- lambda: 'static_cast<LD2410 *>(ld2410)->queryParameters();'
- delay: 500ms
- switch.turn_off: configmode
- id: clear_targets
then:
- lambda: |-
//id(hasTarget).publish_state(0);
//id(hasMovingTarget).publish_state(0);
//id(hasStillTarget).publish_state(0);
id(movingTargetDistance).publish_state(0);
id(movingTargetEnergy).publish_state(0);
id(stillTargetDistance).publish_state(0);
id(stillTargetEnergy).publish_state(0);
id(detectDistance).publish_state(0);Hier müssen wir noch folgende Änderungen vornehmen:
wifi:
ssid: "yyyyyyyyy1"
password: "xxxxxxxxxxxxxx2"
use_address: 192.168.178.67Hier müssen die WLAN-Zugangsdaten eingegeben werden. Soll der Sensor eine feste IP erhalten, so kann diese hier eingetragen werden. Falls keine vergeben werden soll, muss die Zeile gelöscht werden.
mqtt:
broker: 192.168.178.59
port: 1506
topic_prefix: ld2410motion/motion3Hier werden die Zugangsdaten für die MQTT-Verbindung festgelegt. Die IP des MQTT Brokers und der Port müssen angegeben werden. Im Topic geben wir an, in welchem Kanal der Sensor seine Werte ablegen soll.
Schritt 3 – Konfigurieren des mmWave Präsenzmelder
Jetzt können wir den Wemos flashen. Wir speichern die Datei und gehen auf „Install“ jetzt wählen wir mit welcher Methode wir flashen wollen. Ich bevorzuge es die Datei herunterzuladen und mit dem ESPHome-Flasher zu flashen.

Sobald der Flashvorgang abgeschlossen ist, sollte der Sensor mit dem WLAN und dem MQTT Broker kommunizieren.
Über die <<ip-adresse:80>> kann die Webkonfiguration geöffnet werden.

Hier können wir die Empfindlichkeit, die Entfernung und die Zeit einstellen, nach der der mmWave Präsenzmelder wieder den Wert „off“ ausgibt.
Hier hilft nur ausprobieren. Platziere den Sensor an der Stelle, an der er später sein soll. Dann stelle die Werte so ein, dass der Sensor die Anwesenheit erkennt.
Nun kontrollieren wir noch, ob die Werte über MQTT ankommen. Dazu gehen wir im ioBroker in die Objekte und öffnen den MQTT Adapter.

Optional kann der mmWave Präsenzmelder auch in einem 3D gedruckten Gehäuse untergebracht werden. Mir hat dieses Gehäuse sehr gut gefallen, da der Sensor so noch leicht in seiner Position verstellt werden kann.

Beispiele für Automationen
- Beim Verlassen des Raumes wird das Licht ausgeschaltet.
- Beim Betreten des Arbeitszimmers an Werktagen morgens werden Monitore, Drucker und der Heimarbeitsplatz-Computer eingeschaltet. Beim Verlassen des Raumes werden die Minitore ausgeschaltet, um Energie zu sparen.



Schreibe einen Kommentar