Where does the “f” come from/is for?
There’s also this product although continually oos due to component supply issues,
the “f” is to make sure it is comparing the values as a float variable.
Looks like a nice device, also pricey.
And the 0.7?
That is the 70cm.
That line of code is comparing the measurement from the sensor and comparing it against 0.7m, if is less than that it will return a true value meaning that something is on the path of the laser.
Ah I see… I am trying to rebuild/reuse your code to make my sensors (just 2 binairy ones) work. It works, but partially. It misses some motions…
This is what I did and have. Any help/clue appreciated to fit to my sensors greatly appreciated.
globals:
- id: seq1
type: int
restore_value: no
initial_value: '0'
- id: seq2
type: int
restore_value: no
initial_value: '0'
- id: seq3
type: int
restore_value: no
initial_value: '0'
- id: seq4
type: int
restore_value: no
initial_value: '0'
- id: count
type: int
restore_value: no
initial_value: '0'
- id: inside_previous_value
type: bool
restore_value: no
initial_value: 'false'
- id: outside_previous_value
type: bool
restore_value: no
initial_value: 'false'
binary_sensor:
- platform: gpio
pin:
number: GPIO21
mode: INPUT_PULLUP
id: sens_1
name: "Sensor 1"
device_class: motion
# internal: true
- platform: gpio
pin:
number: GPIO22
mode: INPUT_PULLUP
name: "Sensor 2"
id: sens_2
device_class: motion
# internal: true
- platform: template
id: inside_door_sensor
name: "Inside Door Sensor"
lambda: !lambda |-
if((id(sens_1).state < 0.7f) != id(inside_previous_value)){
id(inside_previous_value) = (id(sens_1).state < 0.7f);
if(((id(sens_1).state < 0.7f) == false) && ((id(sens_2).state < 0.7f) == false)){
id(seq1) = id(seq2);
id(seq2) = id(seq3);
id(seq3) = id(seq4);
id(seq4) = 0;
}else if(((id(sens_1).state < 0.7f) == false) && ((id(sens_2).state < 0.7f) == true)){
id(seq1) = id(seq2);
id(seq2) = id(seq3);
id(seq3) = id(seq4);
id(seq4) = 1;
}else if(((id(sens_1).state < 0.7f) == true) && ((id(sens_2).state < 0.7f) == false)){
id(seq1) = id(seq2);
id(seq2) = id(seq3);
id(seq3) = id(seq4);
id(seq4) = 2;
}else if(((id(sens_1).state < 0.7f) == true) && ((id(sens_2).state < 0.7f) == true)){
id(seq1) = id(seq2);
id(seq2) = id(seq3);
id(seq3) = id(seq4);
id(seq4) = 3;
}
if((id(seq1) == 1) && (id(seq2) == 3) && (id(seq3) == 2) && (id(seq4) == 0)){
id(count) ++;
id(people_in).publish_state(id(count));
}else if((id(seq1) == 2) && (id(seq2) == 3) && (id(seq3) == 1) && (id(seq4) == 0)){
id(count) --;
if(id(count) < 0){
id(count) = 0;
}
id(people_in).publish_state(id(count));
}
}
return id(sens_1).state < 0.7f;
- platform: template
id: outside_door_sensor
name: "Outside Door Sensor"
lambda: !lambda |-
if((id(sens_2).state < 0.7f) != id(outside_previous_value)){
id(outside_previous_value) = (id(sens_2).state < 0.7f);
if(((id(sens_1).state < 0.7f) == false) && ((id(sens_2).state < 0.7f) == false)){
id(seq1) = id(seq2);
id(seq2) = id(seq3);
id(seq3) = id(seq4);
id(seq4) = 0;
}else if(((id(sens_1).state < 0.7f) == false) && ((id(sens_2).state < 0.7f) == true)){
id(seq1) = id(seq2);
id(seq2) = id(seq3);
id(seq3) = id(seq4);
id(seq4) = 1;
}else if(((id(sens_1).state < 0.7f) == true) && ((id(sens_2).state < 0.7f) == false)){
id(seq1) = id(seq2);
id(seq2) = id(seq3);
id(seq3) = id(seq4);
id(seq4) = 2;
}else if(((id(sens_1).state < 0.7f) == true) && ((id(sens_2).state < 0.7f) == true)){
id(seq1) = id(seq2);
id(seq2) = id(seq3);
id(seq3) = id(seq4);
id(seq4) = 3;
}
if((id(seq1) == 1) && (id(seq2) == 3) && (id(seq3) == 2) && (id(seq4) == 0)){
id(count)++;
id(people_in).publish_state(id(count));
}else if((id(seq1) == 2) && (id(seq2) == 3) && (id(seq3) == 1) && (id(seq4) == 0)){
id(count)--;
if(id(count) < 0){
id(count) = 0;
}
id(people_in).publish_state(id(count));
}
}
return id(sens_2).state < 0.7f;
sensor:
- platform: template
id: people_in
name: "People Inside"
lambda: !lambda |-
return id(count);
EDIT: Disclaimer: I am no coder at all, just a copy-cat with understanding of logics (some sort of )
As per your picture, you are using binary sensors, this code is made for the VL53L0X sensors that measure distance.
it should not dificult to acomodate it to binary sensors. I’ll take a look tomorrow, is too late now and my brain is not working.
I amended like below. It now works better. But I have 1 strange behavior. When I test the setup it counts well one way and also the other way. But when I count let’s say forward it counts and when I do backward it misses the last one and vice versa. So lets say someone walks in it counts it, but walking out not and the wen walking in and out it does not count it anymore unless a second one passes. Get me :)?
globals:
- id: seq1
type: int
restore_value: no
initial_value: '0'
- id: seq2
type: int
restore_value: no
initial_value: '0'
- id: seq3
type: int
restore_value: no
initial_value: '0'
- id: seq4
type: int
restore_value: no
initial_value: '0'
- id: count
type: int
restore_value: no
initial_value: '0'
- id: inside_previous_value
type: bool
restore_value: no
initial_value: 'false'
- id: outside_previous_value
type: bool
restore_value: no
initial_value: 'false'
binary_sensor:
- platform: gpio
pin:
number: GPIO21
mode: INPUT_PULLUP
id: sens_1
name: "Sensor 1"
device_class: motion
# internal: true
- platform: gpio
pin:
number: GPIO22
mode: INPUT_PULLUP
name: "Sensor 2"
id: sens_2
device_class: motion
# internal: true
- platform: template
id: inside_door_sensor
name: "Inside Door Sensor"
lambda: !lambda |-
if((id(sens_1).state < 1) != id(inside_previous_value)){
id(inside_previous_value) = (id(sens_1).state < 1);
if(((id(sens_1).state < 1) == false) && ((id(sens_2).state < 1) == false)){
id(seq1) = id(seq2);
id(seq2) = id(seq3);
id(seq3) = id(seq4);
id(seq4) = 0;
}else if(((id(sens_1).state < 1) == false) && ((id(sens_2).state < 1) == true)){
id(seq1) = id(seq2);
id(seq2) = id(seq3);
id(seq3) = id(seq4);
id(seq4) = 1;
}else if(((id(sens_1).state < 1) == true) && ((id(sens_2).state < 1) == false)){
id(seq1) = id(seq2);
id(seq2) = id(seq3);
id(seq3) = id(seq4);
id(seq4) = 2;
}else if(((id(sens_1).state < 1) == true) && ((id(sens_2).state < 1) == true)){
id(seq1) = id(seq2);
id(seq2) = id(seq3);
id(seq3) = id(seq4);
id(seq4) = 3;
}
if((id(seq1) == 1) && (id(seq2) == 3) && (id(seq3) == 2) && (id(seq4) == 0)){
id(count) ++;
id(people_in).publish_state(id(count));
}else if((id(seq1) == 2) && (id(seq2) == 3) && (id(seq3) == 1) && (id(seq4) == 0)){
id(count) --;
if(id(count) < 0){
id(count) = 0;
}
id(people_in).publish_state(id(count));
}
}
return id(sens_1).state < 1;
- platform: template
id: outside_door_sensor
name: "Outside Door Sensor"
lambda: !lambda |-
if((id(sens_2).state < 1) != id(outside_previous_value)){
id(outside_previous_value) = (id(sens_2).state < 1);
if(((id(sens_1).state < 1) == false) && ((id(sens_2).state < 1) == false)){
id(seq1) = id(seq2);
id(seq2) = id(seq3);
id(seq3) = id(seq4);
id(seq4) = 0;
}else if(((id(sens_1).state < 1) == false) && ((id(sens_2).state < 1) == true)){
id(seq1) = id(seq2);
id(seq2) = id(seq3);
id(seq3) = id(seq4);
id(seq4) = 1;
}else if(((id(sens_1).state < 1) == true) && ((id(sens_2).state < 1) == false)){
id(seq1) = id(seq2);
id(seq2) = id(seq3);
id(seq3) = id(seq4);
id(seq4) = 2;
}else if(((id(sens_1).state < 1) == true) && ((id(sens_2).state < 1) == true)){
id(seq1) = id(seq2);
id(seq2) = id(seq3);
id(seq3) = id(seq4);
id(seq4) = 3;
}
if((id(seq1) == 1) && (id(seq2) == 3) && (id(seq3) == 2) && (id(seq4) == 0)){
id(count)++;
id(people_in).publish_state(id(count));
}else if((id(seq1) == 2) && (id(seq2) == 3) && (id(seq3) == 1) && (id(seq4) == 0)){
id(count)--;
if(id(count) < 0){
id(count) = 0;
}
id(people_in).publish_state(id(count));
}
}
return id(sens_2).state < 1;
sensor:
- platform: template
id: people_in
name: "People Inside"
lambda: !lambda |-
return id(count);
This should do the work
I added a 10ms de-bounce for your binary sensors and treated as a boolean on the “if” statements (on my original code I treated as a number)
globals:
- id: seq1
type: int
restore_value: no
initial_value: '0'
- id: seq2
type: int
restore_value: no
initial_value: '0'
- id: seq3
type: int
restore_value: no
initial_value: '0'
- id: seq4
type: int
restore_value: no
initial_value: '0'
- id: count
type: int
restore_value: no
initial_value: '0'
- id: inside_previous_value
type: bool
restore_value: no
initial_value: 'false'
- id: outside_previous_value
type: bool
restore_value: no
initial_value: 'false'
binary_sensor:
- platform: gpio
pin:
number: GPIO21
mode: INPUT_PULLUP
id: sens_1
name: "Sensor 1"
device_class: motion
filters:
- delayed_on: 10ms
# internal: true
- platform: gpio
pin:
number: GPIO22
mode: INPUT_PULLUP
name: "Sensor 2"
id: sens_2
device_class: motion
filters:
- delayed_on: 10ms
# internal: true
- platform: template
id: inside_door_sensor
name: "Inside Door Sensor"
lambda: !lambda |-
if(id(sens_1).state != id(inside_previous_value)){
id(inside_previous_value) = id(sens_1).state;
if((id(sens_1).state == false) && (id(sens_2).state == false)){
id(seq1) = id(seq2);
id(seq2) = id(seq3);
id(seq3) = id(seq4);
id(seq4) = 0;
}else if((id(sens_1).state == false) && (id(sens_2).state == true)){
id(seq1) = id(seq2);
id(seq2) = id(seq3);
id(seq3) = id(seq4);
id(seq4) = 1;
}else if((id(sens_1).state == true) && (id(sens_2).state == false)){
id(seq1) = id(seq2);
id(seq2) = id(seq3);
id(seq3) = id(seq4);
id(seq4) = 2;
}else if((id(sens_1).state == true) && (id(sens_2).state == true)){
id(seq1) = id(seq2);
id(seq2) = id(seq3);
id(seq3) = id(seq4);
id(seq4) = 3;
}
if((id(seq1) == 1) && (id(seq2) == 3) && (id(seq3) == 2) && (id(seq4) == 0)){
id(count) ++;
id(people_in).publish_state(id(count));
}else if((id(seq1) == 2) && (id(seq2) == 3) && (id(seq3) == 1) && (id(seq4) == 0)){
id(count) --;
if(id(count) < 0){
id(count) = 0;
}
id(people_in).publish_state(id(count));
}
}
return id(sens_1).state;
- platform: template
id: outside_door_sensor
name: "Outside Door Sensor"
lambda: !lambda |-
if(id(sens_2).state != id(outside_previous_value)){
id(outside_previous_value) = id(sens_2).state;
if((id(sens_1).state == false) && (id(sens_2).state == false)){
id(seq1) = id(seq2);
id(seq2) = id(seq3);
id(seq3) = id(seq4);
id(seq4) = 0;
}else if((id(sens_1).state == false) && (id(sens_2).state == true)){
id(seq1) = id(seq2);
id(seq2) = id(seq3);
id(seq3) = id(seq4);
id(seq4) = 1;
}else if((id(sens_1).state == true) && (id(sens_2).state == false)){
id(seq1) = id(seq2);
id(seq2) = id(seq3);
id(seq3) = id(seq4);
id(seq4) = 2;
}else if((id(sens_1).state == true) && (id(sens_2).state == true)){
id(seq1) = id(seq2);
id(seq2) = id(seq3);
id(seq3) = id(seq4);
id(seq4) = 3;
}
if((id(seq1) == 1) && (id(seq2) == 3) && (id(seq3) == 2) && (id(seq4) == 0)){
id(count)++;
id(people_in).publish_state(id(count));
}else if((id(seq1) == 2) && (id(seq2) == 3) && (id(seq3) == 1) && (id(seq4) == 0)){
id(count)--;
if(id(count) < 0){
id(count) = 0;
}
id(people_in).publish_state(id(count));
}
}
return id(sens_2).state;
sensor:
- platform: template
id: people_in
name: "People Inside"
lambda: !lambda |-
return id(count);
Thank you for publishing your code. I would like to use M5Stack distance sensors M5StickC ToF HAT (VL53L0X). I guess it should work.
Yeah, it should work, it uses the same chip.
Thank you!
Do you have a photo or wire diagram of the hardware? I’m very interested trying to do this at my house.
You could just implement the two beams as the A and B lines of a Rotary Encoder.
The built-in state machine would then tell your code when a person moved inward, or outward, through the beams, just as it can tell when the rotary encoder is turned one way or the other.
And it’d all be handled in one simple entity reference.
I’m testing your code and it works very well.
I have the sensors next to each other at a distance of 15 cm.
Question: you have been tested at the smallest distance it is possible to place sensors next to each other so that they do not affect each other.
Thank you
Hey @Shannondalebreaux, no, I don’t have any diagrams, but it is easy to figure it out from the code.
I’m going to omit the power part of it because it just connecting the correct voltage to the Vin pin for and the ground to the GND pin for each device.
The sensors have 3 pins for data and control, the Enable pin is setup as follow:
- platform: vl53l0x
name: "Sensor 1"
id: sens_1
i2c_id: bus_a
address: 0x41
update_interval: 50ms
enable_pin: GPIO25
timeout: 500us
internal: true
- platform: vl53l0x
name: "Sensor 2"
id: sens_2
i2c_id: bus_a
address: 0x42
update_interval: 50ms
enable_pin: GPIO32
timeout: 500us
internal: true
So you connect the enable pin of the sensor 1 to the GPIO25 of the ESP32 and the enable pin of the sensor 2 to the GPIO32.
Then the data pins for both sensors goes like this:
i2c:
sda: GPIO21
scl: GPIO22
scan: True
id: bus_a
Where the SDA pin of both sensors goes to the GPIO21 and the SCL to the GPIO22.
and that should be it if you are using an ESP32 and the vl53l0x sensor. You can modify the code according to your setup.
@glyndon Yeah, that was my first approach, but it didn’t work consistently. Maybe I didn’t coded it right.
@pepe59 I’m glad you find this code working good for you.
Yes, I have them separated by 6cm each other and I installed them into a door frame to count people that go in and out of my lab. It works very well.
Thank you very much. So far, I’m testing at the kitchen door on the shelf and I wanted to find out the distance from each other when I use other sensors in the door frame. Haven’t you looked at the VL53L1X sensor? Unfortunately, it does not yet have support in ESPhome, but it would also be an interesting solution.