Arduino_Sensor_Nodes/sketch_nov29c/sketch_nov29c.ino

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);
}