LD2410Async
Asynchronous Arduino ESP32 library for the LD2410 mmWave radar sensor
Loading...
Searching...
No Matches
simplePresenceDetectionWebservice.ino
Go to the documentation of this file.
1/**
2 * @brief Example: Webservice for Presence Detection with LD2410Async and ESP Async WebServer
3 *
4 * @details
5 * This example demonstrates how to use the LD2410Async library with an ESP32 to provide a web-based
6 * presence detection service. The ESP32 connects to a WiFi network, starts a web server, and serves
7 * a simple HTML page. The page connects via WebSocket to receive live presence detection data
8 * (presenceDetected, detectedDistance) from the LD2410 radar sensor.
9 *
10 *
11 * Dependencies:
12 * - ESPAsyncWebServer: https://github.com/me-no-dev/ESPAsyncWebServer
13 * - AsyncTCP: https://github.com/me-no-dev/AsyncTCP
14 * - LD2410Async library
15 *
16 * @warning
17 * Make sure to install the required libraries and adjust the configuration section below
18 * to match your hardware and network setup.
19 */
20
21#include <Arduino.h>
22#include <WiFi.h>
23#include <ESPAsyncWebServer.h>
24#include "LD2410Async.h"
25
26 // ========================= USER CONFIGURATION =========================
27
28 /**
29 * @name UART Configuration
30 * @{
31 */
32#define RADAR_RX_PIN 16 ///< ESP32 pin that receives data from the radar (radar TX)
33#define RADAR_TX_PIN 17 ///< ESP32 pin that transmits data to the radar (radar RX)
34#define RADAR_BAUDRATE 256000 ///< UART baudrate for the radar sensor (default is 256000)
35 /** @} */
36
37 /**
38 * @name WiFi Configuration
39 * @{
40 */
41const char* WIFI_SSID = "YOUR_WIFI_SSID"; ///< WiFi SSID
42const char* WIFI_PASSWORD = "YOUR_WIFI_PASSWORD"; ///< WiFi password
43
44// Set to true to use static IP, false for DHCP
45#define USE_STATIC_IP true
46
47// Static network configuration (only used if USE_STATIC_IP is true)
48IPAddress LOCAL_IP(192, 168, 1, 123); ///< ESP32 static IP address
49IPAddress GATEWAY(192, 168, 1, 1); ///< Network gateway
50IPAddress SUBNET(255, 255, 255, 0); ///< Network subnet mask
51/** @} */
52
53/**
54 * @name Webserver Configuration
55 * @{
56 */
57#define WEBSERVER_PORT 80 ///< HTTP/WebSocket server port
58 /** @} */
59
60 // ======================================================================
61
62 /**
63 * @brief HardwareSerial instance for UART1 (LD2410 sensor)
64 */
65HardwareSerial RadarSerial(1);
66
67/**
68 * @brief LD2410Async instance for radar communication
69 */
71
72/**
73 * @brief AsyncWebServer instance for HTTP/WebSocket
74 */
75AsyncWebServer server(WEBSERVER_PORT);
76
77/**
78 * @brief AsyncWebSocket instance for live data updates
79 */
80AsyncWebSocket ws("/ws");
81
82/**
83 * @brief Stores the latest presence detection state
84 */
85volatile bool latestPresenceDetected = false;
86
87/**
88 * @brief Stores the latest detected distance (cm)
89 */
90volatile uint16_t latestDetectedDistance = 0;
91
92/**
93 * @brief Notifies all connected WebSocket clients with the latest presence data.
94 *
95 * Sends a JSON string with the fields "presenceDetected" (bool) and "detectedDistance" (uint16_t).
96 */
98 String msg = "{\"presenceDetected\":";
99 msg += (latestPresenceDetected ? "true" : "false");
100 msg += ",\"detectedDistance\":";
102 msg += "}";
103 ws.textAll(msg);
104}
105
106/**
107 * @brief Callback function called whenever new detection data arrives from the radar.
108 *
109 * @param sender Pointer to the LD2410Async instance (for multi-sensor setups)
110 * @param presenceDetected True if presence is detected, false otherwise
111 */
118
119/**
120 * @brief Handles WebSocket events (client connect/disconnect).
121 *
122 * @param server Pointer to the AsyncWebSocket server
123 * @param client Pointer to the connected client
124 * @param type Event type (connect, disconnect, etc.)
125 * @param arg Event argument
126 * @param data Event data
127 * @param len Data length
128 */
129void onWsEvent(AsyncWebSocket* server, AsyncWebSocketClient* client, AwsEventType type,
130 void* arg, uint8_t* data, size_t len) {
131 if (type == WS_EVT_CONNECT) {
132 Serial.printf("WebSocket client #%u connected\n", client->id());
133 // Send initial state
135 }
136 else if (type == WS_EVT_DISCONNECT) {
137 Serial.printf("WebSocket client #%u disconnected\n", client->id());
138 }
139}
140
141/**
142 * @brief HTML page served to clients.
143 *
144 * Connects to the WebSocket and displays live presence and distance data.
145 */
146const char index_html[] PROGMEM = R"rawliteral(
147<!DOCTYPE html>
148<html>
149<head>
150 <meta charset="UTF-8">
151 <title>LD2410 Presence Detection</title>
152 <style>
153 body { font-family: Arial, sans-serif; margin: 2em; }
154 .status { font-size: 2em; margin-bottom: 1em; }
155 .distance { font-size: 1.5em; }
156 .present { color: green; }
157 .absent { color: red; }
158 </style>
159</head>
160<body>
161 <h2>LD2410 Presence Detection</h2>
162 <div class="status" id="presence">Connecting...</div>
163 <div class="distance" id="distance"></div>
164 <script>
165 let ws = new WebSocket('ws://' + location.host + '/ws');
166 ws.onmessage = function(event) {
167 let data = JSON.parse(event.data);
168 let presence = document.getElementById('presence');
169 let distance = document.getElementById('distance');
170 if (data.presenceDetected) {
171 presence.textContent = "Presence detected!";
172 presence.className = "status present";
173 distance.textContent = "Distance: " + data.detectedDistance + " cm";
174 } else {
175 presence.textContent = "No presence detected.";
176 presence.className = "status absent";
177 distance.textContent = "";
178 }
179 };
180 ws.onopen = function() {
181 document.getElementById('presence').textContent = "Waiting for data...";
182 };
183 ws.onclose = function() {
184 document.getElementById('presence').textContent = "WebSocket disconnected.";
185 document.getElementById('presence').className = "status";
186 };
187 </script>
188</body>
189</html>
190)rawliteral";
191
192/**
193 * @brief Connects to WiFi using the user configuration.
194 *
195 * If USE_STATIC_IP is true, configures a static IP, subnet, and gateway.
196 * Prints connection status and IP address to Serial.
197 */
198void setupWiFi() {
199 Serial.print("Connecting to WiFi: ");
200 Serial.println(WIFI_SSID);
201 WiFi.mode(WIFI_STA);
202#if USE_STATIC_IP
203 if (!WiFi.config(LOCAL_IP, GATEWAY, SUBNET)) {
204 Serial.println("STA Failed to configure static IP");
205 }
206#endif
207 WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
208 int retries = 0;
209 while (WiFi.status() != WL_CONNECTED) {
210 delay(500);
211 Serial.print(".");
212 if (++retries > 40) { // 20 seconds timeout
213 Serial.println("\nFailed to connect to WiFi!");
214 return;
215 }
216 }
217 Serial.println("\nWiFi connected.");
218 Serial.print("IP address: ");
219 Serial.println(WiFi.localIP());
220}
221
222/**
223 * @brief Arduino setup function.
224 *
225 * Initializes serial, WiFi, radar sensor, and webserver.
226 * Registers the detection data callback and sets up the WebSocket and HTTP handlers.
227 */
228void setup() {
229 // Serial for debug output
230 Serial.begin(115200);
231 while (!Serial) { ; }
232 Serial.println("LD2410Async Web Presence Detection Example");
233
234 // Setup WiFi
235 setupWiFi();
236
237 // Start UART for radar
239
240 // Start radar background task
241 if (radar.begin()) {
242 Serial.println("Radar task started successfully.");
244 }
245 else {
246 Serial.println("ERROR! Could not start radar task.");
247 }
248
249 // WebSocket setup
250 ws.onEvent(onWsEvent);
251 server.addHandler(&ws);
252
253 // Serve HTML page at "/"
254 server.on("/", HTTP_GET, [](AsyncWebServerRequest* request) {
255 request->send_P(200, "text/html", index_html);
256 });
257
258 // Start server
259 server.begin();
260 Serial.println("Webserver started.");
261}
262
263/**
264 * @brief Arduino loop function.
265 *
266 * No code required; all logic is handled by callbacks and background tasks.
267 */
268void loop() {
269 // Nothing to do here, everything is handled by callbacks and background tasks
270}
Asynchronous driver class for the LD2410 human presence radar sensor.
Definition LD2410Async.h:38
bool begin()
Starts the background task that continuously reads data from the sensor.
void onDetectionDataReceived(DetectionDataCallback callback)
Registers a callback for new detection data.
const LD2410Types::DetectionData & getDetectionDataRef() const
Access the current detection data without making a copy.
IPAddress SUBNET(255, 255, 255, 0)
Network subnet mask.
AsyncWebServer server(WEBSERVER_PORT)
AsyncWebServer instance for HTTP/WebSocket.
AsyncWebSocket ws("/ws")
AsyncWebSocket instance for live data updates.
const char * WIFI_PASSWORD
WiFi password.
IPAddress GATEWAY(192, 168, 1, 1)
Network gateway.
HardwareSerial RadarSerial(1)
HardwareSerial instance for UART1 (LD2410 sensor)
void setup()
Arduino setup function.
const char * WIFI_SSID
WiFi SSID.
IPAddress LOCAL_IP(192, 168, 1, 123)
ESP32 static IP address.
void onDetectionDataReceived(LD2410Async *sender, bool presenceDetected)
Callback function called whenever new detection data arrives from the radar.
LD2410Async radar(RadarSerial)
LD2410Async instance for radar communication.
void onWsEvent(AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventType type, void *arg, uint8_t *data, size_t len)
Handles WebSocket events (client connect/disconnect).
const char index_html[] PROGMEM
HTML page served to clients.
#define RADAR_BAUDRATE
UART baudrate for the radar sensor (default is 256000)
#define RADAR_RX_PIN
ESP32 pin that receives data from the radar (radar TX)
#define WEBSERVER_PORT
HTTP/WebSocket server port.
volatile bool latestPresenceDetected
Stores the latest presence detection state.
#define RADAR_TX_PIN
ESP32 pin that transmits data to the radar (radar RX)
void setupWiFi()
Connects to WiFi using the user configuration.
volatile uint16_t latestDetectedDistance
Stores the latest detected distance (cm)
void loop()
Arduino loop function.
void notifyClients()
Notifies all connected WebSocket clients with the latest presence data.
Holds the most recent detection data reported by the radar.
unsigned int detectedDistance
General detection distance (cm).
bool presenceDetected
True if any target is detected.