305 lines
8.4 KiB
C++
305 lines
8.4 KiB
C++
|
|
#ifndef ZIGBEE_MODE_ED
|
|
#error "Zigbee end device mode is not selected in Tools->Zigbee mode"
|
|
#endif
|
|
|
|
#include "Zigbee.h"
|
|
|
|
/* Zigbee occupancy sensor configuration */
|
|
#define OCCUPANCY_SENSOR_ENDPOINT_NUMBER 10
|
|
uint8_t button = BOOT_PIN;
|
|
uint8_t sensor_pin = 4;
|
|
|
|
ZigbeeOccupancySensor zbOccupancySensor = ZigbeeOccupancySensor(OCCUPANCY_SENSOR_ENDPOINT_NUMBER);
|
|
|
|
|
|
|
|
#include "DFRobot_C4001.h"
|
|
|
|
HardwareSerial RadarSerial(1);
|
|
DFRobot_C4001_UART radar(&RadarSerial, 9600, /*rx*/17, /*tx*/16); // ESP32-C6 pins
|
|
|
|
eMode_t currentMode = eExitMode; // 0=presence, 1=speed
|
|
unsigned long lastSpeedReport = 0;
|
|
bool lastOccupancy = false;
|
|
unsigned long occupancyStartTime = 0;
|
|
const unsigned long OCCUPANCY_TIMEOUT = 4; // 4 -> 2 seconds - adjust as needed
|
|
const unsigned long TRIGGER_DELAY = 10 // 10 -> 100 ms
|
|
|
|
|
|
void setPresenceMode() {
|
|
radar.setSensorMode(eExitMode);
|
|
currentMode = eExitMode;
|
|
Serial.println("Switched to PRESENCE mode");
|
|
// Presence mode settings from sample
|
|
// radar.setDetectionRange(30, 1000, 1000); // min,max,trig (cm)
|
|
// radar.setTrigSensitivity(1);
|
|
// radar.setKeepSensitivity(2);
|
|
// radar.setDelay(100, 4); // trig,keep
|
|
|
|
|
|
|
|
|
|
|
|
|
|
sSensorStatus_t data;
|
|
data = radar.getStatus();
|
|
// 0 stop 1 start
|
|
Serial.print("work status = ");
|
|
Serial.println(data.workStatus);
|
|
|
|
// 0 is exist 1 speed
|
|
Serial.print("work mode = ");
|
|
Serial.println(data.workMode);
|
|
|
|
// 0 no init 1 init success
|
|
Serial.print("init status = ");
|
|
Serial.println(data.initStatus);
|
|
Serial.println();
|
|
|
|
/*
|
|
* min Detection range Minimum distance, unit cm, range 0.3~25m (30~2500), not exceeding max, otherwise the function is abnormal.
|
|
* max Detection range Maximum distance, unit cm, range 2.4~25m (240~2500)
|
|
* trig Detection range Maximum distance, unit cm, default trig = max
|
|
*/
|
|
if(radar.setDetectionRange(/*min*/30, /*max*/1000, /*trig*/1000)){
|
|
Serial.println("set detection range successfully!");
|
|
}
|
|
// set trigger sensitivity 0 - 9
|
|
if(radar.setTrigSensitivity(1)){
|
|
Serial.println("set trig sensitivity successfully!");
|
|
}
|
|
|
|
// set keep sensitivity 0 - 9
|
|
if(radar.setKeepSensitivity(2)){
|
|
Serial.println("set keep sensitivity successfully!");
|
|
}
|
|
/*
|
|
* trig Trigger delay, unit 0.01s, range 0~2s (0~200)
|
|
* keep Maintain the detection timeout, unit 0.5s, range 2~1500 seconds (4~3000)
|
|
*/
|
|
if(radar.setDelay(/*trig*/TRIGGER_DELAY, /*keep*/OCCUPANCY_TIMEOUT)){
|
|
Serial.println("set delay successfully!");
|
|
}
|
|
|
|
|
|
// get confige params
|
|
Serial.print("trig sensitivity = ");
|
|
Serial.println(radar.getTrigSensitivity());
|
|
Serial.print("keep sensitivity = ");
|
|
Serial.println(radar.getKeepSensitivity());
|
|
|
|
Serial.print("min range = ");
|
|
Serial.println(radar.getMinRange());
|
|
Serial.print("max range = ");
|
|
Serial.println(radar.getMaxRange());
|
|
Serial.print("trig range = ");
|
|
Serial.println(radar.getTrigRange());
|
|
|
|
Serial.print("keep time = ");
|
|
Serial.println(radar.getKeepTimerout());
|
|
|
|
Serial.print("trig delay = ");
|
|
Serial.println(radar.getTrigDelay());
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void setSpeedMode() {
|
|
radar.setSensorMode(eSpeedMode);
|
|
currentMode = eSpeedMode;
|
|
Serial.println("Switched to SPEED mode");
|
|
// Speed mode settings from sample
|
|
// radar.setDetectThres(11, 1200, 10); // min,max,thres (cm)
|
|
// radar.setFrettingDetection(eON);
|
|
|
|
|
|
|
|
|
|
sSensorStatus_t data;
|
|
data = radar.getStatus();
|
|
// 0 stop 1 start
|
|
Serial.print("work status = ");
|
|
Serial.println(data.workStatus);
|
|
|
|
// 0 is exist 1 speed
|
|
Serial.print("work mode = ");
|
|
Serial.println(data.workMode);
|
|
|
|
// 0 no init 1 init success
|
|
Serial.print("init status = ");
|
|
Serial.println(data.initStatus);
|
|
Serial.println();
|
|
|
|
/*
|
|
* min Detection range Minimum distance, unit cm, range 0.3~20m (30~2500), not exceeding max, otherwise the function is abnormal.
|
|
* max Detection range Maximum distance, unit cm, range 2.4~20m (240~2500)
|
|
* thres Target detection threshold, dimensionless unit 0.1, range 0~6553.5 (0~65535)
|
|
*/
|
|
if (radar.setDetectThres(/*min*/ 11, /*max*/ 1200, /*thres*/ 10)) {
|
|
Serial.println("set detect threshold successfully");
|
|
}
|
|
|
|
// set Fretting Detection
|
|
radar.setFrettingDetection(eON);
|
|
|
|
// get confige params
|
|
Serial.print("min range = ");
|
|
Serial.println(radar.getTMinRange());
|
|
Serial.print("max range = ");
|
|
Serial.println(radar.getTMaxRange());
|
|
Serial.print("threshold range = ");
|
|
Serial.println(radar.getThresRange());
|
|
Serial.print("fretting detection = ");
|
|
Serial.println(radar.getFrettingDetection());
|
|
|
|
}
|
|
|
|
|
|
|
|
void handleSerialCommands() {
|
|
while (Serial.available()) {
|
|
char cmd = Serial.read();
|
|
if (cmd == 'P' || cmd == 'p') {
|
|
setPresenceMode();
|
|
} else if (cmd == 'S' || cmd == 's') {
|
|
setSpeedMode();
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
void setup() {
|
|
Serial.begin(115200);
|
|
while (!Serial);
|
|
|
|
RadarSerial.begin(9600, SERIAL_8N1, 17, 16); // C4001 UART (RX=16, TX=17)
|
|
|
|
while (!radar.begin()) {
|
|
Serial.println("NO Device found!");
|
|
delay(1000);
|
|
}
|
|
Serial.println("C4001 connected!");
|
|
|
|
// Start in presence mode
|
|
setPresenceMode();
|
|
Serial.println("Send 'P' for presence, 'S' for speed mode");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Optional: set Zigbee device name and model
|
|
zbOccupancySensor.setManufacturerAndModel("Espressif", "ZigbeeOccupancyPIRSensor_Node17");
|
|
|
|
// Add endpoint to Zigbee Core
|
|
Zigbee.addEndpoint(&zbOccupancySensor);
|
|
|
|
Serial.println("Starting Zigbee...");
|
|
// When all EPs are registered, start Zigbee in End Device mode
|
|
if (!Zigbee.begin()) {
|
|
Serial.println("Zigbee failed to start!");
|
|
Serial.println("Rebooting...");
|
|
ESP.restart();
|
|
} else {
|
|
Serial.println("Zigbee started successfully!");
|
|
}
|
|
Serial.println("Connecting to network");
|
|
while (!Zigbee.connected()) {
|
|
Serial.print(".");
|
|
delay(100);
|
|
}
|
|
Serial.println();
|
|
|
|
}
|
|
|
|
void loop() {
|
|
handleSerialCommands();
|
|
|
|
// // Remove if (radar.available()) - just read directly
|
|
// sSensorStatus_t status = radar.getStatus(); // Always safe to call
|
|
|
|
// Serial.print("Status: work=");
|
|
// Serial.print(status.workStatus);
|
|
// Serial.print(", mode=");
|
|
// Serial.print(status.workMode);
|
|
// Serial.print(", init=");
|
|
// Serial.println(status.initStatus);
|
|
|
|
|
|
if (currentMode == eExitMode) {
|
|
// PRESENCE MODE
|
|
// static bool occupancy = false;
|
|
// bool occupancyNow = radar.motionDetection();
|
|
// Serial.println(occupancyNow);
|
|
// // if (radar.motionDetection() == 1 && !occupancy) {
|
|
// if (occupancyNow != lastOccupancy) {
|
|
// Serial.println("MOTION DETECTED");
|
|
// zbOccupancySensor.setOccupancy(occupancyNow);
|
|
// zbOccupancySensor.report();
|
|
// // occupancy = true;
|
|
// lastOccupancy = occupancyNow;
|
|
// // } else if (radar.motionDetection() == 0 && occupancy) {
|
|
// // } else if (radar.motionDetection() == 0) {
|
|
// // Serial.println("MOTION ENDED");
|
|
// // zbOccupancySensor.setOccupancy(false);
|
|
// // zbOccupancySensor.report();
|
|
// // occupancy = false;
|
|
// }
|
|
// PRESENCE MODE - proper state machine
|
|
bool motionNow = radar.motionDetection();
|
|
Serial.println(motionNow);
|
|
Serial.println(lastOccupancy);
|
|
Serial.println(millis() - occupancyStartTime);
|
|
|
|
if (motionNow && !lastOccupancy) {
|
|
// Motion STARTED → Set occupancy ON
|
|
Serial.println("MOTION DETECTED → OCCUPANCY ON");
|
|
lastOccupancy = true;
|
|
occupancyStartTime = millis();
|
|
zbOccupancySensor.setOccupancy(true);
|
|
zbOccupancySensor.report();
|
|
|
|
} else if (motionNow && lastOccupancy) {
|
|
// Motion ENDED → Start timeout timer
|
|
Serial.println("Motion still present → timeout reset");
|
|
occupancyStartTime = millis();
|
|
|
|
} else if (!motionNow && lastOccupancy && (millis() - occupancyStartTime > OCCUPANCY_TIMEOUT*1000/2)) {
|
|
// TIMEOUT → Clear occupancy
|
|
Serial.println("OCCUPANCY TIMEOUT → OFF");
|
|
lastOccupancy = false;
|
|
zbOccupancySensor.setOccupancy(false);
|
|
zbOccupancySensor.report();
|
|
|
|
} else if (!motionNow && lastOccupancy) {
|
|
// Motion ENDED → Start timeout timer
|
|
Serial.println("Motion ended → timeout started");
|
|
// occupancyStartTime = millis();
|
|
}
|
|
|
|
|
|
|
|
} else if (currentMode == eSpeedMode) {
|
|
// SPEED MODE
|
|
Serial.print("Targets: ");
|
|
Serial.print(radar.getTargetNumber());
|
|
Serial.print(" | Speed: ");
|
|
Serial.print(radar.getTargetSpeed(), 2);
|
|
Serial.print(" m/s | Range: ");
|
|
Serial.print(radar.getTargetRange(), 2);
|
|
Serial.print(" m | Energy: ");
|
|
Serial.println(radar.getTargetEnergy());
|
|
}
|
|
|
|
delay(100);
|
|
}
|