Repeat a timer until a condition is met.

Hello so here is what i want to do :

  • Motor should be off for 100 seconds.

  • 17 Seconds before Motor Turns on start something ( Code under here is not exactly what but it doesnt matter at this point.

  • After the preroll stuff is done check the Ir sensor.

  • If the ir sensor is false. make a Led high for 5 seconds and turn it off and then wait 15 seconds before trying again.

  • if the ir sensor after lets say 3 attempts is true then turn on the motor for 3 seconds and restart the process.

hope i explained myself good enough, been grinding my head over this one. Thanks for help! :slight_smile:

const unsigned int Ontime = 3000;      // How long the motor should stay on.
const unsigned long Offtime = 100000;   // How Long the motor should stay off.
const unsigned long preroll = 17000; // How long time before motor turn on to give a warning sound.
const unsigned long waiting = 15000; // Wait time before it checks the Ir sensor again. 
unsigned long previousMillis = 0;      // will store last time.
bool motorState = true;             // 
int irSensorState = false;

void setup() {
  pinMode(motorPin, OUTPUT);
  Serial.begin(9600); //Start serial communication boud rate at 9600
  pinMode(irSensor, INPUT); //Pin 5 as signal input
  pinMode(ledPin, OUTPUT);
pinMode(ledPin2, OUTPUT);
pinMode(ledPin3, OUTPUT);


}

void loop() {

   if(digitalRead(irSensor)==LOW)  { 
    irSensorState = false;
    // Collision detected.
   }
   else  {
     irSensorState = true;
     // No collision detected.
   }

  if (Motorstate == false)
  {
    if (currentMillis - previousMillis >= (Offtime - preroll)) // start this 17 seconds before Ontime.
        digitalWrite(Ledpin, HIGH);
      }

     // maybe here i want a code that check if the Ir sensor is either true or false,
     //if its false i want to check it again in 15 seconds (( const unsigned long waiting = 15000;) 
     // and then do it every 15 seconds untill its true, and then Turn on the motor pin.


    if (currentMillis - previousMillis >= Offtime)
    {
      previousMillis = currentMillis;
      motorState = !motorState;
      digitalWrite(motorPin, motorState);
    }
  }
  else
  {
    if (currentMillis - previousMillis >= Ontime)
    {
      previousMillis = currentMillis;
      motorState = !motorState;
      digitalWrite(motorPin, motorState);
      signalSent = false;   // Set it back to false again to restart the proces
    }
  }
}
while(1)  {
   delay(500);

Why do you have your loop code inside a while(1)?

Why do you have a half second delay if you are trying to use millis for timing.

Ahh, forgot to remove it, Do you have a idea what i can do :slight_smile: ? Help is so much appreciated.

What’s the problem? What does it do or not do that isn’t to your liking?

Also get into the habit of adding ul
const unsigned long myVar = 200000ul;

larryd:
Also get into the habit of adding ul
const unsigned long myVar = 200000ul;

You don't need it for single constants. Only when doing math with values that fit in 16 bits where you have intermediate values that don't. In the line quoted the ul is completely superfluous.

If you had this you would need the ul:

const unsigned long myVar = 200ul * 1000;

Delta_G:
What’s the problem? What does it do or not do that isn’t to your liking?

  • If the ir sensor is false. make a Led high for 5 seconds and turn it off and then wait 15 seconds before trying again.

  • if the ir sensor after lets say 3 attempts is true then turn on the motor for 3 seconds and restart the process.

hope i explained myself good enough, been grinding my head over this one. Thanks for help! :slight_smile:

I dont know how to make the " waiting " thing happen.

Like, I dont know how to make that code happen.. :confused: cant seem to figure it out. like with the timer and all, to check the ir sensor and go forward or not would be okay, but it is the timer thing im having some issues with

Delta_G:
You don't need it for single constants. Only when doing math with values that fit in 16 bits where you have intermediate values that don't. In the line quoted the ul is completely superfluous.

If you had this you would need the ul:

const unsigned long myVar = 200ul * 1000;

Thanks

My advice - put aside the project for a bit and delve into these examples: debounce & BlinkWithoutDelay & StateChangeDetection, found in the IDE under File/examples/digital/. Having a grasp of the example programs will stand you in good stead down the road. The debounce delay doesn't have to be 50ms, it can be (almost) anything. Nor does it have to be driven by a pushbutton, any digital condition will do. These three examples can be modified and combined to provide almost any timing feature.

Experiment. Tweak them and bend them until you're comfortable with Arduino timing.

A suggested experiment: build a timer, enabled by a pushbutton which increments to a preset. If at any time the button input is removed (false) the timer resets to zero. Turn on a bool when the timer is at preset. Use the timer's bool to drive some one-shot (state change detection) code to turn an additional bool on to drive an LED.

Alternatively, you could utilize one of many timer libraries out there.

dougp:
My advice - put aside the project for a bit and delve into these examples: debounce & BlinkWithoutDelay & StateChangeDetection, found in the IDE under File/examples/digital/. Having a grasp of the example programs will stand you in good stead down the road. The debounce delay doesn't have to be 50ms, it can be (almost) anything. Nor does it have to be driven by a pushbutton, any digital condition will do. These three examples can be modified and combined to provide almost any timing feature.

Experiment. Tweak them and bend them until you're comfortable with Arduino timing.

A suggested experiment: build a timer, enabled by a pushbutton which increments to a preset. If at any time the button input is removed (false) the timer resets to zero. Turn on a bool when the timer is at preset. Use the timer's bool to drive some one-shot (state change detection) code to turn an additional bool on to drive an LED.

Alternatively, you could utilize one of many timer libraries out there.

Feeling okay with timer libaries, Its just how to make that waiting process happen and reset. Can someone atleast point me in the rigth direction ? Thanks for answer!

Hi,

What is the application of your project.?
If we know what you are trying to accomplish, we maybe able to give you a more concise answer.

Thanks.. Tom.... :slight_smile:

TomGeorge:
Hi,

What is the application of your project.?
If we know what you are trying to accomplish, we maybe able to give you a more concise answer.

Thanks.. Tom.... :slight_smile:

its a small pig feeder, I dont want them to get food when they are standing rigth in front off the bowl, ( where the ir sensor are ) And also instead of the led im going to send a 50 ms signal to a mp3 card.. But that doesnt matter rigth now.

if you have read blink without delay, you know there is a 3-prong concept.

when you want to trigger the start of the timing or event
the timing
the way you use your timing data, often just a state change of a value.

there are many concepts for needing to time.
the exact time since the start or button push, this ignores repeated button pushes.
as opposed to the last time the sensor was tripped. looking only at time since last trip.

if your case, your sensor(s) signal that there is someone where they should not be. you want last event.

this means we keep re-setting the timer.
// note that this is not code, just a general way to write it, it will not compile and none of the variables are declared.

if (sensor shows movement)
lastTime = millis()

this will keep resetting lastTime as long as there is activity.

as opposed to :
if StartFlag==1
if (sensor shows movement)
lastTime = millis()
StartFlag=0 // stops the loop until something changes this to 1

back to your sketch

if (sensor shows movement)
lastTime = millis()

here is a simple part

duration = millis() - lastTime // duration is your counter

if duration >== 17 seconds // set your time out period
open the pod bay doors HAL // do your thing here.

you might want to have safeties on when they close and a second timer on when to close them.

you could use

if duration >== 10 minutes
HAL close the pod bay doors please

but, you run into the problem of re-setting the timer during that 10 min.

so

if podBayDoors == closed
if (sensor shows movement)
lastTime = millis()

duration = millis() - lastTime // time out period

if podBayDoors == closed
if duration >== 17 seconds
open the pod bay doors HAL // do your thing here.
podBayDoors = open // set a flag

if podBayDoors == open
if duration >== 10 minutes // timer was locked when the doors opened
HAL close the pod bay doors please
podBayDoors = closed // allows the timer to count again

what is missing is that as soon as they close, the whole thing is active and could re-open 17 seconds after everyone goes home.

so, you have to set some flag as to when you will want this loop to run.
time of day from some clock ? RTC or internet ?
time from sun rise or some such ?

you could do
if duration >== 24 hours

to do this 24 hours after the last close, but if it took the 10 minutes it would be 24 plus 10 min
if there was a lot of milling around, and it took 12 minutes, then each day the time is not the same time of day. And RTC could be used if you wanted to have it work at the same time each day.