Help me fix this part of code

hi can anyone help me fix this part of code

if (dis_a > 90 && dis_b > 90 && flag1 == 1 && flag2 == 1) {
    flag1 = 0, flag2 = 0;
    delay(3000);
  }

using delay here works for counting people more stable but this just stops the whole animations running,
soo tried to replace the delay with sensor_timeout soo it can stop making reading for a specifc time

if (dis_a > 90 && dis_b > 90 && flag1 == 1 && flag2 == 1) {
    flag1 = 0, flag2 = 0;
    //delay(2000);
    sensor_sleep = true;
    sensor_sleep_start = millis();
  }

but this just doesn't work. and its not stopping the sensors take reading for the specific time.
can anyone help me fix this.
Complete code:

#include <ShiftRegister74HC595.h>
// create a global shift register object
// parameters: <number of shift registers> (data pin, clock pin, latch pin)
ShiftRegister74HC595<2> sr(14, 16, 15);
#define e_s1 2 //echo pin
#define t_s1 3 //Trigger pin

#define e_s2 4 //echo pin
#define t_s2 5 //Trigger pin

#define TOUPON 1
#define TODOWNOFF 2
#define NONE -1
int anim_state = NONE;
int last_anim_state = -1;
unsigned long last_millis = 0;

long dis_a = 0, dis_b = 0;
int flag1 = 0, flag2 = 0;
int person = 0;
int counter = 0;
const int sensor_sleep_mils = 5000;
unsigned long sensor_sleep_start = 0;
bool sensor_sleep = false;

void peopleCount();
void animate_state();
//**********************ultra_read****************************
void ultra_read(int pin_t, int pin_e, long &ultra_time) {
  long time;
  pinMode(pin_t, OUTPUT);
  pinMode(pin_e, INPUT);
  digitalWrite(pin_t, LOW);
  delayMicroseconds(2);
  digitalWrite(pin_t, HIGH);
  delayMicroseconds(10);
  time = pulseIn (pin_e, HIGH);
  ultra_time =  time / 29 / 2;
}


void setup() {
  Serial.begin(9600);// initialize serial communication at 9600 bits per second:
  Serial.println("BOO Staircase Started");
}

void loop() {

  peopleCount();
  animate_state();

}
void peopleCount() {

  ////// check for sensor sleep state and timeout condition
  if (sensor_sleep && millis() > sensor_sleep_start + sensor_sleep_mils )
  {
    return;   // exit the function early thus disabling sensor reading
  }
  else
  {
    sensor_sleep = false;  // sensor sleep is over so set the bool to false and let the function continue
  }

  //*************************
  ultra_read(t_s1, e_s1, dis_a); delay(30);
  ultra_read(t_s2, e_s2, dis_b); delay(30);
  //*************************

  Serial.print("da:"); Serial.println(dis_a);
  Serial.print("db:"); Serial.println(dis_b);

  if (dis_a < 90 && flag1 == 0) {
    flag1 = 1;
    if (flag2 == 0) {
      person = person + 1;
    }
  }

  if (dis_b < 90 && flag2 == 0) {
    flag2 = 1;
    if (flag1 == 0) {
      person = person - 1;
    }
  }

  if (dis_a > 90 && dis_b > 90 && flag1 == 1 && flag2 == 1) {
    flag1 = 0, flag2 = 0;
    //delay(2000);
    sensor_sleep = true;
    sensor_sleep_start = millis();
  }


  Serial.print("Have Person: ");
  Serial.print(person);
  Serial.print("  ");

  Serial.print("Light is ");
  if (person < 0) {
    person = 0;
  }
  if (person == 1 && dis_a < 90 && flag1 == 1 )
  {
    anim_state = TOUPON;
    // for (int i = 0; i < 16; i++) {
    //   sr.set(i, HIGH);
    //   delay(400);
    //   Serial.print("turn on lights ");
    //   Serial.println(i);
    }
  
  if (person == 0 && dis_b < 90 && flag2 == 1)
  {
    anim_state = TODOWNOFF;
    // for (int i = 15; i >= 0; i--) {
    //   sr.set(i, LOW);
    //   delay(400);
    //   Serial.print("turn off lights ");
    //   Serial.println(i);
    }
  }


void animate_state() {

  if (anim_state == TOUPON) {
    //last_millis = millis();
    if (anim_state != last_anim_state) { // state just changed, lets set the counter to 0
      counter = 0;
      sr.set(counter, HIGH);
      Serial.println("starting toupon ");
      last_millis = millis();
    } else if ( millis() > last_millis + 800 ) {   // continue the animation if the time interval is up
      counter++;
      sr.set(counter, HIGH);
      Serial.print(" lights on ");
      Serial.println(counter);
      last_millis = millis();
    }
    if ( counter >= 15 ) anim_state = NONE;

  }
  if (anim_state == TODOWNOFF) {
    //last_millis = millis();
    if (anim_state != last_anim_state) { // state just changed, lets set the counter to 0
      counter = 15;
      sr.set(counter, LOW);
      Serial.println("starting todownoff ");
      last_millis = millis();
    } else if ( millis() > last_millis + 800 ) {   // continue the animation if the time interval is up
      counter--;
      sr.set(counter, LOW);
      Serial.print(" lights off ");
      Serial.println(counter);
      last_millis = millis();
    }
    if ( counter == 0 ) anim_state = NONE;

  }
  last_anim_state = anim_state;
}

H boopesh boo,

it is not clear to my what you want to try do do.
Can you please describe in detail and in normal words

by avoiding all programming terms

the functionality that you want to have?

You have some kind of animation running and the animation shall run all the time
regardless of what the other program-functions are doing.

You have some kind of sensor that is sensing the "dis_a-dis_b-flag1-flag2-factor"
(whatever this means ???)

and if certain conditions are fullfilled the sensor shall pausing sensing for 3 seconds???

best regards Stefan

1 Like

Yeah pause sensor for 3 secs.. And that's where the animation stops as delays stops the whole sketch... I want to replace that delay with millis or Boolean

as an everyday example with easy to follow numbers
delay() is blocking. As long as the delay is "delaying" nothing else of the code can be executed.
Now there is a technique of non-blocking timing.
The basic principle of non-blocking timing is fundamental different from using delay()

You have to understand the difference first and then look into the code.

otherwise you might try to "see" a "delay-analog-thing" in the millis()-code which it really isn't
Trying to see a "delay-analog-thing" in millis() makes it hard to understand millis()
Having understood the basic principle of non-blocking timing based on millis() makes it easy to understand.

imagine baking a frosted pizza
the cover says for preparation heat up oven to 200°C
then put pizza in.
Baking time 10 minutes

You are estimating heating up needs 3 minutes
You take a look onto your watch it is 13:02 (snapshot of time)
You start reading the newspaper and from time to time looking onto your watch
watch shows 13:02. 13:02 - 13:02 = 0 minutes passed by not yet time
watch shows 13:03. 13:03 - 13:02 = 1 minute passed by not yet time
watch shows 13:04. 13:04 - 13:02 = 2 minutes passed by not yet time

watch shows 13:05 when did I start 13:02? OK 13:05 - 13:02 = 3 minutes time to put pizza into the oven

New basetime 13:05 (the snapshot of time)
watch 13:06 not yet time
watch 13:07 not yet time
watch 13:08 not yet time (13:08 - 13:05 = 3 minutes is less than 10 minutes
watch 13:09 not yet time
watch 13:10 not yet time
watch 13:11 not yet time
watch 13:12 not yet time
watch 13:13 not yet time
watch 13:14 not yet time (13:14 - 13:05 = 9 minutes is less than 10 minutes
watch 13:15 when did I start 13:05 OK 13:15 - 13:05 = 10 minutes time to eat pizza (yum yum)

You did a repeated comparing how much time has passed by
This is what non-blocking timing does

In the code looking at "How much time has passed by" is done

currentTime - startTime >= bakingTime

bakingTime is 10 minutes

13:06 - 13:05 = 1 minute >= bakingTime is false
13:07 - 13:05 = 2 minutes >= bakingTime is false
...
13:14 - 13:05 = 9 minutes >= bakingTime is false
13:15 - 13:05 = 10 minutes >= bakingTime is TRUE time for timed action!!

So your loop() is doing

void loop()
// doing all kinds of stuff like reading the newspaper

if (currentTime - previousTime >= period) {
previousTime = currentTime; // first thing to do is updating the snapshot of time
// time for timed action
}

it has to be coded exactly this way because in this way it manages the rollover from Max back to zero
of the function millis() automatically

baldengineer.com has a very good tutorial about timing with function millis() too .

There is one paragraph that nails down the difference between function delay() and millis() down to the point:

The millis() function is one of the most powerful functions of the Arduino library. This function returns the number of milliseconds the current sketch has been running since the last reset. At first, you might be thinking, well that’s not every useful! But consider how you tell time during the day. Effectively, you look at how many minutes have elapsed since midnight. That’s the idea behind millis()!

Instead of “waiting a certain amount of time” like you do with delay(), you can use millis() to ask “how much time has passed”?

best regards Stefan

1 Like

i really liked the way you explained stuffs...i really appreciate it

i'm curious

looks like you're using 2 ultra-sound sensors to count the # of people both entering and exiting some space. could you explain how they are physically positioned to do that?

a common practice is 2 optical beams a person needs to cross. a count in/decreases depending on which beam is broken last

with a distance measure, i would have expected there to be 2 separate thresholds: one for close and one for far where the two thresholds are different values

a count would in/decrease when there is a transition from the one threshold to the other (not multiple occurrences of just one threshold being exceded)

1 Like

Yeah... Different threshold works when you walk in at short distance and walk out at long distance.. But in my project sonic sensors are placed at 10cms apart and they both get triggered at the same distance thresholds.

why?

FWIW that won’t work with cats, who can learn, it seems, to carefully break the beams in any order (or not at all) to further their need to avoid being tracked.

a7

I think the meaning is different:
You have two ultra-sonic sensors A and B
example a person walking in

P-->>------A------------B
the measured threshold of A will be crossed as the first one
the measured threshold of B will be crossed as the second one
==> person walks in

with the person walking out it is vice versa
------A------------B------<< P
the measured threshold of A will be crossed as the second one
the measured threshold of B will be crossed as the first one

Your project has an important physical dimension so giving information about this physical dimension would help a lot.

You are a person who always asks for some details.

details overview:
We are talking about details. Please give an overview over your whole project.
in mimimum 70% of all cases knowing the whole thing offers completely different and much better working solutions.

here is an analogon that shall show what can happen if just ask for details:

Newbee: "I want to do better cutting please help me sharpening. " (too less details expert has to ask back)
Expert: Sure I can help you. What kind of cutting-tool are you using?
Newbee: a scissor.
Expert: OK take this sharpening tool
Newbee: Yeah works great Next question How can I make it to cut faster I need to finish faster.
expert: Motorised scissors.
newbee Yeah works great though still not fast enough.

expert: Ok can you give an overview about what you are cutting.
newbee: the green of a football-arena.
expert: Oha! take a big mowing tractor with a seven boom spindel-mower and GPS-steering

In the beginning the newbee always just told details.
The expert was assuming the newbee knows that his basic approach is well suited.
which turns out to be very bad suited
that's the reason why it is always a good idea to give an overview and to explain what shall happen in the end.

It is up to you to maybe start new from scratch after a lot of fiddling with details trying to make it work reliably or to give an overview and get the help of experts for this kind of problem as a hole thing.

best regards Stefan

1 Like

thanks i fixed my code.....

would you mind posting the working code?

yeah sure..recreated the whole code for better understanding....will post when its finished.