POE* mmWave PIR Sensor

Here’s my latest POE mmWave PIR Sensor. This one is only using the POE for power and not Ethernet. It uses a PoE FeatherWing, TinyS3, LD2410 and a EKMB1309113K. I forgot to get some assemly pictures.





Case

1 Like

Are you going to share the source files?

Also without 150mm separation or a permanent barrier between the mains and LAN cabling that contravenes the wiring rules in my country.

Yeah I think US NEC also requires physical separation of line voltage and low voltage devices when in the same wallbox. But aside that, good choice for the PIR.

Now we need to talk about those screws on your wall plate… :no_mouth:

1 Like

The mains is in a dual gang box and the low voltage is seperate. This is the orginal dual gang and then I 3d printed this: Low Voltage Add a Gang Mounting Bracket by justinrsmith23 - Thingiverse

What’s wrong with the screws?

It needs a bit more work I think but if anyone wants it I could share it. When I was testing the design I always pluged the Cat6 cable in after it was in the low volatage bracket and when I went to install it and try and fit it through the hole after the bracket was installed it was a pretty tight fight.

Looks nice. Please share how you integrated this with HA?
And what was the total cost of your build?

I used this libary for the LD2410: GitHub - rain931215/ESPHome-LD2410: ESPHome LD2410 mmWave Radar Sensor Custom Component

Here is the yaml:

esphome:
  name: main-bath-occupancy-sensor
  platformio_options:
    board_build.extra_flags:
      - "-DARDUINO_USB_CDC_ON_BOOT=0"  
  includes:
    - header/ld2410_uart.h
  on_boot:
    priority: 600
    # ...
    then:
      - lambda: |-
          auto uart_component = static_cast<LD2410 *>(ld2410);
          uart_component->setNumbers(maxMovingDistanceRange, maxStillDistanceRange, noneDuration);

esp32:
  board: um_tinys3
  framework:
    type: arduino

# Enable logging
logger:
  baud_rate: 0

# Enable Home Assistant API
api:

ota:
  password: ""

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

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Main-Bath-Occupancy-Sensor"
    password: !secret wifi_ap_password

captive_portal:

uart:
  id: uart1
  tx_pin: GPIO05
  rx_pin: GPIO04
  baud_rate: 256000 # Change this according to your setting
  parity: NONE
  stop_bits: 1
#  debug:
#    direction: BOTH
#    dummy_receiver: false
#    after:
#      delimiter: [0xF8,0xF7,0xF6,0xF5]
      
custom_component:
  - lambda: |-
      return {new LD2410(id(uart1))};
    components:
      - id: ld2410

binary_sensor:
  - platform: gpio
    pin:
      number: GPIO07
      mode: INPUT_PULLDOWN
    name: "Main Bath Room PIR"
    id: pir_motion_sensor
    device_class: motion
    filters:
      - delayed_off: 10s
  - platform: gpio
    pin:
      number: GPIO21
      mode: INPUT_PULLUP
    name: "Main Bath Room mmWave"
    id: mmWave_sensor
    device_class: motion
  - platform: template
    name: "Main Bath Room Occupancy"
    id: occupancy
    device_class: occupancy
    filters:
      - delayed_off: 15s
    lambda: |-
      if ( id(mmWave_sensor).state or id(pir_motion_sensor).state) {
        return true;
      } 
      else if (id(mmWave_sensor).state == 0 and id(pir_motion_sensor).state == 0) {
        return false;
      } 
      else {
        return id(occupancy).state;
      }

  - platform: custom
    lambda: |-
      auto uart_component = static_cast<LD2410 *>(ld2410);
      return {uart_component->hasTarget,uart_component->hasMovingTarget,uart_component->hasStillTarget,uart_component->lastCommandSuccess};
    binary_sensors:
      - name: "Has Target"
      - name: "Has Moving Target"
      - name: "Has Still Target"
      - name: "Last Command Success"    

sensor:
  - platform: custom
    lambda: |-
      auto uart_component = static_cast<LD2410 *>(ld2410);
      return {uart_component->movingTargetDistance,uart_component->movingTargetEnergy,uart_component->stillTargetDistance,uart_component->stillTargetEnergy,uart_component->detectDistance};
    sensors:
      - name: "Moving Target Distance"
        unit_of_measurement: "cm"
        accuracy_decimals: 0
      - name: "Moving Target Energy"
        unit_of_measurement: "%"
        accuracy_decimals: 0
      - name: "Still Target Distance"
        unit_of_measurement: "cm"
        accuracy_decimals: 0
      - name: "Still Target Energy"
        unit_of_measurement: "%"
        accuracy_decimals: 0
      - name: "Detect Distance"
        unit_of_measurement: "cm"
        accuracy_decimals: 0

number:        
  - platform: template
    name: "Max Moving Distance Range"
    id: maxMovingDistanceRange
    min_value: 1
    max_value: 8
    step: 1
    update_interval: never
    optimistic: true
    set_action:
      - lambda: |-
          auto uart_component = static_cast<LD2410 *>(ld2410);
          uart_component->setMaxDistancesAndNoneDuration(x,id(maxStillDistanceRange).state,id(noneDuration).state);
  - platform: template
    name: "Max Still Distance Range"
    id: maxStillDistanceRange
    min_value: 1
    max_value: 8
    step: 1
    update_interval: never
    optimistic: true
    set_action:
      - lambda: |-
          auto uart_component = static_cast<LD2410 *>(ld2410);
          uart_component->setMaxDistancesAndNoneDuration(id(maxMovingDistanceRange).state,x,id(noneDuration).state);
  - platform: template
    name: "None Duration"
    id: noneDuration
    min_value: 0
    max_value: 32767
    step: 1
    mode: box
    update_interval: never
    optimistic: true
    set_action:
      - lambda: |-
          auto uart_component = static_cast<LD2410 *>(ld2410);
          uart_component->setMaxDistancesAndNoneDuration(id(maxMovingDistanceRange).state,id(maxStillDistanceRange).state,x);
      
button:
  - platform: template
    name: "Reboot LD2410"
    on_press:
      lambda: 'static_cast<LD2410 *>(ld2410)->reboot();'
  - platform: template
    name: "Turn on config mode"
    on_press:
      - lambda: 'static_cast<LD2410 *>(ld2410)->setConfigMode(true);'
  - platform: template
    name: "Turn off config mode"
    on_press:
      - lambda: 'static_cast<LD2410 *>(ld2410)->setConfigMode(false);'
  - platform: template
    name: "Get config"
    on_press:
      - lambda: 'static_cast<LD2410 *>(ld2410)->queryParameters();'
  - platform: template
    name: "Set baud rate to 256000"
    on_press:
      - lambda: 'static_cast<LD2410 *>(ld2410)->setBaudrate(7);'
  - platform: template
    name: "Set baud rate to 115200"
    on_press:
      - lambda: 'static_cast<LD2410 *>(ld2410)->setBaudrate(5);'
  - platform: template
    name: "Set baud rate to 9600"
    on_press:
      - lambda: 'static_cast<LD2410 *>(ld2410)->setBaudrate(1);'    

FIrst thing I noticed viewing this post was the screws. Slots should all be vertical.

1 Like

Funny thing my father-in-law said the same thing. It’s been fixed now. :slight_smile:

1 Like