LD2410 Human presence radar sensor

The reliable detection of human presence is not easy to achieve. But there is an interesting very small sensor HLK-LD2410(B) for this purpose.

It uses 24GHz FMCW (frequency-modulated continuous wave)  radar technology.
Unlike infrared or ultrasonic based presence detection modules, this module is able to detect moving targets (people) as well as non-moving, standing people.



The LD2410B can be used standalone after setting some parameters via a serial interface. Then it can simply indicate the presence of a person by a connected LED. There is a windows tool for configuration and visualization.

The module is even Bluetooth/BLE capable, but I have not investigated this further until today.

But even more interesting is that the sensor can be a serial connected peripheral hardware to an  ESP32 .  For a fast prototyping I used again  Annex32, a very versatile  BASIC-Interpreter for ESP32 based devices.

My ESP32 in this project is a very small and in its housing well protected M5 ATOM lite or a M5 ATOM matrix. Any other ESP32 module will do the job as well, since connecting to the LD2410 requires only four exposed pins: GND, +5V, GPIO21, GPIO25

I wrote a BASIC-script to visualize the obtained data in a browser window.
The module knows a very conversational “engineering mode” where it displays the reflected energy of different distance ranges.

It was a bit tricky to extract the datastructure from the LD2410 serial communication manual. In return, however, very interesting, detailed information and measured values are provided,

The Webinterface visualizes especially the reflected 24GHz energy.

A target status register of the module indicates wether there is a moving and/or static target. The webinterface indicates this by a dynamic status text and two status LEDs.

On one hand there are 9 distance gates for the the doppler shifted energy refected at objects/targets moving towards or away from the module.

On the other hand, the radar module detects static, non-moving persons (in 7 gates only ) characterized by the slowly oscillating and doppler shifted energy reflected at their breathing body surface.


Very interesting and impressive to see how even a non moving person is detected very accurately by the reflection of the 24GHz radio signal on the breathing body.

There are some hints in the manual how to mount the LD2410 module, so that it can determin the energy in the different distance gates and how to connect it via the serial interface.


The BASIC script code is written with ANNEX32 a unique BASIC interpreter for ESP32 :

' HLK-LD2410 RADAR module from Hi-Link connected to an ESP32
' for very reliable detection of moving or non-moving persons

' - Connected via serial2 to an ESP32 (e.g. M5Stack ATOM matrix ESP32pico with 5x5 neopixel matrix)
' - Switches the radar unit to engineering mode to report more details.
' - Selects the data indicating a moving person (= moving target).
' - Selects the data indicating a non-moving but breathing person (= static target)

' - Creates a Webpage to ..
' -- Visualize the energy of the moving targets in 9 distance ranges by bar graphs
' -- Visualize the energy of the static targets in 7 distance ranges by bar graphs
' -- Visualize the internal detection for a moving target by a LED symbol
' -- Visualize the internal detection for a static target by a LED symbol
 
Version$ = "1.0" ' DB9JG 2023/03/

RX_pin       = 21   'pin for serial2 input comming from LD2410 TX-pin
TX_pin       = 25   'pin for serial2 output going to LD2410 RX-pin
toggle       = 0
t$           = ""
RADAR$       = ""
RADAR_X$     = ""
Target_state$= ""
count        = 0
moving_LED   = 1 'green
static_LED   = 1 'green

TState       = 0
MTDis1       = 0
MTDis2       = 0
ETE_val      = 0
STDIS_val1   = 0
STDis_val2   = 0
STE_val      = 0
DetDis1      = 0
DetDis2      = 0
MMD_gate     = 0
MSD_gate     = 0

static_range0=0  : moving_range0=0
static_range1=0  : moving_range1=0
static_range2=0  : moving_range2=0
static_range3=0  : moving_range3=0
static_range4=0  : moving_range4=0
static_range5=0  : moving_range5=0
static_range6=0  : moving_range6=0
static_range7=0  : moving_range7=0
static_range8=0  : moving_range8=0

gosub        SETUP_LD2410_RADAR

gosub        webpage
onhtmlreload webpage
onhtmlchange webpage

onserial2    SER2RX
timer0 1000, TICK

wait
end

'#########################
SER2RX:
'#########################
count=count+1
toggle=1-toggle
'pause 1
serial2.read_iobuff(toggle)
size = iobuff.len(toggle)
' use only  each second incomming frame (toggle =0),
' but only the engineering frames with size=45
if (toggle=0) and (size = 45) then
  TState       =iobuff.read(0,8)
  MT_Dis1      =iobuff.read(0,9)
  MT_Dis2      =iobuff.read(0,10)
  ETE_val      =iobuff.read(0,11)
  STDIS_val1   =iobuff.read(0,12)
  STDis_val2   =iobuff.read(0,13)
  STE_val      =iobuff.read(0,14)
  Det_Dis1     =iobuff.read(0,15)
  Det_Dis2     =iobuff.read(0,16)
  MMD_gate     =iobuff.read(0,17)
  MSD_gate     =iobuff.read(0,18)
  
  moving_range0=iobuff.read(0,19)
  moving_range1=iobuff.read(0,20)
  moving_range2=iobuff.read(0,21)
  moving_range3=iobuff.read(0,22)
  moving_range4=iobuff.read(0,23)
  moving_range5=iobuff.read(0,24)
  moving_range6=iobuff.read(0,25)
  moving_range7=iobuff.read(0,26)
  moving_range8=iobuff.read(0,27)
  
  static_range0=iobuff.read(0,28)
  static_range1=iobuff.read(0,29)
  static_range2=iobuff.read(0,30)
  static_range3=iobuff.read(0,31)
  static_range4=iobuff.read(0,32)
  static_range5=iobuff.read(0,33)
  static_range6=iobuff.read(0,34)
  static_range7=iobuff.read(0,35)
  static_range8=iobuff.read(0,36)
  
  'Tstate regards the actual (default?) energy limits, 
  ' for each distance gate and for the maned time
  SELECT CASE TState 
    CASE 0
      Target_state$ = "No target detected"
      moving_LED = 1 'green
      static_LED = 1 'green
    CASE 1
      Target_state$ = "Moving target detected"
      moving_LED = 0 'red
      static_LED = 1 'green
    CASE 2
      Target_state$ = "Static target detected"
      moving_LED = 1 'green
      static_LED = 0 'red
    CASE 3
      Target_state$ = "Moving+static target detected"
      moving_LED = 0 'red
      static_LED = 0 'red
  END SELECT
endif
return

'#########################
WEBPAGE:
'#########################
A$ = ""
A$ = A$ + "<H3>LD2410 radar-sensor visualizer v" + Version$ +"</H3>"
A$ = A$ + textbox$(T$) + "<br>" 
A$ = A$ + textbox$(Target_state$) + " m:" + LED$(moving_LED) + " s:" + LED$(static_LED)+ "<br><br>"
A$ = A$ + "Targets energy in distance ranges: <br>"
A$ = A$ + "_________________<u>moving</u>_____<u>static+breathing</u><br>"
'A$ = A$ + " 0: 0.00m - 0.75m _ "+ meter$(moving_range0,0,100)+ " _ " + meter$(static_range0,0,100)+"<br>"
'A$ = A$ + " 1: 0.75m - 1.50m _ "+ meter$(moving_range1,0,100)+ " _ " + meter$(static_range1,0,100)+"<br>"
A$ = A$ + " 0: 0.00m - 0.75m _ "+ meter$(moving_range0,0,100)+ "<br>"
A$ = A$ + " 1: 0.75m - 1.50m _ "+ meter$(moving_range1,0,100)+ "<br>"
A$ = A$ + " 2: 1.50m - 2.25m _ "+ meter$(moving_range2,0,100)+ " _ " + meter$(static_range2,0,100)+"<br>"
A$ = A$ + " 3: 2.25m - 3.00m _ "+ meter$(moving_range3,0,100)+ " _ " + meter$(static_range3,0,100)+"<br>"
A$ = A$ + " 4: 3.00m - 3.75m _ "+ meter$(moving_range4,0,100)+ " _ " + meter$(static_range4,0,100)+"<br>"
A$ = A$ + " 5: 3.75m - 4.50m _ "+ meter$(moving_range5,0,100)+ " _ " + meter$(static_range5,0,100)+"<br>"
A$ = A$ + " 6: 4.50m - 5.25m _ "+ meter$(moving_range6,0,100)+ " _ " + meter$(static_range6,0,100)+"<br>"
A$ = A$ + " 7: 5.25m - 6.00m _ "+ meter$(moving_range7,0,100)+ " _ " + meter$(static_range7,0,100)+"<br>"
A$ = A$ + " 7: 6.00m - 6.75m _ "+ meter$(moving_range8,0,100)+ " _ " + meter$(static_range8,0,100)+"<br>"

cls
autorefresh 250
html A$
return

'#########################
TICK:
'#########################
t$=time$
RADAR$=IObuff.ToHex$(0)
'wlog t$, count ,RADAR$
wlog t$, count, Tstate
count=0
return


'#########################
SETUP_LD2410_RADAR:
'#########################
serial2.mode 256000,RX_pin,TX_pin

Enable_config$           ="fdfcfbfa0400ff00010004030201"
Enable_engineering_mode$ ="fdfcfbfa0200620004030201"
End_config$              ="fdfcfbfa0200fe0004030201"
'movement: 8 gates; static: 8 gates; unmaned duration: 5s
Default1$                ="fdfcfbfa1400600000000800000001000800000002000500000004030201"

IObuff.FromHex(1, Enable_config$)
SERIAL2.WRITE_IOBUFF(1)
pause 100
IObuff.FromHex(1, Enable_engineering_mode$)
SERIAL2.WRITE_IOBUFF(1)
pause 100
IObuff.FromHex(1, Default1$)
SERIAL2.WRITE_IOBUFF(1)
pause 100
IObuff.FromHex(1, End_config$)
SERIAL2.WRITE_IOBUFF(1)
pause 100
return

Next things to do:

  • set the detection sensitivity on the different distance range gates
  • enable a Telegram Bot based messaging if a person is detected in selectable range
  • use the Neopixel-LEDs of the ATOM matrix to visualize the detected radar signal
  • The module is Bluetooth/BLE capable. This could be investigated as an alternative link to the ESP32.

MANUALS of the LD2410B:

I attached the two English PDF manuals for the LD2410B here …

HLK LD2410B Human Presence Sensing Module Manual V104.pdf

HLK-LD2410B Serial communication protocol V104.pdf


#

##

###

####

#####

######

#######

########

#########

##########

#########

########


#######

######

#####

####

##

#

Advertisement
%d bloggers like this: