Use tape?
I don’t see a software option in the wiki.
Use tape?
I don’t see a software option in the wiki.
I had a lot of trouble with false positives using the RCWL sensors. Since it looks like some of you have been using them now for a while, how has it been so far?
What I understand from this topic they will be detect the smallest movement. Since I have a cat I expect I won’t be able to use it in most places anyway, but a bed occupancy sensor seems possible with some extra logic. However, I would have to be able to ignore moving curtains, flying bugs, plant leave moving in the wind - we often have the windows open - things like that. Or restrict it very specifically to just the bed somehow.
By themselves, the smallest movement reliably triggers them. So the breeze from an open window rustling papers on a desk, curtains, plants, etc will set them off. I haven’t tested bugs though…
I have cats - they do indeed set these off. Pairing with a PIR can help mitigate that and the previously mentioned sources. Likewise careful placement if possible, but cats go everywhere; Suki!!
Alternatively, if you need merely occupancy and not response time, you could use a delayed_on
configuration for similar debouncing of non-sustained movements.
What is the PIR for, to trigger the initial state? And then use the microwave sensor to more reliably detect if there’s still a presence? I’m just a bit hesitant to start trying presence detection again. After a lot of tries and invested time (including bayesian sensors and the like) I simply gave up on anything but home/not home.
I’m just spitballing here, but maybe two microwave sensors can be combined (probably using two different wavelengths)? One to detect ‘big’ movement so that a human can be distinguished and the other to detect ‘fine’ movement to confirm that the human is still there.
You got it.
I concur that reliable presence is challenging. And it has taken experimentation and patience to work out a good solution. Even the best sensor, aimed poorly, can be frustrating. I’ve been there.
Combining mmWave is possible. But I haven’t seen one that differentiates big or small. The K-LD series offer a threshold/sensitivity adjustment. But having played with them I can tell you that these are far more effort in order to tune.
Here is the next iteration of this project that uses PIR and mmWave, Low-latency presence sensor: mmWave + PIR using ESPHome
This has been a great thread, which I’ve taken and implemented using the Seeed 24GHz sensor in ESPHome.
My yaml file
substitutions:
# Change the disp_name to something you want
display_name: Office presence
# Interval of how often the power is updated
update_time: 1s
esphome:
name: office-presence-sensor
comment: ${display_name}
includes:
- uart_read_radar_sensor.h
libraries:
- "Seeed Arduino 24GHz Radar Sensor"
esp32:
board: esp32dev
framework:
type: arduino
wifi:
ssid: something
password: something
fast_connect: true
# power_save_mode: none
manual_ip:
static_ip: 192.168.1.33
gateway: 192.168.1.1
subnet: 255.255.255.0
dns1: 192.168.1.1
# Enable logging
logger:
level: INFO #makes uart stream available in esphome logstream
# Enable Home Assistant API
api:
services:
# Service to send a command directly to the display. Useful for testing
- service: send_command
variables:
cmd: string
then:
- uart.write: !lambda
char buf[128];
sprintf(buf, "%s\n", cmd.c_str());
std::string s = buf;
return std::vector<unsigned char>( s.begin(), s.end() );
ota:
password: "s"
uart:
id: uart_bus
tx_pin: GPIO17
rx_pin: GPIO16
baud_rate: 9600
# debug:
# Example configuration entry
binary_sensor:
- platform: gpio
pin: GPIO21
name: ${display_name} Presence
device_class: motion
filters:
- delayed_on: 100ms
- delayed_off: 500ms
- platform: gpio
pin: GPIO22
name: ${display_name} Moving
device_class: moving
filters:
- delayed_on: 100ms
- delayed_off: 500ms
sensor:
- platform: custom
lambda: |-
auto my_custom_sensor = new UartReadRadarSensor(id(uart_bus));
App.register_component(my_custom_sensor);
return {my_custom_sensor->action_status, my_custom_sensor->movement_status };
sensors:
- name: ${display_name} Action
id: office_presence_action
- name: ${display_name} Movement
id: office_presence_movement
# Example configuration entry
text_sensor:
- platform: template
name: "${display_name} Action Description"
id: office_presence_action_description
lambda: |-
if( id(office_presence_action).state == 2 ) {
return{ "Movement" };
}
else if( id(office_presence_action).state == 3 ) {
return{ "Stationary" };
}
else if( id(office_presence_action).state == 4 ) {
return{ "No-movement" };
}
else if( id(office_presence_action).state == 5 ) {
return{ "Closer" };
}
else if( id(office_presence_action).state == 6 ) {
return{ "Further" };
}
return {"Vacant"};
update_interval: ${update_time}
- platform: template
name: "${display_name} Movement Description"
id: office_presence_movement_description
lambda: |-
if( id(office_presence_movement).state == 1 ) {
return{ "Still" };
}
else if( id(office_presence_movement).state == 2 ) {
return{ "Micro" };
}
else if( id(office_presence_movement).state == 3 ) {
return{ "Slow" };
}
else if( id(office_presence_movement).state == 4 ) {
return{ "Fast" };
}
return {"None"};
update_interval: ${update_time}
My uart_read_radar_sensor.h file
#include "esphome.h"
#include "radar.h"
#define MESSAGE_HEAD 0x55
#define NEWLINE 0x0a
class UartReadRadarSensor : public Component, public UARTDevice {
public:
radar RADAR;
Sensor *action_status = new Sensor();
Sensor *movement_status = new Sensor();
UartReadRadarSensor(UARTComponent *parent) : UARTDevice(parent) {}
void setup() override {
// nothing to do here
}
int Bodysign_judgment(int ad1, int ad2, int ad3, int ad4, int ad5){
float s;
s = RADAR.Bodysign_val(ad1, ad2, ad3, ad4, ad5);
ESP_LOGV("custom", "Bodysign_val = %f", s );
if(s < 1.0){
return 0; // NOBODY;
}
else if(s < 2.0){
return 1; // STATIONARY;
}
else if(s >= 2.0 && s < 30.0){
return 2; // MICRO MOVEMENTS;
}
else if(s >= 30.0 && s < 60.0){
return 3; // SLOW MOVEMENT;
}
else if(s >= 60.0){
return 4; // FAST MOVEMENT;
}
return -1;
}
int readline(int readch, int *thisMessage, int len)
{
static int pos = 0;
int rpos;
ESP_LOGV("custom", "this char = %2x; pos = %i", readch, pos );
// if the read char is not the marker and the pos is zero, skip
// i.e. skip until the start marker is found
if( readch != MESSAGE_HEAD && pos == 0 ){
return -1;
}
// if the read char is a newline and the pos is 1, store the data
// I find i'm getting 0x55, then 0x0a, then the good data
if( readch == NEWLINE && pos == 1 ){
if (pos < len-1) {
thisMessage[pos++] = readch;
thisMessage[pos] = 0;
}
return -1;
}
// if the read char is the marker and the pos is not zero, return result
if( readch == MESSAGE_HEAD && pos != 0 ){
rpos = pos;
pos = 0; // Reset position index ready for next time
return rpos;
}
if (readch != -1) {
switch (readch) {
// case '\r': // Return on CR
// break;
case NEWLINE: // Return on new-line
rpos = pos;
pos = 0; // Reset position index ready for next time
return rpos;
default:
if (pos < len-1) {
thisMessage[pos++] = readch;
thisMessage[pos] = 0;
}
}
}
// No end of line has been found, so return -1.
return -1;
}
void loop() override {
const int max_line_length = 14;
static int thisMessage[max_line_length];
int activity_result = 0;
int movement_result = 0;
while (available()) {
if(readline(read(), thisMessage, max_line_length) > 0) {
activity_result = RADAR.Situation_judgment(thisMessage[4], thisMessage[5], thisMessage[6], thisMessage[7], thisMessage[8]);
ESP_LOGD("custom", "The value of sensor is: %i = RADAR.Situation_judgment( %2x, %2x, %2x, %2x, %2x, )", activity_result, thisMessage[4], thisMessage[5], thisMessage[6], thisMessage[7], thisMessage[8] );
if( activity_result > 0 ) {
action_status->publish_state( activity_result );
}
movement_result = Bodysign_judgment(thisMessage[5], thisMessage[6], thisMessage[7], thisMessage[8], thisMessage[9]);
ESP_LOGD("custom", "The value of sensor is: %i = Bodysign_judgment( %2x, %2x, %2x, %2x, %2x, )", movement_result, thisMessage[5], thisMessage[6], thisMessage[7], thisMessage[8], thisMessage[9] );
if( thisMessage[5] == 6 ){
movement_status->publish_state( movement_result );
}
}
}
}
};
I can confirm my 24GHz Seeed sensor can see through single brick walls! It is very responsive and will trigger movement almost immediately
any links to it?
Yes - i updated my post above
Absolutely, it’d be great if someone designed a case for this sensor, I can’t find any on thingiverse sadly.
Anyone here knows how to CAD ?
Get the hobby license for Fusion360, it is not as hard as it may seem at first. It will take some practice, and you need a decent set of calipers, but I expect anyone that can a operate a 3dprinter can design a case.
You can also always just glue it into a ready made box, you can get those cheap of aliexpres.
I don’t have the sensor - for now - so I can’t design it myself sadly.
Hi, what’s the most ideal location/direction to place the sensor in a bedroom if I need to avoid getting false detection from other rooms?
Center ceiling or on table next to bed perhaps?
Based on your drawings, i would place in the ceiling pointing down, over the middle of the foot of the beds. If possible, I would ‘test fit’ to see if the sensors are triggered by movement outside of the room. The other option would be on top of the wardrobes, pointing at the beds.
Thanks, as for smaller space like the bathroom
Could I limit the detection range within the bathroom area since it might penetrate the bedroom walls?
Yes, distance is configurable. I have four DFRobot mmwave and zero see through my walls. Typical North American construction of 1/2" drywall with 2x4 framing.
The DFRobot bounces off my walls and increasing detection distance for those reflections may easily confuse some to believe that it sees thru them.
Other sensors such as the SeedStudio indicate in their datasheet that seeing through material is by design. I have seen no such evidence for the DFRobot.
You’re right, I made a case in Fusion 360, wasn’t that hard. It fits pretty well and has two little screw standoffs, I’ll publish it on thingiverse once I get the screw holes working.
I’ve been trying to connect the UART on my SEN0395 but I can’t get anything back, do people have it working just using the config in the first post ? I tried adding the esphome’s debug to see what it sends back but I never get any output from the sensor, not sure why.
A new mains powered ZigBee mmWave to compete with the Aqara FP1. Where the Aqara has a ~5 sec detection time, the Lifesmart is 0.5 sec with a 2 minute cooldown.
https://iot.ilifesmart.com/smart-sensor/human-presence-sensor.html
Thanks, is there an example for distance adjustment and can that be used with the seeed sensors? Apparently it will be restocked within 2 weeks
Haven’t used them, sorry. Suggest referring to the datasheet for available options.
Thanks for the code. Works neatly.
Could you please share if it is possible to adjust the sensor’s sensitivity - if so how?
Thanks