Just guessing, but one is better at short range, the other at far range.
They would probably be interchangeable for a lot of applications.
I was only able to get my hands on the human static one which is also cheaper. (Arriving today!)
Just guessing, but one is better at short range, the other at far range.
They would probably be interchangeable for a lot of applications.
I was only able to get my hands on the human static one which is also cheaper. (Arriving today!)
Looking forward for your review, Iâm just concerned about the wall penetration if it still detects person from different rooms.
I think it should be able to detect through walls, but you can set up the distance you want
I read a bit more and looks like the breath one can detect when someone is getting closer or further.
Let us know if the static can do that too as I can only order the expensive one!
Iâm super curious to know how these work with multiple people in the room!
Or⌠pets?
So the good news is both the wifi & zigbee version of the tuya mm wave human detector version i ordered arrived today.
The bad news, i might have fried the zigbee version.
I wired up to a plug & plugged into a socket extension to test it out (which is what iâve been doing normally for relay switches). I turned it on, noticed some sparks and i immediately turned it off.
Iâm no electrician, so could anyone explain what went wrong and how can i fix that before i test the wifi version? My house is on 240v btw
If that manual says 12 volts (assuming DC) and you hooked it up to 230 AC then itâs beyond dead.
Thanks, so that means i need to get power supply converter first (ac 240v - 12v)
Looks like the wifi version does include it, but not the zigbee one
Another lesson learned for me i guess
Labelling 12v DC connections âLâ and âNâ
Yeah⌠thatâs a bit silly.
But I have learned to expect nothing when it comes to manuals these days.
So Iâve been playing with the Seeed human presence detection sensor for two days now. I have improved their crappy library a bit by adding things like writing commands over serial with the necessary checksum code.
Serial Data: itâs pretty simple to work with, and the chip sends 12~ byte packets. What each packet means is well documented for all 4 sensors. The 3 24GHz sensors are all very similar and can detect presence and movement amount and all send back identical data packets. The difference between the 3 is that:
24GHz Fall Detection: Has an extra fall detection packet it will send. This may mean it is better at detecting if someone is moving away from the sensor. More or less the same as the human presence sensor.
24GHz Sleep Detection: It is more sensitive so it can detect breath rate. It has a shorter range. I believe based on the breath rate (it tries to) detect how deep the sleep is and what the quality of sleep is. It has a heart rate packet but somehow I doubt it would be accurate. Says it has a 3m presence detection range which is the same as the other two. For motion, it could easily be more.
24GHz Human Presence / Fall Detection Range: 12m range, 5m micromotion, 3m presence range (similar to the other two for static presence range).
â 60GHz Sleep Detection is a different beast: Double+ the price. Totally different packet format and might need some kind of uart to serial converter. Way more things it tries to detect: breath rate, breath waveform, heart rate, number of people in the environment, âResting Distanceâ - perhaps how far the person is. None of the others do. Says it has a 2m range. For motion, it could easily be more. 60GHz does not penetrate objects and walls as much as 24GHz.
Movement and direction: The documentation says you can measure whether someone is ânearbyâ, âwalking awayâ, or âmoving without directionâ for all 4 sensors. None of them have a âmoving closerâ packet documented, maybe the ânearbyâ packet is moving closer but it really just sounded like a âperson is nearbyâ packet. This data is too random in the Human Detection sensor to be useful. It is maybe better for the fall detection one but Iâm skeptical. The 24GHz and 60GHz sleep ones seem to have a better perception of distance and movement direction so they may be able to better detect if someone is walking away. No promises!
My opinion on the human presence sensor:
Iâm happy with it. This sensor definitely has a better processing algorithm that is much more consistent and removes the need for averaging data over 20+ seconds compared to the DFRobot one. It will hold a steady, unoccupied state when there is no one around and quickly switch to occupied when someone enters the vicinity. Takes a couple of minutes to switch back to unoccupied. Seems to be a little quicker when you reduce the sensitivity.
Sensitivity setting: All 3 have a sensitivity setting (1-10) which I was able to write to the board over serial (Checksum required!). I reduced the sensitivity from the default 7 down to 3.
âMotor Signsâ: You can get a 4 byte float back from 0-100 (called motor signs). 0 is unoccupied, 1 is occupied but stationary, and 1-100 is increasing amounts of movement in the area. The number does seem to reflect the amount of movement. If it is >1 I would do a moving average to get a clearer picture of how much movement there is. You need to write a packet to start getting this data back frequently.
This is in reference to @mattdm 's question:
What the sensor does is it sends out radar waves and tries to interpret them as they return. If you have multiple people or dogs in the area it will all just affect the readings you get.
Dog walks past a little ways away? If you have it set to low sensitivity maybe it wouldnât interpret it as occupied.
Multiple people in the frame? If one is sitting close by and another is moving further away it would still read it as movement. Maybe 40/100 or something. Unlike the other 3, the 60GHz sleep sensor claims it can detect how many people are in the frame.
Itâs a slightly smaller pin header than Arduino / most breadboards.
Another person got the human presence one working:
Looks somewhat similar to how I have implemented it.
Happy to answer any questions!
@phillip1
Hi, if i point the sensor towards my bed, would it still penetrate the walls next to my living room and detect the people there? Or do you still need to fine tune the settings for it
Wow. This is awesome and terrifying at the same time. Look at how small the thing isâŚ
The sensor is fairly directional so I wouldnât be worried about it picking up stuff from the living room based on your diagram, but Iâm not sure if it would pick you up the whole night if the sensor is positioned at a similar level as you and you sleep on your back / front.
Iâll test it tonight to see if it picks me up all night if itâs placed the same as in your diagram.
This is approximately the sensorâs pickup pattern where it switches from unoccupied to occupied if Iâm moving a little (same for the other two as well probs)
But the further out to the side you are, the weaker the signal and the less it goes through walls.
The vertical range is not nearly as tall as it is wide
For home automation, that seems like the killer feature.
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); };