Unlike IR or ultrasonic based presence detection modules, this module is able to detect moving targets (people) as well as non-moving, standing people.
It 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.
But even more interesting is that the sensor can be a serial connected peripheral hardware to an ANNEX32 capable ESP32
I wrote a first test code 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.
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.
Next things to do:
- set the detection sensitivity on the different distance range gates
- use the Neopixel-LEDs of the ATOM matrix to visualize the detected radar signal
- enable a Telegram Bot based messaging if a person is detected in selectable range
I will report on further experiments as soon as possible.
The simple schematic diagram:
The pinout of the module:
My simple interface:
The code:
Code: [Local Link Removed for Guests]
' 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
Vertical mounting example:
Horizontal mounting example: