Two people right beside eachother might still be read as 1. If they’re behind eachother especially. So I wouldn’t hold my breath for that one.
Still definitely better than regular motion detectors!
Two people right beside eachother might still be read as 1. If they’re behind eachother especially. So I wouldn’t hold my breath for that one.
Still definitely better than regular motion detectors!
So I wouldn’t hold my breath for that one.
In that case it would stop detecting anyway
Yeah… I wouldn’t expect it to be perfectly accurate. I’m imagining that on the ceiling would provide the most accuracy in most rooms — if it can figure out “people” in that configuration.
Thanks for the update and the link to the working implementation. It works well.
Could you please tell us a bit about how to set the sensor’s sensitivity?
TIA.
Here’s how to do checksums & send messages to the three boards. They all use the same checksum codes / algorithm and these commands should work on the human presence sensor, the fall detection and the 24ghz sleep one.
Example of how you can set up the serial connection if you set it up in C:
(9600/8N1 is standard for serial).
HardwareSerial hardwareSerial(1);
void setup() {
hardwareSerial.begin(9600, SERIAL_8N1, 27, 26);
while (!hardwareSerial) { //optional depending on use case
delay(10); // wait till serial port opens
}
delay(2000);
send_write_SystemParameter_ThresholdGear_3();
}
But in ESP home there is an easy way it seems UART Bus — ESPHome. You would define your uart and have a customer UARTComponent as described here Custom UART Device — ESPHome. Then you can replace the hardwareSerial.write(dataWithChecksum[n]);
line inside of sendMessage
with just write(dataWithChecksum[n])
using the arduino API as shown in the second link.
uart:
id: uart_bus
tx_pin: GPIO16 #or other. D26, etc.
rx_pin: GPIO17 #or other. D27, etc.
baud_rate: 9600
custom_component:
- lambda: |-
auto my_custom = new MyCustomComponent(id(uart_bus));
return {my_custom};
The setting transmission & checksum code:
const unsigned char cuc_CRCHi[256] = {
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40
};
const unsigned char cuc_CRCLo[256]= {
0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06, 0x07, 0xC7,
0x05, 0xC5, 0xC4, 0x04, 0xCC, 0x0C, 0x0D, 0xCD, 0x0F, 0xCF, 0xCE, 0x0E,
0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09, 0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9,
0x1B, 0xDB, 0xDA, 0x1A, 0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC,
0x14, 0xD4, 0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3,
0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3, 0xF2, 0x32,
0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4, 0x3C, 0xFC, 0xFD, 0x3D,
0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A, 0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38,
0x28, 0xE8, 0xE9, 0x29, 0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF,
0x2D, 0xED, 0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26,
0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60, 0x61, 0xA1,
0x63, 0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67, 0xA5, 0x65, 0x64, 0xA4,
0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F, 0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB,
0x69, 0xA9, 0xA8, 0x68, 0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA,
0xBE, 0x7E, 0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5,
0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71, 0x70, 0xB0,
0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92, 0x96, 0x56, 0x57, 0x97,
0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C, 0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E,
0x5A, 0x9A, 0x9B, 0x5B, 0x99, 0x59, 0x58, 0x98, 0x88, 0x48, 0x49, 0x89,
0x4B, 0x8B, 0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C,
0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42, 0x43, 0x83,
0x41, 0x81, 0x80, 0x40
};
unsigned short int us_CalculateCrc16(unsigned char *lpuc_Frame, unsigned short int lus_Len){
unsigned char luc_CRCHi = 0xFF;
unsigned char luc_CRCLo = 0xFF;
int li_Index=0;
while(lus_Len--){
li_Index = luc_CRCLo ^ *( lpuc_Frame++);
luc_CRCLo = (unsigned char)( luc_CRCHi ^ cuc_CRCHi[li_Index]);
luc_CRCHi = cuc_CRCLo[li_Index];
}
return (unsigned short int )(luc_CRCLo << 8 | luc_CRCHi);
}
char CRC(char ad1, char ad2, char ad3, char ad4, char ad5, char ad6, char ad7){
unsigned char data[] = {ad1, ad2, ad3, ad4, ad5, ad6, ad7};
unsigned short int crc_data = 0x0000;
unsigned int lenth = sizeof(data)/sizeof(unsigned char);
crc_data = us_CalculateCrc16(data, lenth);
return crc_data;
}
void sendMessage(unsigned char partialData[], int length)
{
length += 3;
unsigned char data[length];
unsigned char dataWithChecksum[length + 2];
data[0] = 0x55;
data[1] = length + 1; //
data[2] = 0x00;
for (int n = 0; n < length - 3; n++)data[n + 3] = partialData[n];
for (int n = 0; n < length; n++)dataWithChecksum[n] = data[n];
unsigned short int crc_data = us_CalculateCrc16(data, length);
dataWithChecksum[length] = (crc_data & 0xff00) >> 8;
dataWithChecksum[length+1] = crc_data & 0xff;
for (int n = 0; n < length + 2; n++){
hardwareSerial.write(dataWithChecksum[n]);
}
}
unsigned char read_RadarInfo_EnvironmentalStatus[3] = {0x01, 0x03, 0x05};
unsigned char read_RadarInfo_MotorSigns[3] = {0x01, 0x03, 0x06};
unsigned char read_SystemParameter_ThresholdGear[3] = {0x01, 0x04, 0x0C}; //tested
unsigned char read_SystemParameter_SceneSetting[3] = {0x01, 0x04, 0x10};
unsigned char write_SystemParameter_ThresholdGear_1[4] = {0x02, 0x04, 0x0C, 0x01}; //least sensitive
unsigned char write_SystemParameter_ThresholdGear_2[4] = {0x02, 0x04, 0x0C, 0x02};
unsigned char write_SystemParameter_ThresholdGear_3[4] = {0x02, 0x04, 0x0C, 0x03};
unsigned char write_SystemParameter_ThresholdGear_4[4] = {0x02, 0x04, 0x0C, 0x04};
unsigned char write_SystemParameter_ThresholdGear_5[4] = {0x02, 0x04, 0x0C, 0x05};
unsigned char write_SystemParameter_ThresholdGear_6[4] = {0x02, 0x04, 0x0C, 0x06};
unsigned char write_SystemParameter_ThresholdGear_7[4] = {0x02, 0x04, 0x0C, 0x07}; //default
unsigned char write_SystemParameter_ThresholdGear_8[4] = {0x02, 0x04, 0x0C, 0x08};
unsigned char write_SystemParameter_ThresholdGear_9[4] = {0x02, 0x04, 0x0C, 0x09};
unsigned char write_SystemParameter_ThresholdGear_10[4] = {0x02, 0x04, 0x0C, 0x0A}; //most sensitive
unsigned char write_SystemParameter_SceneSetting_Default[4] = {0x02, 0x04, 0x10, 0x00}; //roughly a distance setting?
unsigned char write_SystemParameter_SceneSetting_AreaTopLoading[4] = {0x02, 0x04, 0x10, 0x01};
unsigned char write_SystemParameter_SceneSetting_BathroomTopMounted[4] = {0x02, 0x04, 0x10, 0x02};
unsigned char write_SystemParameter_SceneSetting_BathroomTopLoading[4] = {0x02, 0x04, 0x10, 0x03};
unsigned char write_SystemParameter_SceneSetting_LivingTopMounted[4] = {0x02, 0x04, 0x10, 0x04};
unsigned char write_SystemParameter_SceneSetting_OfficeTopLoading[4] = {0x02, 0x04, 0x10, 0x05};
unsigned char write_SystemParameter_SceneSetting_HotelTopLoading[4] = {0x02, 0x04, 0x10, 0x06}; //hotel is the largest?
void send_read_RadarInfo_EnvironmentalStatus() { sendMessage(read_RadarInfo_EnvironmentalStatus, 3); };
void send_read_RadarInfo_MotorSigns() { sendMessage(read_RadarInfo_MotorSigns, 3); };
void send_read_SystemParameter_ThresholdGear() { sendMessage(read_SystemParameter_ThresholdGear, 3); };
void send_read_SystemParameter_SceneSetting() { sendMessage(read_SystemParameter_SceneSetting, 3); };
void send_write_SystemParameter_ThresholdGear_1() { sendMessage(write_SystemParameter_ThresholdGear_1, 4); };
void send_write_SystemParameter_ThresholdGear_2() { sendMessage(write_SystemParameter_ThresholdGear_2, 4); };
void send_write_SystemParameter_ThresholdGear_3() { sendMessage(write_SystemParameter_ThresholdGear_3, 4); };
void send_write_SystemParameter_ThresholdGear_4() { sendMessage(write_SystemParameter_ThresholdGear_4, 4); };
void send_write_SystemParameter_ThresholdGear_5() { sendMessage(write_SystemParameter_ThresholdGear_5, 4); };
void send_write_SystemParameter_ThresholdGear_6() { sendMessage(write_SystemParameter_ThresholdGear_6, 4); };
void send_write_SystemParameter_ThresholdGear_7() { sendMessage(write_SystemParameter_ThresholdGear_7, 4); };
void send_write_SystemParameter_ThresholdGear_8() { sendMessage(write_SystemParameter_ThresholdGear_8, 4); };
void send_write_SystemParameter_ThresholdGear_9() { sendMessage(write_SystemParameter_ThresholdGear_9, 4); };
void send_write_SystemParameter_ThresholdGear_10() { sendMessage(write_SystemParameter_ThresholdGear_10, 4); };
void send_write_SystemParameter_SceneSetting_Default() { sendMessage(write_SystemParameter_SceneSetting_Default, 4); };
void send_write_SystemParameter_SceneSetting_AreaTopLoading() { sendMessage(write_SystemParameter_SceneSetting_AreaTopLoading, 4); };
void send_write_SystemParameter_SceneSetting_BathroomTopMounted() { sendMessage(write_SystemParameter_SceneSetting_BathroomTopMounted, 4); };
void send_write_SystemParameter_SceneSetting_BathroomTopLoading() { sendMessage(write_SystemParameter_SceneSetting_BathroomTopLoading, 4); };
void send_write_SystemParameter_SceneSetting_LivingTopMounted() { sendMessage(write_SystemParameter_SceneSetting_LivingTopMounted, 4); };
void send_write_SystemParameter_SceneSetting_OfficeTopLoading() { sendMessage(write_SystemParameter_SceneSetting_OfficeTopLoading, 4); };
void send_write_SystemParameter_SceneSetting_HotelTopLoading() { sendMessage(write_SystemParameter_SceneSetting_HotelTopLoading, 4); };
Note:
After extensive testing, I don’t really like the Seeed Human Presence sensor that much for sleep detection. Somewhat similar issues with people sitting but since there’s more movement you can set the sensitivity really low and while still avoiding getting many incorrect unoccupied readings because of people moving around a little bit while watching tv, etc.
If you want to detect sleep from beneath (through) your bed, use the DFRobot one. I trust my daily routine / alarm on the DFRobot sensor detecting if I’m in bed or not.
The Seeed one can have a hard time returning back to unoccupied (sometimes doesn’t for hours). If you set the sensitivity to lower, it can miss you sleeping entirely.
DFRobot does really well on stabilizing at a 1=occupied, 0=unoccupied (after about 15-30s to occupied, about 30-60s to unoccupied) even though it has much less configuration and “features”, it does the one thing better (you have to filter out some blips which is easy to do).
Thanks for the update and advice. I also noted that on the Seeed studio model, it sometimes takes forever to get to the vacant state, despite nobody being present in its vicinity. I have been trying to get my hands on the DFRobot model for some time, but being in India, I have very few sources.
Let me know if you have any trouble with the checksum code!
In the other thread you previously shared, @crlogic pointed out that in the manual of the chip, it recommends to use 2 capacitors instead of connecting it straight away to the 5V pin, could it be that your issues are because of that?
Hi @phillip1 - amazing thread! Appreciate the code for the SeeedStudio. I have a question about the sensitivity adjustment posted above. Please note; this is coming from someone w/ no cpp knowledge. But I can read the formatting as well as copy & paste!
Question: where is _s
declared?
I am trying to make the sensitivity HA adjustable, aka
esphome:
name: poe-seedstudio-mmwave
includes:
- philips_seeedstudio_sensitivity.h
number:
- platform: template
name: sensitivity
id: sensitivity
min_value: 1
max_value: 10
initial_value: 2
step: 1
restore_value: true
set_action:
- delay: 2s
- uart.write: !lambda
if (x == 1) {
send_write_SystemParameter_ThresholdGear_1();
return {};
}
else if (x == 2) {
send_write_SystemParameter_ThresholdGear_2();
return {};
}
else if (x == 3) {
send_write_SystemParameter_ThresholdGear_3();
return {};
}
I have reviewed the thread a couple times but seems to miss any prior .h where serial is perhaps setup?
Check out the RFBeam K-LD2 if you are interested in approaching/receding detection. Works well for me the past few months. I use one to trigger motion lights around a corner where the primary motion sensor is also around that corner. Approaching = trigger lights before primary sensor. Receding = allow primary sensor to trigger lights off. The interesting part of the K-LD2 is that is turns off on static presence. So just “standing around the corner” doesn’t mean triggering the lights.
Alternatively, the K-LD7 provides speed, distance and angle which is fun when you make WLED blink a light that follows you around the room.
That’s a super neat sensor, might just have to get one.
I have updated the code I posted previously in the “Here is the code” block to give you an idea on how to setup the serial. I think you may need to use a custom component.
To simplify your code, you can add a sendThreshold
function
void sendThreshold(int threshold) {
unsigned char thresholdPacket[4] = {0x02, 0x04, 0x0C, threshold};
sendMessage(thresholdPacket, 4);
}
Then call it with sendThreshold(x);
inside your !lambda.
I think the part the confuses me is that the ESPHome Custom UART shows read examples and we are trying to write.
Hence my usage of the ESPHome uart.write
yaml which I have successfully used in the past.
Following this simplified strategy to feed uart.write
with bytearray string to change the threshold. Can you see why the following “not declared in this scope” error are occurring? I makes not sense to me given I have paired down the existing code which didn’t have such errors.
esphome:
name: poe-seedstudio-mmwave
includes:
- uart_seeedstudio_sensitivity.h
const unsigned char cuc_CRCHi[256] = {
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40
};
const unsigned char cuc_CRCLo[256]= {
0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06, 0x07, 0xC7,
0x05, 0xC5, 0xC4, 0x04, 0xCC, 0x0C, 0x0D, 0xCD, 0x0F, 0xCF, 0xCE, 0x0E,
0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09, 0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9,
0x1B, 0xDB, 0xDA, 0x1A, 0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC,
0x14, 0xD4, 0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3,
0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3, 0xF2, 0x32,
0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4, 0x3C, 0xFC, 0xFD, 0x3D,
0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A, 0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38,
0x28, 0xE8, 0xE9, 0x29, 0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF,
0x2D, 0xED, 0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26,
0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60, 0x61, 0xA1,
0x63, 0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67, 0xA5, 0x65, 0x64, 0xA4,
0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F, 0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB,
0x69, 0xA9, 0xA8, 0x68, 0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA,
0xBE, 0x7E, 0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5,
0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71, 0x70, 0xB0,
0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92, 0x96, 0x56, 0x57, 0x97,
0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C, 0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E,
0x5A, 0x9A, 0x9B, 0x5B, 0x99, 0x59, 0x58, 0x98, 0x88, 0x48, 0x49, 0x89,
0x4B, 0x8B, 0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C,
0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42, 0x43, 0x83,
0x41, 0x81, 0x80, 0x40
};
unsigned short int us_CalculateCrc16(unsigned char *lpuc_Frame, unsigned short int lus_Len){
unsigned char luc_CRCHi = 0xFF;
unsigned char luc_CRCLo = 0xFF;
int li_Index=0;
while(lus_Len--){
li_Index = luc_CRCLo ^ *( lpuc_Frame++);
luc_CRCLo = (unsigned char)( luc_CRCHi ^ cuc_CRCHi[li_Index]);
luc_CRCHi = cuc_CRCLo[li_Index];
}
return (unsigned short int )(luc_CRCLo << 8 | luc_CRCHi);
}
char CRC(char ad1, char ad2, char ad3, char ad4, char ad5, char ad6, char ad7){
unsigned char data[] = {ad1, ad2, ad3, ad4, ad5, ad6, ad7};
unsigned short int crc_data = 0x0000;
unsigned int lenth = sizeof(data)/sizeof(unsigned char);
crc_data = us_CalculateCrc16(data, lenth);
return crc_data;
}
char sendThreshold(int threshold) {
unsigned char thresholdPacket[4] = {0x02, 0x04, 0x0C, threshold};
len = 7;
unsigned char data[len];
unsigned char dataWithChecksum[len + 2];
data[0] = 0x55;
data[1] = len + 1;
data[2] = 0x00;
for (int n = 0; n < len - 3; n++) {
data[n + 3] = thresholdPacket[n];
}
for (int n = 0; n < len; n++) {
dataWithChecksum[n] = data[n];
}
unsigned short int crc_data = us_CalculateCrc16(data, len);
dataWithChecksum[len] = (crc_data & 0xff00) >> 8;
dataWithChecksum[len+1] = crc_data & 0xff;
return dataWithChecksum;
}
number:
- platform: template
name: sensitivity
id: sensitivity
min_value: 1
max_value: 9
initial_value: 3
step: 1
restore_value: true
set_action:
- delay: 2s
- uart.write: !lambda
return sendThreshold(x);
Compiling /data/poe-seedstudio-mmwave/.pioenvs/poe-seedstudio-mmwave/src/main.cpp.o
In file included from src/main.cpp:51:0:
src/uart_seeedstudio_sensitivity.h: In function 'char sendThreshold(int)':
src/uart_seeedstudio_sensitivity.h:73:66: warning: narrowing conversion of 'threshold' from 'int' to 'unsigned char' inside { } [-Wnarrowing]
unsigned char thresholdPacket[4] = {0x02, 0x04, 0x0C, threshold};
^
src/uart_seeedstudio_sensitivity.h:74:3: error: 'len' was not declared in this scope
len = 7;
^
src/uart_seeedstudio_sensitivity.h:77:3: error: 'data' was not declared in this scope
data[0] = 0x55;
^
src/uart_seeedstudio_sensitivity.h:84:5: error: 'dataWithChecksum' was not declared in this scope
dataWithChecksum[n] = data[n];
^
src/uart_seeedstudio_sensitivity.h:87:3: error: 'dataWithChecksum' was not declared in this scope
dataWithChecksum[len] = (crc_data & 0xff00) >> 8;
^
/config/esphome/poe-seedstudio-mmwave.yaml: In lambda function:
/config/esphome/poe-seedstudio-mmwave.yaml:126:27: error: could not convert 'sendThreshold((int)x)' from 'char' to 'std::vector<unsigned char>'
- uart.write: !lambda
^
*** [/data/poe-seedstudio-mmwave/.pioenvs/poe-seedstudio-mmwave/src/main.cpp.o] Error 1
========================== [FAILED] Took 2.98 seconds ==========================
Your code looks good you just scrubbed some declarations from the code. I don’t know esphome well, so uart.write is new to me (I just do it all with 10x more c++ code so I can put off learning esphome).
Try this (simpler):
//make the code more concise, but still work the same:
std::vector<unsigned char> getThresholdPacket(int threshold) {
int len = 7;
unsigned char thresholdPacket[] = {0x55, (unsigned char)(len+1), 0x00, 0x02, 0x04, 0x0C, (unsigned char)threshold};
unsigned short int crc_data = us_CalculateCrc16(thresholdPacket, len);
std::vector<unsigned char> dataWithChecksum;
dataWithChecksum.assign(thresholdPacket, thresholdPacket + len);
dataWithChecksum.push_back((crc_data & 0xff00) >> 8);
dataWithChecksum.push_back(crc_data & 0xff);
return dataWithChecksum;
}
That compiles!
Snippet of log when changing values;
[19:47:43][D][number:113]: New number value: 2.000000
[19:47:45][D][uart_debug:114]: >>> 55:08:00:02:04:0C:02:DB:F5
[19:47:45][D][uart_debug:114]: <<< 55:08:00:02:04:0C:02:DB:F5
[19:47:51][D][number:054]: 'sensitivity' - Setting number value
[19:47:51][D][number:113]: New number value: 1.000000
[19:47:53][D][uart_debug:114]: >>> 55:08:00:02:04:0C:01:9B:F4
[19:47:53][D][uart_debug:114]: <<< 55:08:00:02:04:0C:01:9B:F4
Will have to do some testing as this SeeedStudio is unfamiliar to me.
The DFRobot can be tuned down to mere CM’s distance which is helpful for testing purposes.
Thank you very much for your review! I hoped that I can use the Seeed 60Ghz as a sleep and bett sensor.
Is it possible for you to post an esphome yaml for presence, breathing and heart rate to test?
presence_sensor.h
#include "esphome.h"
#include "Radar.h"
using namespace esphome;
static const char* TAG = "PresenceSensor";
class PresenceSensor : public Component, public UARTDevice {
public:
Radar* radar = new Radar(&Serial);
Sensor* presence_sensor = new Sensor();
PresenceSensor(UARTComponent *parent) : UARTDevice(parent) {}
void setup() {
// delay(1000);
// radar->send_write_SystemParameter_ThresholdGear_1();
// delay(1000);
// radar->send_write_SystemParameter_SceneSetting_LivingTopMounted();
}
std::vector<int> bytes;
void loop() override {
while(available() > 0) {
int incomingByte = read();
//hit next message
if(incomingByte == 85) {
//could check if checksum matches if you feel like it (last 2 bytes)
processPacket();
bytes.clear();
bytes.push_back(85);
} else {
bytes.push_back(incomingByte);
}
}
}
std::vector<float> lastLevels = std::vector<float>(4, 0.0f);
void processPacket() {
//the array could look like 85 7 0 4 3 0 1 1 1 137 92
//cut off the first 3 header bytes and the last 2 checksum bytes
bytes.erase(bytes.begin(), bytes.begin() + 3);
bytes.resize(bytes.size() - 2); //remove last 2 checksum bytes
std::string str = "";
//NOW YOU HAVE THE DATA PACKET BYTES. DO WHATEVER YOU WANT
//this is the one you really only care about
//to get the movement amount
if((bytes[0] == 0x03 || bytes[0] == 0x04) && (bytes[1] == 0x03) && (bytes[2] == 0x06))
{
str = "Proactive Radar Signs: " + esphome::to_string(getFloat(bytes[3], bytes[4], bytes[5], bytes[6]));
ESP_LOGI(TAG, str.c_str());
float newSensorValue = getFloat(bytes[3], bytes[4], bytes[5], bytes[6]);
lastLevels.insert(lastLevels.begin(), newSensorValue);
//sometimes when movement starts, the sensor jumps down to zero for one or two readings
//this fixes that behaviour
if(newSensorValue < 0.1f && (lastLevels[0] > 5 || lastLevels[1] > 5 || lastLevels[2] > 5 || lastLevels[3] > 5)) {
//don't publish
} else {
presence_sensor->publish_state(newSensorValue);
}
return;
}
if((bytes[0] == 0x04) && (bytes[1] == 0x03) && (bytes[2] == 0x07))
{
str = "Proactive Radar Approaching: " + hexStr(bytes[5]);
ESP_LOGI(TAG, str.c_str());
return;
}
if((bytes[0] == 0x03 || bytes[0] == 0x04) && (bytes[1] == 0x03) && (bytes[2] == 0x05)) //env
{
str += "Proactive Radar Env:";
if(bytes[3] == 0x00 && bytes[4] == 0xFF && bytes[5] == 0xFF)
{
str += " Unoccupied";
}
else if(bytes[3] == 0x01 && bytes[4] == 0x00 && bytes[5] == 0xFF)
{
str += " Stationary";
}
else if(bytes[3] == 0x01 && bytes[4] == 0x01 && bytes[5] == 0x01)
{
str += " Exercise";
}
else
{
str += " Other?";
}
ESP_LOGI(TAG, str.c_str());
return;
}
//toss away most of the data (headers, length byte, checksum)
for (int i = 0; i < bytes.size(); i++) {
int code = bytes[i];
if(i == 0) {
if(code == 0x03)
{
str += "Passive ";
}
else if (code == 0x04)
{
str += "Proactive ";
}
} else if(i == 1) {
if(code == 0x03)
{
str += "Radar ";
}
} else if(i == 2) {
if(code == 0x05)
{
str += "Env ";
}
else if (code == 0x06)
{
str += "Signs ";
}
} else {
str += hexStr(bytes[i]) + " ";
}
}
ESP_LOGI(TAG, str.c_str());
}
char hexmap[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
std::string hexStr(int data)
{
std::string s = " ";
s[0] = '0';
s[1] = 'x';
s[2] = hexmap[(data & 0xF0) >> 4];
s[3] = hexmap[data & 0x0F];
//s = "0x" + s;
return s;
}
typedef union
{
unsigned char Byte[4];
float Float;
}FloatByte;
float getFloat(int b1, int b2, int b3, int b4)
{
FloatByte fb;
fb.Byte[0] = b1;
fb.Byte[1] = b2;
fb.Byte[2] = b3;
fb.Byte[3] = b4;
return fb.Float;
}
};
Radar.cpp
#include "Arduino.h"
#include "Radar.h"
#define MESSAGE_HEAD 0x55
#define ACTIVE_REPORT 0x04
#define FALL_REPORT 0x06
#define REPORT_RADAR 0x03
#define REPORT_OTHER 0x05
#define HEARTBEAT 0x01
#define ABNOEMAL 0x02
#define ENVIRONMENT 0x05
#define BODYSIGN 0x06
#define CLOSE_AWAY 0x07
#define CA_BE 0x01
#define CA_CLOSE 0x02
#define CA_AWAY 0x03
#define SOMEBODY_BE 0x01
#define SOMEBODY_MOVE 0x01
#define SOMEBODY_STOP 0x00
#define NOBODY 0x00
Radar::Radar(Stream *s)
{
_s = s;
}
//CHECKSUM CALCULATION
const unsigned char cuc_CRCHi[256]= {
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40
};
const unsigned char cuc_CRCLo[256]= {
0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06, 0x07, 0xC7,
0x05, 0xC5, 0xC4, 0x04, 0xCC, 0x0C, 0x0D, 0xCD, 0x0F, 0xCF, 0xCE, 0x0E,
0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09, 0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9,
0x1B, 0xDB, 0xDA, 0x1A, 0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC,
0x14, 0xD4, 0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3,
0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3, 0xF2, 0x32,
0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4, 0x3C, 0xFC, 0xFD, 0x3D,
0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A, 0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38,
0x28, 0xE8, 0xE9, 0x29, 0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF,
0x2D, 0xED, 0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26,
0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60, 0x61, 0xA1,
0x63, 0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67, 0xA5, 0x65, 0x64, 0xA4,
0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F, 0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB,
0x69, 0xA9, 0xA8, 0x68, 0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA,
0xBE, 0x7E, 0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5,
0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71, 0x70, 0xB0,
0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92, 0x96, 0x56, 0x57, 0x97,
0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C, 0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E,
0x5A, 0x9A, 0x9B, 0x5B, 0x99, 0x59, 0x58, 0x98, 0x88, 0x48, 0x49, 0x89,
0x4B, 0x8B, 0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C,
0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42, 0x43, 0x83,
0x41, 0x81, 0x80, 0x40
};
unsigned short int Radar::us_CalculateCrc16(unsigned char *lpuc_Frame, unsigned short int lus_Len){
unsigned char luc_CRCHi = 0xFF;
unsigned char luc_CRCLo = 0xFF;
int li_Index=0;
while(lus_Len--){
li_Index = luc_CRCLo ^ *( lpuc_Frame++);
luc_CRCLo = (unsigned char)( luc_CRCHi ^ cuc_CRCHi[li_Index]);
luc_CRCHi = cuc_CRCLo[li_Index];
}
return (unsigned short int )(luc_CRCLo << 8 | luc_CRCHi);
}
char Radar::CRC(char ad1, char ad2, char ad3, char ad4, char ad5, char ad6, char ad7){
unsigned char data[] = {ad1, ad2, ad3, ad4, ad5, ad6, ad7};
unsigned short int crc_data = 0x0000;
unsigned int lenth = sizeof(data)/sizeof(unsigned char);
crc_data = us_CalculateCrc16(data, lenth);
return crc_data;
}
void Radar::sendMessage(unsigned char partialData[], int length)
{
length += 3;
unsigned char data[length];
unsigned char dataWithChecksum[length + 2];
data[0] = 0x55;
data[1] = length + 1; //
data[2] = 0x00;
for (int n = 0; n < length - 3; n++)data[n + 3] = partialData[n];
for (int n = 0; n < length; n++)dataWithChecksum[n] = data[n];
unsigned short int crc_data = us_CalculateCrc16(data, length);
dataWithChecksum[length] = (crc_data & 0xff00) >> 8;
dataWithChecksum[length+1] = crc_data & 0xff;
for (int n = 0; n < length + 2; n++){
_s->write(dataWithChecksum[n]);
}
}
unsigned char read_RadarInfo_EnvironmentalStatus[3] = {0x01, 0x03, 0x05};
unsigned char read_RadarInfo_MotorSigns[3] = {0x01, 0x03, 0x06};
unsigned char read_SystemParameter_ThresholdGear[3] = {0x01, 0x04, 0x0C}; //tested
unsigned char read_SystemParameter_SceneSetting[3] = {0x01, 0x04, 0x10};
unsigned char write_SystemParameter_ThresholdGear_1[4] = {0x02, 0x04, 0x0C, 0x01}; //least sensitive
unsigned char write_SystemParameter_ThresholdGear_2[4] = {0x02, 0x04, 0x0C, 0x02};
unsigned char write_SystemParameter_ThresholdGear_3[4] = {0x02, 0x04, 0x0C, 0x03};
unsigned char write_SystemParameter_ThresholdGear_4[4] = {0x02, 0x04, 0x0C, 0x04};
unsigned char write_SystemParameter_ThresholdGear_5[4] = {0x02, 0x04, 0x0C, 0x05};
unsigned char write_SystemParameter_ThresholdGear_6[4] = {0x02, 0x04, 0x0C, 0x06};
unsigned char write_SystemParameter_ThresholdGear_7[4] = {0x02, 0x04, 0x0C, 0x07}; //default
unsigned char write_SystemParameter_ThresholdGear_8[4] = {0x02, 0x04, 0x0C, 0x08};
unsigned char write_SystemParameter_ThresholdGear_9[4] = {0x02, 0x04, 0x0C, 0x09};
unsigned char write_SystemParameter_ThresholdGear_10[4] = {0x02, 0x04, 0x0C, 0x0A}; //most sensitive
unsigned char write_SystemParameter_SceneSetting_Default[4] = {0x02, 0x04, 0x10, 0x00}; //roughly a distance setting?
unsigned char write_SystemParameter_SceneSetting_AreaTopLoading[4] = {0x02, 0x04, 0x10, 0x01};
unsigned char write_SystemParameter_SceneSetting_BathroomTopMounted[4] = {0x02, 0x04, 0x10, 0x02};
unsigned char write_SystemParameter_SceneSetting_BathroomTopLoading[4] = {0x02, 0x04, 0x10, 0x03};
unsigned char write_SystemParameter_SceneSetting_LivingTopMounted[4] = {0x02, 0x04, 0x10, 0x04};
unsigned char write_SystemParameter_SceneSetting_OfficeTopLoading[4] = {0x02, 0x04, 0x10, 0x05};
unsigned char write_SystemParameter_SceneSetting_HotelTopLoading[4] = {0x02, 0x04, 0x10, 0x06}; //hotel is the largest?
void Radar::send_read_RadarInfo_EnvironmentalStatus() { sendMessage(read_RadarInfo_EnvironmentalStatus, 3); };
void Radar::send_read_RadarInfo_MotorSigns() { sendMessage(read_RadarInfo_MotorSigns, 3); };
void Radar::send_read_SystemParameter_ThresholdGear() { sendMessage(read_SystemParameter_ThresholdGear, 3); };
void Radar::send_read_SystemParameter_SceneSetting() { sendMessage(read_SystemParameter_SceneSetting, 3); };
void Radar::send_write_SystemParameter_ThresholdGear_1() { sendMessage(write_SystemParameter_ThresholdGear_1, 4); };
void Radar::send_write_SystemParameter_ThresholdGear_2() { sendMessage(write_SystemParameter_ThresholdGear_2, 4); };
void Radar::send_write_SystemParameter_ThresholdGear_3() { sendMessage(write_SystemParameter_ThresholdGear_3, 4); };
void Radar::send_write_SystemParameter_ThresholdGear_4() { sendMessage(write_SystemParameter_ThresholdGear_4, 4); };
void Radar::send_write_SystemParameter_ThresholdGear_5() { sendMessage(write_SystemParameter_ThresholdGear_5, 4); };
void Radar::send_write_SystemParameter_ThresholdGear_6() { sendMessage(write_SystemParameter_ThresholdGear_6, 4); };
void Radar::send_write_SystemParameter_ThresholdGear_7() { sendMessage(write_SystemParameter_ThresholdGear_7, 4); };
void Radar::send_write_SystemParameter_ThresholdGear_8() { sendMessage(write_SystemParameter_ThresholdGear_8, 4); };
void Radar::send_write_SystemParameter_ThresholdGear_9() { sendMessage(write_SystemParameter_ThresholdGear_9, 4); };
void Radar::send_write_SystemParameter_ThresholdGear_10() { sendMessage(write_SystemParameter_ThresholdGear_10, 4); };
void Radar::send_write_SystemParameter_SceneSetting_Default() { sendMessage(write_SystemParameter_SceneSetting_Default, 4); };
void Radar::send_write_SystemParameter_SceneSetting_AreaTopLoading() { sendMessage(write_SystemParameter_SceneSetting_AreaTopLoading, 4); };
void Radar::send_write_SystemParameter_SceneSetting_BathroomTopMounted() { sendMessage(write_SystemParameter_SceneSetting_BathroomTopMounted, 4); };
void Radar::send_write_SystemParameter_SceneSetting_BathroomTopLoading() { sendMessage(write_SystemParameter_SceneSetting_BathroomTopLoading, 4); };
void Radar::send_write_SystemParameter_SceneSetting_LivingTopMounted() { sendMessage(write_SystemParameter_SceneSetting_LivingTopMounted, 4); };
void Radar::send_write_SystemParameter_SceneSetting_OfficeTopLoading() { sendMessage(write_SystemParameter_SceneSetting_OfficeTopLoading, 4); };
void Radar::send_write_SystemParameter_SceneSetting_HotelTopLoading() { sendMessage(write_SystemParameter_SceneSetting_HotelTopLoading, 4); };
Radar.h
#ifndef _RADAR_H__
#define _RADAR_H__
#include <Arduino.h>
class Radar
{
private:
Stream *_s;
public:
Radar(Stream *s);
char CRC(char ad1, char ad2, char ad3, char ad4, char ad5, char ad6, char ad7);
void sendMessage(unsigned char partialData[], int length);
unsigned short int us_CalculateCrc16(unsigned char *lpuc_Frame, unsigned short int lus_Len);
void send_read_RadarInfo_EnvironmentalStatus();
void send_read_RadarInfo_MotorSigns();
void send_read_SystemParameter_ThresholdGear(); //tested
void send_read_SystemParameter_SceneSetting();
void send_write_SystemParameter_ThresholdGear_1(); //least sensitive
void send_write_SystemParameter_ThresholdGear_2();
void send_write_SystemParameter_ThresholdGear_3();
void send_write_SystemParameter_ThresholdGear_4();
void send_write_SystemParameter_ThresholdGear_5();
void send_write_SystemParameter_ThresholdGear_6();
void send_write_SystemParameter_ThresholdGear_7(); //default
void send_write_SystemParameter_ThresholdGear_8();
void send_write_SystemParameter_ThresholdGear_9();
void send_write_SystemParameter_ThresholdGear_10(); //most sensitive
void send_write_SystemParameter_SceneSetting_Default(); //roughly a distance setting?
void send_write_SystemParameter_SceneSetting_AreaTopLoading();
void send_write_SystemParameter_SceneSetting_BathroomTopMounted();
void send_write_SystemParameter_SceneSetting_BathroomTopLoading();
void send_write_SystemParameter_SceneSetting_LivingTopMounted();
void send_write_SystemParameter_SceneSetting_OfficeTopLoading();
void send_write_SystemParameter_SceneSetting_HotelTopLoading(); //hotel is the largest?
};
#endif
presence-sensor.yaml
esphome:
name: presence-sensor
platform: ESP32
board: esp32dev
includes:
- presence_sensor.h
- libraries/Radar.h
- libraries/Radar.cpp
logger:
#level: VERBOSE #makes uart stream available in esphome logstream
baud_rate: 0 #disable logging over uart
api:
ota:
password: "password"
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
power_save_mode: none
# Enable fallback hotspot (captive portal) in case wifi connection fails
ap:
ssid: "Presence-Sensor"
password: "password"
captive_portal:
#9600 baud is mandatory, GPIOs are to your preference
uart:
id: uart_bus
tx_pin: GPIO26
rx_pin: GPIO27
baud_rate: 9600
sensor:
- platform: custom
lambda: |-
auto my_sensor = new PresenceSensor(id(uart_bus));
App.register_component(my_sensor);
return {my_sensor->presence_sensor};
sensors:
- name: "Presence Level"
accuracy_decimals: 1
state_class: measurement
Need 5V, GND, RX, TX. That’s All!
Oh snap thanks!
Just caught your comment. That could make a difference.
Edit: Tested w/ oscilloscope and my esp32 has a ripple of about 100mV on the edge of “<100mV” and a supply voltage of 4.75V which is also on the edge of “4.9V-6V”
Thank you very much!
Is this for the 60Ghz Seeed Sleep and Breathe sensor?
I can’t get it to work
Nah, it’s for the 24Ghz one.
Same idea for the 60Ghz one but different packet header and checksum(which doesn’t matter for reading)
For the 60Ghz one, you would wait until you see the end of frame packet 0x54 0x43
void loop() override
{
while (available() > 0)
{
bytes.push_back(read());
//End of Frame is 0x54 0x43
if(bytes[bytes.size()-2] == 0x54 && bytes[bytes.size()-1] == 0x43)
{
processPacket();
bytes.clear();
}
}
}