Using Millis() to control timing of Function

I apologize if there are a million questions relating to the millis() function already, but I really can't seem to figure this out. I am trying to set it up to run after the sensor I am using detects an object within x centimeters away from it, which is passed as an int variable to this if statement. When it detects an object, it needs to change the value of a boolean bit(called obstacle_Bit). I don't think I really understand how to implement millis() in this case (I know how to set it up to make a couple of led's blink at the set timing), and what I am seeing online isn't helping me much. This is what I attempted to do:

int distance;
int objectDetect_State = LOW;
bool obstacle_Bit = 0;

unsigned long objectPreviousMillis = 0;
const long objectInterval = 25;

void setup() {
objectPreviousMillis = millis();

}

void loop() {
distanceDecision();
}

void distanceDecision(){

unsigned long objectCurrentMillis = millis();
if(distance < 29){
if(objectCurrentMillis - objectPreviousMillis >= objectInterval){
objectPreviousMillis = objectCurrentMillis;
if(objectDetect_State == HIGH){
obstacle_Bit = 1;
}else{
obstacle_Bit = 0;
}
}
}
}

And this is the code I am trying to replace, which works perfectly, but, I cannot have the entire program pause completely during this execution:

int distance;
bool obstacle_Bit = 0;

void setup() {
}

void loop() {
distanceDecision();
}

void distanceDecision(){

unsigned long objectCurrentMillis = millis();

if(distance < 29){ //Condition where obstacle is detected less than --cm away
delay(15);
obstacle_Bit = 1;
}else{
obstacle_Bit = 0;
}
}

What does it do that's not what you wanted?

You know what? I am looking at my code again. Maybe it actually is working, but I got the logic backwards. I think when I was using Serial.print to output the values I needed to see if the program was working correctly, I was comparing the wrong things. Looking at it more closely, I think I simply got my logic a little backwards, I am getting the opposite output from what I wanted, but that should be an easy fix. I think. I may or may not have just answered my own question here, though not 100% sure just yet. Kinda feel a little stupid at the moment, thanks for your reply!

I think I am still just confusing myself with millis() since I have only just recently learned how to use it at all, and need to work through my program to eliminate the use of the delay() function anywhere that it is still present.

Honestly, I think I need to work through the code a little bit more before I even know what specifically to ask. My bad. Sorry about that.

Just think about it as your rubber ducking service :grinning:

objectDetect_State ?

if closer than 29
if closer for longer than 25ms

then you have
if(objectDetect_State == HIGH){

it would seem that if you want to blink the lights, you would just change obstacle_Bit
and not need to check for that other thing.

if you comment out that if, then the lights should change state
if you are closer than 29 for over 25ms

if (obstacle_Bit == 0) {
obstacle_Bit = 1;
} else {
obstacle_Bit = 0;
}

or obstacle_Bit=!obstacle_Bit);

Ok, I think I know what went wrong, don't know why just yet, but it appears either my sensor crapped out on me, or I messed up my code somewhere, and ended up calculating nonsense distance values. Will need to troubleshoot that, it was working yesterday. Currently a bit of a garbage in garbage out type of situation I think.

I still might need help though. When the distance < 29 == true, I need the program to hold that condition as true(or the bool obstacle_Bit as true) until the timer has run through. I am currently getting the opposite, and I tested this by increasing the length of the timer to 2500 milliseconds instead of 25, and used Serial.print to show me that it is not holding the condition, but is checking if the condition is true every time the time interval is reached.

Your answer almost works. What is happening now, is the delay applies when the obstacle_Bit is true, and when it is false. So, it holds the condition true as required, then holds it false for the same amount of time. The trouble now, is regardless of a change in the condition, obstacle_Bit alternates from 1 to 0, in sync with the objectInterval. What I mean is, if it is true, and I set the interval to 2500 milleseconds, obstacle_Bit will remain true for 2.5 seconds, then become false for 2.5 seconds, over and over. Is there a way to set it so that there is no delay for when obstacle_Bit is set back to false by the else{ obstacle_Bit = 0; } ?

I figured it out, thank you for the help! Your answer was the nudge I needed to find a solution. This is the code that I settled on that works exactly as intended:

void distanceDecision(){

unsigned long objectCurrentMillis = millis();
if(distance < 29){
if(objectCurrentMillis - objectPreviousMillis >= objectInterval){
objectPreviousMillis = objectCurrentMillis;
if(obstacle_Bit == 0){
obstacle_Bit = 1;
}
}
}

if(distance > 29 && obstacle_Bit == 1 && objectCurrentMillis - objectPreviousMillis >= objectInterval){
obstacle_Bit = 0;
}

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.