GithubHelp home page GithubHelp logo

andrea-fox / peoplecounter Goto Github PK

View Code? Open in Web Editor NEW
94.0 14.0 27.0 4.35 MB

Code for a cheap people counter based on VL53L1X sensor and ESP32/8266

License: The Unlicense

C++ 83.08% C 16.92%
vl53l1x people-counter home-automation esp32 esp8266

peoplecounter's Introduction

This folder is currently archived


ESP people counter

This repository contains a program (to be flashed, for example on an ESP32, using the Arduino IDE) which allows to create a sensor capable of detecting people going in and out of a room. It works using the VL53L1X sensor by ST Microelectronics. The passage detection is then shared through the MQTT protocol and the count of the people in the room is done directly on other platform such as Home Assistant (see the dedicated file for a smooth integration in Home Assistant).

Idea behind the algorithm

The code contains an adaptation of the program STSW-IMG10 (developed by ST Microelectronics), written using the Sparkfun library for VL53L31X.

The library used is from SparkFun and is made for their sensor, however the same code can also be used alongside the Pololu VL53L31X sensor.

The sensor uses the time of flight (ToF) of invisible, eye-safe laser pulses to measure absolute distances independent of ambient lighting conditions and target characteristics like color, shape, and texture (though these things will affect the maximum range). Something is detected in a certain zone, when the distance read by the sensor os lower than the corresponding threshold.

The idea behind the main algorithm counting for people is the following: after defining two different zones, a passage (entrance or exit) is registered only when:

  1. a person is detected in the first zone
  2. a person is detected in both zones simultaneously
  3. a person is detected in the second zone
  4. no person are detected in both zones

Then, depending on which are the first and the second zone, the movement will be either registered as an entrance or an exit.

Hardware

Sensor

As previously stated, the library used to write the code is built for the Sparkfun Distance Sensor, but also works using the Pololu VL53L31X sensor. It probably should also work with other VL53L1X sensors, however I've never tried it.

Board

The following tables contain the necessary wire connections, when using certain boards.

5V boards

(including Arduino Uno, Leonardo, Mega)

Arduino   VL53L1X board
-------   -------------
     5V - VIN
    GND - GND
    SDA - SDA
    SCL - SCL

The Pololu sensor can also be connetced to 3.3V boards, such as the Arduino Due.

Clearly, to use the MQTT functionalities one has to use a board which supports WiFi connection, such as ESP32: in this case, the connections are the following:

ESP32

                    ESP32   VL53L1X board
-------------------------   -------------
                      3V3 - VIN
                      GND - GND
     SDA (pin 42, GPIO21) - SDA
     SCL (pin 39, GPIO22) - SCL

The sensors from Pololu and Adafruit can also be connected to the 5v pin (VIN)

ESP8266

It is also possible to use an ESP8266, using, for example, the following connections: (in that case, use the code specific for this board)

                  ESP8266   VL53L1X board
-------------------------   -------------
                      3V3 - VIN
                      GND - GND
                       D2 - SDA
                       D1 - SCL

How to adapt the code to your case

The sensor can be mounted on the top of a door frame or on the side. It has been observed that if the door is wide it is more convenient to mount the sensor on the side.

WiFi information

In order to connect to the WiFi, one has to specify the name of the WiFi network, its password, the MQTT broker address and ots port, the MQTT username and the corresponding password. All this values have to inserted at the beginning of the code, in the corresponding lines.

Parameters one might want to set

In the first few lines of the code in the main folder, there are a few parameters which can be modified: (in the parentheses, are indicated the default values)

  • devicename (name_for_this_device)
  • threshold_percentage (80)
  • update_raw_measurements (false)
  • advised_orientation_of_the_sensor (true)
  • save_calibration_result (true)
  • short_distance_threshold (1300)
  • delay_between_measurements_long (50)
  • time_budget_in_ms_long (50)
  • delay_between_measurements_short (20)
  • time_budget_in_ms_short (20)

Some parameters areavailable only in the ESP32 version.

Name of the device

It indicates the room in which the sensor is going to be positioned. It will simplt change the MQTT topics and will help when multiple sensors are placed around the house.

Threshold percentage

After mounting the sensor, it detects automatically the height at which it is situated. When the sensor is working, a person is detected if the distance measured is below a certain threshold, hence defining the right thresholds is pivotal to guarantee a correct functioning of the whole system. It has been observed that having as threshold a value which is 80% of the distance measured in general produces good results, however one might observe that is his sistuation another value of the threshold is better.

Update raw measurements

In the initial phase, or when debugging, it can be useful to read the distance measured every 100 ms by the sensor, however in general thish is not useful and produces an useless cinsumption of the resources. This value has to be set to true if one wants to read the distances measured, however the advice is to hold that to false.
One can change this value through MQTT using the command "update_raw_measurement".

Advised orientation of the sensor

This value is going to deterin the center of each zone of detection and has to be true if the sensor is positioned as in the following image:

The arrow indicates the direction of the people passing under the sensor.

Save calibration result

If this value is true, then the results of the calibration of the zones are going to be stored in the EEPROM memory, hence if the ESP is turned off no data is going to be lost. If false, every time the sensor is turned on, a new calibraion is launched, however that is useless if the sensor is always in the same position. A recalibration can still be called using the MQTT command (see the integration with Home Assistant file)

Short distance threshold

When the distane measured in one of the zones is below this threshold (exoressed in millimeters) the sensor uses the short distance mode, which allows more frequent measurements and better performances. The VL53L1X sensor supports short distance mode only if the distance is below 1300 mm

Measurements time parameters

These parameters set the time the sensor takes to do a measurements (in milliseconds) and the following delay between two different measurements. The user can define two different values: one for the longRange mode and one for the shortRange mode

Additional information

Additional information about the parameters used in the code can be found in the additional_information.md file in the manual_configuration folder

How to invert the two zones

If you observe that when you get in a room the number of people inside it decreases, while it increases when you get out it means that the values of the centers are inverted. to solve this issue, you can simply invert the values 1 and 2 in the automations which regulate the number of people in the integration_with_home_assistant.md file.

Issues due to sunlight

As stated in the datasheet from the creators of the sensor, the VL53L1X has (much) less accuracy when there is a lot of light. Unfortunately it is not possible to eliminate such issue

Case for the sensor

In the case folder you can find an several stl files created by @noxhirsch for a case that fits both the ESP and the VL53L1X sensor.

Discord server

If you want to discuss about the idea of finding the ultimate room presence sensor, feel free to join the dedicate Discord server, created by @DutchDeffy: https://discord.gg/65eBamz7AS

peoplecounter's People

Contributors

andrea-fox avatar lc7894 avatar noxhirsch avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

peoplecounter's Issues

Possible enhancement with 4 ROIs

Hi @Andrea-Fox and @noxhirsch, Thanks so much for what you have done here!

I have been thinking of possible ways to make the sensor more accurate on wider doorways.

My thinking behind this is to use more than 2 ROIs but rather use 4 zones of 8x8 two would be in the front zone and two in the back zone. ( Note I haven't had much success with an ROI set to 8 x 16 but 8x8 works well but sometimes misses counts if you approach a doorway from an angle)

I am working on trying to implement this but would be interested in your opinion on the idea?

I was considering two possible ways of implementing this.

option 1: feed the two values from the front zone into the counting algorithm at the same time and the same for the back zone
option 2: feed the lowest measurement reading from the two zones in the front and back into the algorithm.

Thank you
Mark

Feature request: Use a single MQTT publisher topic and ArduinoJson.h

Hi Andrea,

Here I'm with a suggestion on how the code could be improved or functionality can be added to your code. I thought of using a single MQTT publish topic and publish all the data in json format to that. Instead of using 3 topics. That way configuring can be a bit more easy. I have already something set up. The idea is using global variables, instead of passing everything data related as a parameter to the specific functions. You would need to define those variables tho. So, for example.

/******************************** MQTT TOPIC(s) change these to your liking *******************************/
#define mqtt_topic "/peopleCounter/" // one publisher topic 

/******************************** VARIABLES FOR 'CARRYING' THE DATA *******************************/

String Passage_Event;

uint16_t Distance;

int LocalPeopleCount;

The general publish function can something like this.

void publishData(){
  StaticJsonDocument<300> doc;

  doc["passage_event"] = Passage_Event;

  JsonObject distance = doc.createNestedObject("distance");
  distance["zone"] = Zone;
  distance["measurement"] = Distance;

  doc["local_people_count"] = LocalPeopleCount;

  char buffer[300];
  serializeJson(doc, buffer);
  Serial.print(String(buffer));

  client.publish(mqtt_topic, buffer, true);
}

The data first gets formatted into a json before it gets published to the MQTT server.
Then after an entry (peoplecounter.ino line 295) you can add these lines to publish the data.

        if ((PathTrack[1] == 1)  && (PathTrack[2] == 3) && (PathTrack[3] == 2)) {
          // this is an entry
          Passage_Event = "entry";
          LocalPeopleCount++;
          publishData();
          }

You can use the same method for for the exit event and distance measuring.

And an example of the JSON data can consequently look like this.

{"passage_event":"entry",
"distance":{"zone":1,"measurement":2115}
"local_people_count":1}

Maybe I'm completely wrong and does this change only make things more difficult. Also it depends on how the users use the code of course. Anyway, it's just a suggestion. If it would help I can also share my 'version' of your code, where I did some stuff differently. (Using a cheap aliexpress time of flight sensor which has a different I2C address.)

Count People at two entrance

Hello @Andrea-Fox ,

I would like to use your code to count people on a staircase. This would require using two sensors on an ESP32, as people can leave the stairs at the beginning and end. The use of two sensors is possible after a research with i2c.
Can the VL53L0X also be used instead of the VL53L1X?

Best regards TheMBeat

People in the room now: 111227

Hello . is it ok?

: warning: 'RIGHT' defined but not used [-Wunused-variable]
static int RIGHT = 1;
^

One person has entered in the room. People in the room now: 111227
One person has exited the room. People in the room now: 71227

ESPHome compatible sketch?

Hello,

Sorry for declaring it as an issue, it's more of a question. Will there be a file available for ESPHome? It's way easier, especially for HomeAssistant to integrate automatically. Thanks!

Code question advised_oriantation_of_the_sensor

Shouldn't the switch...case for advised_orientation_of_the_sensor == false also have break;?

  if (advised_orientation_of_the_sensor){
    
    switch (ROI_size) {
        case 4:
          center[0] = 150;
          center[1] = 247;
          break;
        case 5:
          center[0] = 150;
          center[1] = 247;
          break;
        case 6:
          center[0] = 159;
          center[1] = 239;
          break;
        case 7:
          center[0] = 159;
          center[1] = 239;
          break;
        case 8:
          center[0] = 167;
          center[1] = 231;
          break;
      }
  }
  else{
    switch (ROI_size) {
        case 4:
          center[0] = 195;
          center[1] = 60;
        case 5:
          center[0] = 194;
          center[1] = 59;
        case 6:
          center[0] = 194;
          center[1] = 59;
        case 7:
          center[0] = 193;
          center[1] = 58;
        case 8:
          center[0] = 193;
          center[1] = 58;
  
      }
  }

Possible to use ESP8266 ?

Is it possible to use an ESP8266 instead of a ESP32 or do you need the extra processing power that the ESP32 has ?

Automation Example with Choose

This is another automation example which works with HA >0.113
With that you only need one automation for increasing and decreasing the counter.
Since I don't know if you want to add this to your examples or replace them, I didn't open a PR and post it here instead.

alias: Person Counter
trigger:
  - platform: mqtt
    topic: peopleCounter/serialdata/tx
action:
  - choose:
      - conditions:
          - condition: template
            value_template: '{{ trigger.payload == "1" }}'
        sequence:
          - service: input_number.increment
            entity_id: input_number.people_counter
      - conditions:
          - condition: template
            value_template: '{{ trigger.payload == "2" }}'
        sequence:
          - service: input_number.decrement
            entity_id: input_number.people_counter
mode: single

Using without MQTT

I am a newbie and wanted to use this code without MQTT. want to print people counter directly to serial or to a display. could somebody help me with this?

High power consumption -> not possible to run via battery

I measured the power consumption of the sensor in a setup with an ES8266 NodeMCU and found it to use (on average) 80mA. One of the main reasons for the high power consumption is the WiFi that is always on. Therefore, using a battery as power source is not suitable except you want to change the battery very often. This is a problem when there is no outlet nearby or you don't want to use a cord. According to the docs of the sensor it should be possible to use the deep sleep mode of the ESP and wake it up when someone passes the sensor:

image

I'll just leave this here as a suggestion for further development of the algorithm ๐Ÿ™‚ (Maybe I am able to find a solution on my own, but I have to learn a lot about ESP programing until I reach this point)

Link to the docs: https://www.st.com/resource/en/user_manual/dm00474730-vl53l1x-api-user-manual-stmicroelectronics.pdf

Wifi connection issues

I have tried different ESP32s, different USB-cables, and tried connecting to several networks (2.4Ghz). But I only get the "Sensor online" -message. Then dots, but it never connects to any wifi. Is there any special procedure for connecting to a wifi network besides specifying the sid and password ?

ESP32 & VL53L3CX

Hi, I would like to implement the code using an ESP32 with the VL53L3CX newer sensor. Can you help? Thanks a lot!!!

counter = 1, but never 2

Starting a new topic here.

I used:
people_counter_esp32.ino
the name of my sensor is tof_people_ard

Changed the value 500 to 5000 for wifi timeout.

The ESP32 is succesfully conected to WiFi and MQTT. I can see the topic realtime changing for:
people_counter/tof_people_ard/distance

I do not see any updates for the counter in topic:
people_counter/tof_people_ard/counter

It did work 1 time hower.

mqtt

In above image you can see the MQTT realtime going and on some moment I place my hand before the sensor.

the standard config as in the ino is in my compiled upload. And no matter what I try to place the sensor it counts 2... so the home assistant counter is never updated.

Any help appreciated!

Configure MQTT for HomeAssistant

Ok, I got some more stupid questions. I have a Zigbee2MQTT USB-Stick in my server and also dockers running a Mosquitto MQTT server and another docker running Home Assistant. The Zigbee2MQTT-usb sends everything to the MQTT server and they show up in Home Assistant in Integrations -> MQTT.

In the Mosquitto log I see:

1605812716: New connection from 192.168.0.182 on port 1883.
1605812716: New client connected from 192.168.0.182 as PeopleCounterESP32Client-a164 (p2, c1, k15).

But how do I make the device show up in Home Assistant ?
I tried Adding the :

sensor:
    - platform: mqtt
      name: "People counter"
      state_topic: "peopleCounter/serialdata/tx"

But I get no new devices with or without the sensor added to config.yaml

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.