Trying to Make a Bi-directional visitor counter

Good Day!

I’m still new in arduino programming but always try my best to learn something new.

Currently I am trying to make a bi-directional visitor counter using an Arduino Uno and 2 pieces of ultra sonic sensor (HC-SR04). I have managed to make an initial code for my project and manage to make it slightly work. My problem is that sometimes the total visitor/ guest doesn’t increase nor decrease. I am suspecting that there are flaws in my codes. I tried troubleshooting using the serial monitor and I think that the problem is at this part of my control structure.

int control_1 = 0, control_2 = 0;
int oldcontrol_1 = 0, oldcontrol_2 = 0;
int total = 0;

void setup()
{
  Serial.begin(9600);
}
void loop()
{
//PERSON ENTERS THE ROOM

  if (d_1 <= 48)
  {
    control_1 = 1;
  }
  else control_1 = 0;
  if (control_1 != oldcontrol_1)
  {
    sensor(trig_2, echo_2, d_2);
    if (d_2 <= 48)
    {
      control_2 = 1;
    } else control_2 = 0;
    if (control_2 != oldcontrol_2)
    {
      total = total + 1;
    }
  }
}

So if the first if statement is true, control_1’s value becomes 1 right? So by observing the results from the serial monitor when the first if statement becomes true and control_1 = 1 and what should happen next is that the next if statement is executed because the condition becomes true right? Now what my conclusion on why the total count of visitors/ guests does not increase because once the first if statement becomes false count_1 now has the value of 0.

What I am thinking of next as a solution for my problem is to know when was the two sensor active. For example if a person enters the room. Sensor 1 was active last 1 second and sensor 2 was active last 0.5 second so “if sensor1lastActivetime > seonsor2lastActivetime then the total count of the visitor should increase” and vice versa for exit.

Is there a way for it to be coded just like that? If there are better ways that it can be coded so that it can function more accurately I’d be grateful for the help.

Here is my full code for my project and I’ll be attaching a picture of my initial setup of my project.

#define trig_1 2
#define echo_1 3
#define trig_2 4
#define echo_2 5

float d_1, d_2;
int control_1 = 0, control_2 = 0;
int oldcontrol_1 = 0, oldcontrol_2 = 0;
int total = 0;

void setup()
{
  Serial.begin(9600);
}

void loop()
{

  sensor(trig_1, echo_1, d_1);
  delay(30);
  sensor(trig_2, echo_2, d_2);
  delay(30);

//PERSON ENTERS THE ROOM

  if (d_1 <= 48)
  {
    control_1 = 1;
  }
  else control_1 = 0;
  if (control_1 != oldcontrol_1)
  {
    sensor(trig_2, echo_2, d_2);
    if (d_2 <= 48)
    {
      control_2 = 1;
    } else control_2 = 0;
    if (control_2 != oldcontrol_2)
    {
      total = total + 1;
    }
  }
  
//PERSON EXITS THE ROOM
  if (d_2 <= 48)
  {
    control_2 = 1;
  }
  else control_2 = 0;
  if (control_2 != oldcontrol_2)
  {
    sensor(trig_1, echo_1, d_1);
    if (d_1 <= 48)
    {
      control_1 = 1;
    } else control_1 = 0;
    if (control_1 != oldcontrol_1)
    {
      total = total - 1;
    }
  }

  Serial.print(control_1);
  Serial.print(control_2);
  Serial.print("   Total:  ");
  Serial.println(total);

}
void sensor(int trig, int echo, float &distance)
{
  float duration;
  pinMode(trig, OUTPUT);
  pinMode(echo, INPUT);

  digitalWrite(trig, LOW);
  delay(20);
  digitalWrite(trig, HIGH);
  delay(50);
  digitalWrite(trig, LOW);

  duration = pulseIn(echo, HIGH);
  distance = (0.013464 * duration) / 2; //inches
}

Thank you for your kindness.

I am not sure I understand the logic behind your program, but when using variables to track "current" and "previous" states, you have to update "previous state" after "current state" has changed.

You have to do something like this:

  if (control_1 != oldcontrol_1)
  {
    //do things
    oldcontrol_1 = control_1;
  }

Welcome and +1 karma for using code tags in your first post.

But

A picture of my initial setup.

We don't like clicking on links to pages full of annoying ads or worse when there is no need to. Simply attach the picture to your post usung the "Attachments and other options" link and it will be displayed as part of your post.

OP, do you want to count enters and exits or actual room occupancy?

I found a single point of count fails, especially with sr04's.

I found ultrasonics with the SR04 is poor.

A sensor such as a 'grid eye' can see people a lot better then a sro04.

If you are very serious about counting people in a room then use TensorFLow. Steep learning curve and requires a 32 bit MCU like a Nano 32 BLE or an ESP32 and the TensorFLow lite library or the ESP32 TensorFlow lite library.

I agree, your first attempt above is just not going to work. Your idea of using "timestamps" is a better way to go. But your idea isn't quite complete yet. A sensor could be active for an extended period depending how fast a visitor is walking, or they might even pause in front of a sensor. During that time, the Arduino could take several, perhaps hundreds, of readings. You don't want a single visitor to count as hundreds just because they were walking slowly or stopped in front of a sensor. So you need to detect the instant when a sensor changes from not detecting anything to detecting something. That's the moment to record the time (ie. millis()) and decide whether to increment the vistor count. Or maybe the instant the sensor changes from detecting something to detecting nothing. Either could work I think.

@leongjerland

I think I might have miss used those variables sorry. Thank you for your advice

@idahowalker

What I was hoping to do is to count the total room occupancy depending on how many person enters or exit the room.
I used SR04 because it is the only sensor available in our market and based on what i have researched on the web an ultrasonic sensor works more better and is more reliable than an IR sensor and that is why I used an SR04.

I am new in arduino programming so regarding TensorFlow I don’t have any much idea about it yet. Thank you for your suggestion and response.

The cone angle of an SR04 is 15 degrees. That's a wide angle of measurement.

A TOF sensor in before the door and after the door can produce direction of people movement. A grid eye can 'say' if the reason for a trigger is a heat source at or above x degrees.

I use a TFMiniP as eyes to a hexapod. The TFMiniP 'sees' very well and does not produce all the false readings that a SR04 will.

I have a room with automatic lights. When the person enters the room, lights on. I use a GridEye , a AMG8833, to detect that the person is in the room, keep the lights on. I like that I can sit very still but the grideye "knows" I'm there.

@PaulRB

I know the attached code in this thread is already my 2nd attemp on fixing my first code.

My first code on this counter which I will attach at the end of this reply has the problem that when a person stands still on the first sensor it just keeps on reading and counting just as you have said a single visitor counts to a hundred so started fixing my first program and this is what i ended up the one attached to this thread.

So Running thhis program fixed my problem of counting 1 visitor as hundred and then the next problem arrived. The problem is that sometimes the counter doesn't count/ increment, more like a 60/40. 60% of the time it counts and 40% it does not. From what you have said the solution to this problem is to detect the instant it changes from detecting nothing to detecting something and record the time it was last active.

So for example sensor 1 which is the first sensor the person passes-by detected something last few millis ago and the next sensor he passes-by which is sensor 2 detected something last maybe a few microsecs ago. In this case create a condition whether if sensor1_time > sensor2_time then that is the moment to increment the visitor count. And for exit just do the opposite

but sadly I don't know where to start on how to implement that program. I keep on browsing the web on how to make a code this matter but I can't find anything that is why I tried posting a thread here.

p.s. sorry for attaching a link. the "Attachments and other options" does not work for me I don't know why.

@Idahowalker

What I am trying to make here is just what you did to your room. I enter the room, the room knows that someone is inside. Is the room dark? then if it is lights turns on if is not then it remains off. I have manage to program this correctly already. The only issue I am facing now is the inaccuracy of the counter. I am only creating this arduino project to be submitted in school and so I chose the budget friendly path which is the SR04. I know that my code for my counter can be improved to boost it's accuracy a little but being a newbie in arduino programming I don't know where to start with my new idea and what PaulRB suggested.

the "Attachments and other options" does not work for me

Did you see the error message

This function does not work for user iskadoosh

?

With respect to counting, I wonder if you are asking too much from an SR04, it appears you are expecting a return echo from a body entering or leaving a room, within 48" of the sensor. Once detected, start a tally process. Have you done the simple experiment of counting a body moving in or out of the room with just one sensor to see if the sensor picks up the body 100% of the time, at all speeds, and all entry angles?

Ultrasonic energy can be absorbed and dispersed by cloth. I have used terry cloth to mask echo returns from a target's support. The texture of the cloth will have a major impact on sound energy loss. In addition, the angle the body presents to the beam is also critical. Most sound energy reflected from a highly irregular shape may never make it back to the transducer to trigger a distance. And although the beam angle is often stated as 15 degrees, the angle is highly dependent on distance and angle of the object to the sensor transducers. For even a flat hard object normal to the beam, the beam angle at which sound pressure is sufficient to still trigger an echo narrows substantially within a couple of meters from the sensor.

If indeed the problem is a detection issue, would a better alternative be too look for a negative distance response. Monitor the distance to a fixed object in the room(s)? When that distance changes, out of a certain small range, trigger your count.

@garydyr

Maybe I am really asking too much from an SR04 and not considering factors that may affect the receiving of an echo. I have already tried using a single SR04 and i didn't saw any problem in counting.

I had been thinking that since my objective is not to measure accurate distance and my objective is to detect if someone enters the door or exit would it better if try using and IR sensor rather than an SR04? Or is SR04 more reliable than an IR sensor and I should remain on using the SR04?

The idea of PaulRB of using times stamps is promising but I don't know how to use millis().

What I am looking forward to on what to happen is like this.

2 sensor beside each other for about 6" to 8" apart at an entrance/ door

Person enters room -----> Person passes the first sensor so from "no one detected state" to "Someone was detected state" and returns back to "no one detected state" (start recording elapsed time, "last time it was active") ----> person passes the 2nd sensor so from "no one detected state" to "someone detected state" and back to "No one detected state" ( start recording elapsed time, last time it was active)

So considering someone entered the room "elapsed time" from the moment sensor 1 was "last active" will be longer than the time from sensor 2s "elapsed time between it was last active" so Total will increment. Vice versa for exit.

Since I have read a few examples and functions of millis() and I know the basics on how to use them like using them as delay() or using them to measure how long a button was pressed. Still I don't know how to use millis() to my idea of measuring the time it was "last active".

Can anyone one help me or show me a sample on how to code the logic behind this? Thank you.

iskadoosh:
2 sensor beside each other for about 6" to 8" apart at an entrance/ door

Assuming well behaved humans who aren't going to try to jigger the system by hopping around on pogo sticks or somesuch nonsense and excluding dogs and other wildlife or interference from galactic cosmic rays, consider a quadrature arrangement.

Use the sensor signals as A-B to determine direction.

YMMV

2 sensor beside each other for about 6" to 8" apart at an entrance/ door

I wonder if you have considered the trigger timings on the sensor arrangements. Without knowing whether the sensors are aimed so their centerlines are 6-8 inches apart, or the sensor centerlines are angled very far apart, I would suggest you consider some of the timings you have to wrestle with:

From here:
https://uglyduck.vajn.icu/ep/archive/2014/01/Making_a_better_HC_SR04_Echo_Locator.html

I see it takes just under 0.5 ms to trigger and send out the 8 ultrasonic pulses.
Sound will travel ~34.3 cm/ms.
The typical walking speed of a human is 1.4 m/s, or 0.14 cm/ms.
Assuming a reliable echo from the person, and the person is 50 cm from the sensor (~20") it will take. ~ 2ms to get a response for the first sensor. (100 cm round trip for sound travel). So a person would travel 0.24 cm. Of course, this does not take into account any cpu delays.

If I am interpreting your code correctly, you trigger a sensor HIGH, and delay for 50 ms, then put the trigger pin LOW. You then monitor the echo pin using pulseIn(…), looking for a HIGH to get the time interval. The SR-04 expects something around a 10 microsecond HIGH pulse to start a cycle. Again, if I am interpreting the code correctly, you are starting to look for a return echo from an object 25 ms, or greater than ~8.6 meters away, Did you mean to use delaymicroseconds() instead of delay()?

The only issue I am facing now is the inaccuracy of the counter

Yes you and everyone else trying the same thing. The only way to do this accurately is to have a turnstile the visitors go through. Any other solution is going to be less than 100%. Even professional systems don’t work correctly.

This is one of those problems I first came across in the 60s in my first job. We were trying to determine the occupation rate of the top deck of a bus, so I have been following it over the years. Many manufacturers of sensors claim to have solved the problem but they over process and under delivering.

What ever this is, it is not a beginners project.