Tutoriel détecteur LD2450 esphome

LD2450

LD2450 un decteur milimetrique

capable de detecter jusqu’a 3 personnes et de donner leurs positions.

SOURCE : https://github.com/tsunglung/esphome-ld2450/blob/master/README.md
MATERIEL : UN ESP32 et UN LD2450 quelque dupont femellle/femelle

attention si vous prenez le ld2450 avec câbles ne vous fiez pas aux couleurs de câble mais a la gravure du circuit

Comme vous pouvez le voir chez moi noir 5V, rouge RX, blanc TX, jaune GND, du grand n’importe quoi ces chinois !!!

Câblage :

LD2450 --------------> ESP32
5volts ----------------> 5volts (vin)
GNG -----------------> GND
TX --------------------> RX2 GPIO17
RX --------------------> TX2 GPIO16

CODE:

Dans HA il faut faire un dossier dans esphome components
puis copier le fichier ld2450_uart.h du github

Capture d’écran du 2023-12-25 22-10-40

La première fois il faut installer un système minimal sur l’esp32 en connexion USB avec Webui Esphome
aprés avoir choisi le port serie, choisir l’option Prepare for first use
Une fois fait retournez dans votre HA dans esphome vous devriez voir votre ESP32
En haut a droite cliquez su SECRET puis entrez le code suivant:

Your Wi-Fi SSID and password
wifi_ssid: « votre ssid »
wifi_password: « le mot de passe de votre ssid »

ensuite choisir choisir EDIT puis copiez le Code ci-dessous
(sauvez dans un block note le code existant il servira a adapter le nouveau code)
Cliquez sur SAVE puis INSTALL

A personaliser (cherchez les XXXXXXXXX dans le début du code)

LE CODE
esp32:
  board: esp32dev
  framework:
    type: arduino

# Enable Home Assistant API
api:
  encryption:
    key: "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "VOTRE APxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
    password: "Le mot de passe xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

captive_portal:

# OLIVE

light:
  - platform: binary
    name: "Led bleu"
    output: light_output

output:
  - id: light_output
    platform: gpio
    pin: GPIO02

# LD2450
substitutions:
  devicename: ld2450
  upper_devicename: "Hi-Link LD2450"

esphome:
  name: ${devicename}
  comment: ${upper_devicename}
  includes:
    - components/ld2450_uart.h
  on_boot:
    priority: -100
    # ...
    then:
      - lambda: 'static_cast<LD2450 *>(ld2450)->getInfo();'
      - lambda: id(tracking_mode).publish_state("Multiple");



# Enable logging
logger:
  baud_rate: 0


ota:

uart:
  id: uart_ld2450
  tx_pin: GPIO17
  rx_pin: GPIO16
  baud_rate: 256000
  parity: NONE
  stop_bits: 1
#  debug:
#    direction: BOTH
#    dummy_receiver: false

custom_component:
  - lambda: |-
      return {new LD2450(id(uart_ld2450))};
    components:
      - id: ld2450

binary_sensor:
  - platform: custom
    lambda: |-
      auto uart_component = static_cast<LD2450 *>(ld2450);
      return {uart_component->lastCommandSuccess, uart_component->configMode, uart_component->bluetoothState};
    binary_sensors:
      - name: "Last Command Success"
        id: binary_sensor_command_state
        internal: true
      - name: "Config Mode"
        icon: mdi:cog
        id: binary_sensor_config_mode
      - name: "Bluetooth State"
        icon: mdi:bluetooth
        id: binary_sensor_bluetooth_state
        internal: true

button:
  - platform: template
    name: "Reboot LD2450"
    on_press:
      - lambda: 'static_cast<LD2450 *>(ld2450)->reboot();'
  - platform: template
    name: "Factory Reset LD2450"
    on_press:
      - lambda: 'static_cast<LD2450 *>(ld2450)->factoryReset();'
  - platform: template
    name: "Single Target Tracking"
    on_press:
      - lambda: 'static_cast<LD2450 *>(ld2450)->setSingle();'
  - platform: template
    name: "Multiple Targets Tracking"
    on_press:
      - lambda: 'static_cast<LD2450 *>(ld2450)->setMultiple();'
  - platform: template
    name: "Get Zones Information"
    on_press:
      - lambda: 'static_cast<LD2450 *>(ld2450)->getZone();'
  - platform: template
    name: "Set Zones Information"
    on_press:
      lambda: |-
        int type = 0;
        if (id(zone_type).state == "Disable Zone Filter") {
          type = 0;
        } else if (id(zone_type).state == "Only Detect Configured Zone") {
          type = 1;
        } else if (id(zone_type).state == "Not Detect Configured Zone") {
          type = 2;
        }
        static_cast<LD2450 *>(ld2450)->setZone(type, id(zone1_x1).state * 10, id(zone1_y1).state * 10, id(zone1_x2).state * 10, id(zone1_y2).state * 10, id(zone2_x1).state * 10, id(zone2_y1).state * 10, id(zone2_x2).state * 10, id(zone2_y2).state * 10, id(zone2_x1).state * 10, id(zone2_y1).state * 10, id(zone2_x2).state * 10, id(zone2_y2).state * 10);

number:
  - platform: template
    name: "Zone1 X1"
    id: zone1_x1
    icon: mdi:align-horizontal-left
    min_value: -100
    max_value: 100
    step: 1
    optimistic: true
  - platform: template
    name: "Zone1 Y1"
    id: zone1_y1
    icon: mdi:align-horizontal-distribute
    min_value: -100
    max_value: 100
    step: 1
    optimistic: true
  - platform: template
    name: "Zone1 X2"
    id: zone1_x2
    icon: mdi:align-horizontal-right
    min_value: -100
    max_value: 100
    step: 1
    optimistic: true
  - platform: template
    name: "Zone1 Y2"
    id: zone1_y2
    icon: mdi:align-horizontal-distribute
    min_value: -100
    max_value: 100
    step: 1
    optimistic: true
  - platform: template
    name: "Zone2 X1"
    id: zone2_x1
    icon: mdi:align-horizontal-left
    min_value: -100
    max_value: 100
    step: 1
    optimistic: true
  - platform: template
    name: "Zone2 Y1"
    id: zone2_y1
    icon: mdi:align-horizontal-distribute
    min_value: -100
    max_value: 100
    step: 1
    optimistic: true
  - platform: template
    name: "Zone2 X2"
    id: zone2_x2
    icon: mdi:align-horizontal-right
    min_value: -100
    max_value: 100
    step: 1
    optimistic: true
  - platform: template
    name: "Zone2 Y2"
    id: zone2_y2
    icon: mdi:align-horizontal-distribute
    min_value: -100
    max_value: 100
    step: 1
    optimistic: true
  - platform: template
    name: "Zone3 X1"
    id: zone3_x1
    icon: mdi:align-horizontal-left
    min_value: -100
    max_value: 100
    step: 1
    optimistic: true
  - platform: template
    name: "Zone3 Y1"
    id: zone3_y1
    icon: mdi:align-horizontal-distribute
    min_value: -100
    max_value: 100
    step: 1
    optimistic: true
  - platform: template
    name: "Zone3 X2"
    id: zone3_x2
    icon: mdi:align-horizontal-right
    min_value: -100
    max_value: 100
    step: 1
    optimistic: true
  - platform: template
    name: "Zone3 Y2"
    id: zone3_y2
    icon: mdi:align-horizontal-distribute
    min_value: -100
    max_value: 100
    step: 1
    optimistic: true

select:
  - platform: template
    name: "Template select"
    id: zone_type
    optimistic: true
    options:
      - Disable Zone Filter
      - Only Detect Configured Zone
      - Not Detect Configured Zone

sensor:
  - platform: custom
    lambda: |-
      auto uart_component = static_cast<LD2450 *>(ld2450);
      return {uart_component->target1Resolution, uart_component->target1Speed, uart_component->target1X, uart_component->target1Y, uart_component->target2Resolution, uart_component->target2Speed, uart_component->target2X, uart_component->target2Y, uart_component->target3Resolution, uart_component->target3Speed, uart_component->target3X, uart_component->target3Y, uart_component->targets, uart_component->zoneType, uart_component->zone1X1, uart_component->zone1Y1, uart_component->zone1X2, uart_component->zone1Y2, uart_component->zone2X1, uart_component->zone2Y1, uart_component->zone2X2, uart_component->zone2Y2, uart_component->zone3X1, uart_component->zone3Y1, uart_component->zone3X2, uart_component->zone3Y2
      };
    sensors:
      - name: "Target1 Resolution"
        unit_of_measurement: "nm"
        accuracy_decimals: 0
        icon: mdi:artboard
      - name: "Target1 Speed"
        unit_of_measurement: "cm/s"
        accuracy_decimals: 0
        icon: mdi:speedometer
      - name: "Target1 X"
        unit_of_measurement: "cm"
        accuracy_decimals: 0
        icon: mdi:map-marker-right
      - name: "Target1 Y"
        unit_of_measurement: "cm"
        accuracy_decimals: 0
        icon: mdi:map-marker-down
      - name: "Target2 Resolution"
        unit_of_measurement: "nm"
        accuracy_decimals: 0
        icon: mdi:artboard
      - name: "Target2 Speed"
        unit_of_measurement: "cm/s"
        accuracy_decimals: 0
        icon: mdi:speedometer
      - name: "Target2 X"
        unit_of_measurement: "cm"
        accuracy_decimals: 0
        icon: mdi:map-marker-right
      - name: "Target2 Y"
        unit_of_measurement: "cm"
        accuracy_decimals: 0
        icon: mdi:map-marker-down
      - name: "Target3 Resolution"
        unit_of_measurement: "nm"
        accuracy_decimals: 0
        icon: mdi:artboard
      - name: "Target3 Speed"
        unit_of_measurement: "cm/s"
        accuracy_decimals: 0
        icon: mdi:speedometer
      - name: "Target3 X"
        unit_of_measurement: "cm"
        accuracy_decimals: 0
        icon: mdi:map-marker-right
      - name: "Target3 Y"
        unit_of_measurement: "cm"
        accuracy_decimals: 0
        icon: mdi:map-marker-down
      - name: "Targets"
      - name: "Zone Type"
        id: zonetype
        icon: mdi:tangram
        internal: true
        on_value:
          then:
            lambda: |-
              if (id(zonetype).state == 0) {
                id(zone_type).publish_state("Disable Zone Filter");
              } else if (id(zonetype).state == 1) {
                id(zone_type).publish_state("Only Detect Configured Zone");
              } else if (id(zonetype).state == 2) {
                id(zone_type).publish_state("Not Detect Configured Zone");
              }
      - name: "Zone1 X1"
        id: zone1x1
        unit_of_measurement: "cm"
        accuracy_decimals: 0
        icon: mdi:align-horizontal-left
        internal: true
        on_value:
          then:
            - lambda: id(zone1_x1).publish_state(id(zone1x1).state);
      - name: "Zone1 Y1"
        id: zone1y1
        unit_of_measurement: "cm"
        accuracy_decimals: 0
        icon: mdi:align-horizontal-distribute
        internal: true
        on_value:
          then:
            - lambda: id(zone1_y1).publish_state(id(zone1y1).state);
      - name: "Zone1 X2"
        id: zone1x2
        unit_of_measurement: "cm"
        accuracy_decimals: 0
        icon: mdi:align-horizontal-right
        internal: true
        on_value:
          then:
            - lambda: id(zone1_x2).publish_state(id(zone1x2).state);
      - name: "Zone1 Y2"
        id: zone1y2
        unit_of_measurement: "cm"
        accuracy_decimals: 0
        icon: mdi:align-horizontal-distribute
        internal: true
        on_value:
          then:
            - lambda: id(zone1_y2).publish_state(id(zone1y2).state);
      - name: "Zone2 X1"
        id: zone2x1
        unit_of_measurement: "cm"
        accuracy_decimals: 0
        icon: mdi:align-horizontal-left
        internal: true
        on_value:
          then:
            - lambda: id(zone2_x1).publish_state(id(zone2x1).state);
      - name: "Zone2 Y1"
        id: zone2y1
        unit_of_measurement: "cm"
        accuracy_decimals: 0
        icon: mdi:align-horizontal-distribute
        internal: true
        on_value:
          then:
            - lambda: id(zone2_y1).publish_state(id(zone2y1).state);
      - name: "Zone2 X2"
        id: zone2x2
        unit_of_measurement: "cm"
        accuracy_decimals: 0
        icon: mdi:align-horizontal-right
        internal: true
        on_value:
          then:
            - lambda: id(zone2_x2).publish_state(id(zone2x2).state);
      - name: "Zone2 Y2"
        id: zone2y2
        unit_of_measurement: "cm"
        accuracy_decimals: 0
        icon: mdi:align-horizontal-distribute
        internal: true
        on_value:
          then:
            - lambda: id(zone2_y2).publish_state(id(zone2y2).state);
      - name: "Zone3 X1"
        id: zone3x1
        unit_of_measurement: "cm"
        accuracy_decimals: 0
        icon: mdi:align-horizontal-left
        internal: true
        on_value:
          then:
            - lambda: id(zone3_x1).publish_state(id(zone3x1).state);
      - name: "Zone3 Y1"
        id: zone3y1
        unit_of_measurement: "cm"
        accuracy_decimals: 0
        icon: mdi:align-horizontal-distribute
        internal: true
        on_value:
          then:
            - lambda: id(zone3_y1).publish_state(id(zone3y1).state);
      - name: "Zone3 X2"
        id: zone3x2
        unit_of_measurement: "cm"
        accuracy_decimals: 0
        icon: mdi:align-horizontal-right
        internal: true
        on_value:
          then:
            - lambda: id(zone3_x2).publish_state(id(zone3x2).state);
      - name: "Zone3 Y2"
        id: zone3y2
        unit_of_measurement: "cm"
        accuracy_decimals: 0
        icon: mdi:align-horizontal-distribute
        internal: true
        on_value:
          then:
            - lambda: id(zone3_y2).publish_state(id(zone3y2).state);

switch:
  - platform: template
    name: "Config Mode"
    lambda: |-
      if (id(binary_sensor_config_mode).state) {
        return true;
      } else {
        return false;
      }
    turn_on_action:
      - lambda: 'static_cast<LD2450 *>(ld2450)->setConfigMode(true);'
    turn_off_action:
      - lambda: 'static_cast<LD2450 *>(ld2450)->setConfigMode(false);'
  - platform: template
    name: "Bluetooth Function"
    lambda: |-
      if (id(binary_sensor_bluetooth_state).state) {
        return true;
      } else {
        return false;
      }
    icon: mdi:bluetooth
    turn_on_action:
      - lambda: 'static_cast<LD2450 *>(ld2450)->setBluetooth(true);'
    turn_off_action:
      - lambda: 'static_cast<LD2450 *>(ld2450)->setBluetooth(false);'

text_sensor:
  - platform: custom
    lambda: |-
      auto uart_component = static_cast<LD2450 *>(ld2450);
      return { uart_component->macAddress, uart_component->fwVersion, uart_component->trackingMode
      };
    text_sensors:
      - name: "Mac Address"
        icon: mdi:puzzle
      - name: "Firmware Versoin"
        icon: mdi:new-box
      - name: "Tracking Mode"
        icon: mdi:radar
        id: tracking_mode

Le résultat :

Amusez-vous bien, bonne fêtes !

9 « J'aime »

Merci pour le partage , je le met en favoris …+1

1 « J'aime »

Bonjour Didier,
De rien n’hésite pas a revenir vers moi si tu a des questions.

1 « J'aime »

Merci pour le tuto.
Reste à attendre la livraison de la commande pour faire la mise en oeuvre

Bonsoir,
Merci pour les encouragements
çà fait plaisir de ne pas avoir écrit tout ça pour rien …

3 « J'aime »

Bonjour à tous,

Merci pour ce tuto. Moi j’ai mis le mien en route en suivant la vidéo de ArminasTV, qui change un peu, mais on retrouve les même choses.

Néanmoins, je rencontre un petit problème avec, je m’explique. J’ai placer ce capteur dans mon garage dans le but de piloter automatiquement la lumière. Mais voila, une fois le capteur en place et la pièce vide, j’ai toujours une détection. Cela semble provenir de ma baie informatique. Avez vous une idée de ce qui pourrais produire ce signal?
Je vous joint une capture d’écran de ma fausse détection:
image
La zone verte représente mon garage et la baie informatique ce trouve juste a droite de la zone rouge dans le garage.
Dans ma baie, il y un un UDM pro, un switch Poe 24 ports, un Nas Synology, deux Raspberry, un onduleur, en deux trois boitiers de domotique propriétaire (Somfy)

Bonjour,
le LD2450 peut couvrir combien de surface en m² ?

Il est donnée pour 6m de profondeur et 4 m de chaque coté. Apres je n’ai pas encore réellement tester car je pense que dans les coins tu dois perdre un peu.

1 « J'aime »

Hello,

Citation
attention si vous prenez le ld2450 avec câbles ne vous fiez pas aux couleurs de câble mais a la gravure du circuit

Citation
Comme vous pouvez le voir chez moi noir 5V, rouge RX, blanc TX, jaune GND, du grand n’importe quoi ces chinois !!!

Tu peux facilement modifier le connecteur en levant légèrement les ergots blancs et en intervertissant les fils :wink:

2 « J'aime »

Oui bien sur c’était juste un avertissement pour que personne de s’y fasse prendre …

1 « J'aime »

Une autre source que je viens de découvrir ( pas testé )

encore un autre github (pas testé non plus)

Salut,
Une autre source par ici.
Cette source fait l’objet d’une PR dans ESPHome et devrait être intégré de manière officielle sous peu…
Testé, Ok de mon coté :wink:

2 « J'aime »

Bonjour olive,
As tu prévu une alimentation autonome avec une batterie de type LIPO 3,7 volts et un régulateur de tension pour alimenter l’ESP 32 en 3,3 volts?
Merci pour ton aide

Non c’est pas prévu, faut pas oublier que c’est du wifi donc assez gourmand !
Mais rien n’est impossible.

1 « J'aime »

Bonjour Nico,
Je ne sais pas pourquoi tu as cette fausse détection, cependant, il doit être simple de l’exclure de tes automatisations, ce qui n’aurait pas été le cas avec un 2410.

Ben ça c’est une bonne nouvelle, j’avais déjà vu que certains fork étaient en attente de ces PR.

Merci de l’info.

Salut Olive,
Merci pour ce tuto.

Super tuto. Merci
Je me suis fais un fp2 du pauvre :joy::joy::joy:



5 « J'aime »

Bravo je suis content que cette publication soit utile a quelque chose :wink:

1 « J'aime »

Je pense en mettre une dizaine dans la maison. Je pensais ramener un câble rj45 à chaque Ld2450 et mettre une alim 5v 40amp dans ma baie de brassage pour alimenter tous les esp32. Qu’en penses tu ?

J’aimerai pouvoir ajouter un bm280 et bh1750. Mais j’ai sais pas comment adapter ça :joy:

Merci a toi
Bon week-end