Millis timer

Okay so was wondering. If i wanted to make a timer from 2 to 4, 6 and 8 minutes then shouldn’t i be able to do this with millis?

I tried but it only works for 2 min.

unsigned long previousMillis; 

void setup()
{

  //Buttons and lamps.

}

void loop()
{

  if (button = pressed) //Just an example of how it would look like...
  {

    unsigned long currentMillis = millis(); 
      
    if (currentMillis - previousMillis >= 120000)  // 120000 is 2 min. 
    {
      digitalWrite(Shut down one of my lamps);
    }


    if (currentMillis - previousMillis >= 240000)  // 240000 is 4 min. 
    {
      digitalWrite(Shut down one of my lamps);
    }
    
 
    
  }

}

That code doesn't work for me at all.

You can do this with millis(), what ever you are trying to do. Please explain further? Chances are it involves the fact that you never assign previousMillis a value.

No previousMillis does have a value.. i just made this up real quick.

But this is the code that i am writing atm.

It is a timer that can shut of at any time with two buttons pressed at the same time and it only starts everything once when one button is pushed.

This doesn't work for me. Even if CM - Lamp > 120000 (aka 2 min). So i tried with only CM as a counter but not even that worked. There is nothing wrong with my board so there has to be something in in this code that really isn't right.

I did this for only 2 min aswell. It worked perfectly... It shut one lamp of every 30 sec. And when 2 min hits then 3 pips of sound come along and then everything resets.

So for some reason it doesn't work for anything over 120000 ms or 2 min.

int sound = 3;
int led4 = 4;
int led5 = 5;
int led6 = 6;
int led7 = 7;
int buttonPin = 2;
int buttonPin2 = 9;
long Interval = 0;
long cat = 0;
long pip = 1;
int first = 0;
unsigned long Lamp = 1;
long Tone = 100;
long ledon = 0;
long previousMillis = 0;
int EndInterval = 3000;
int Time = 0;
int weak = 0;



void setup()
{
  pinMode(9, INPUT_PULLUP);
  pinMode(2, INPUT_PULLUP);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);
  pinMode(7, OUTPUT);
  Serial.begin(9600);
}

void loop()
{
  unsigned long CM = millis();
  int reading = digitalRead(buttonPin);
  int reading2 = digitalRead(buttonPin2);

  if (reading == LOW)
  {
    first = 1;
    ++Interval;
  }

  if (reading2 == LOW)
  {
  }


  if (Interval >= 1)   //This happens when the first button is pressed. 
  {

    CM++;
    if (ledon == 0)
    {
      ledon = 1;
      digitalWrite(4, HIGH);
      digitalWrite(5, HIGH);
      digitalWrite(6, HIGH);
      digitalWrite(7, HIGH);
    }

    if (CM == 1)
    {
      digitalWrite(4, HIGH);    //Everything from here starts the lamps and time. 
      digitalWrite(5, HIGH);
      digitalWrite(6, HIGH);
      digitalWrite(7, HIGH);
    }

    if (CM == 120000)
    {
      digitalWrite(4, LOW);
      CM = CM;
    }


    if (CM == 240000)          //it wont work after 120000... 
    {
      digitalWrite(5, LOW);
      CM = CM;
    }

    if (CM == 360000)
    {
      digitalWrite(6, LOW);
      CM = CM;
    }

    if (CM == 480000)
    {
      digitalWrite(7, LOW);
      cat = 1;
      Lamp = CM;
    }


    if (cat == 1)
    {
      if (CM - Tone >= 150)
      {
        tone(sound, 400, 100);
        Serial.println("Ljud");
        Tone = CM;
        pip++;
      }
    }
    if (pip == 4)
    {
      Interval = 0;
      pip = 1;
      cat = 0;
      ledon = 0;
    }
  }



  if ((reading == LOW) && (CM - weak >= 1000) && (reading2 == LOW))
  {
    Interval = 0;
    pip = 1;
    cat = 0;
    digitalWrite(4, LOW);
    digitalWrite(5, LOW);
    digitalWrite(6, LOW);
    digitalWrite(7, LOW);
    EndInterval = 3000;
    Lamp = 1;
    ledon = 0;
    delay (1000);
    weak = 0;
  }
}

Clarify:

Do you need a timer that ‘does something’ every 2 minutes?

0-2 (ding), 2 min later (ding) , 2 min later (ding), etc…

or a timer(s) that goes from :

0-2, 0-4, 0-6, 0-8 min ?

or a timer(s) that goes from :

2-4 min , 2-6, 2-8, etc?

Curious, why keep counting out if you can reset the timer and keep the millis <= 2 min? if you could just do something if 1 cycle (12,000) then reset and do something , or if 2 cycles (2 x 12,000) do something , ect…

To do something from 0 to 2 and then 2 min after do something again etc.. and when it hits 8 min then it should do something and reset.

Your example code in post #1 has the correct way to use millis(), you actual program is wrong. You cannot test CM == x. CM will likely never exactly == x.

You should program what you said.

Lexianlex:
To do something from 0 to 2 and then 2 min after do something again etc.. and when it hits 8 min then it should do something and reset.

0 minutes = start action 1
2 minutes = end action 1
4 minutes = start action 2
6 minutes = end action 2
8 minutes = start action 1
...

Every two minutes you need to change the action.

if (currentMillis - previousMillis >= 120000) // 120000 is 2 min.
{
previousMillis = currentMillis;
action++;
if (action >=4) {action=0;}
}
switch (action)
{
case 0: //start action 1
break;
case 1: //end action 1
break;
case 2: //start action 2
break;
case 3: //end action 2
break;
default:
break;
}

previousMillis doesn't really need to be assigned a value as it's declared global it will be defaulted to zero. Without assigning it a value however, and not updating it, seems rather pointless to use it in a comparison. Could just as easily say if (currentMillis > 12000);

I don't think that's what you're looking for though. And of course what you've got doesn't work because after 2 minutes the first test case will always be true. At some point you're going to have assign previousMillis the value of currentMillis and then test for the elapsed time. I'll let you think on that a bit, or for as long as it takes one of the eager beavers to want to show how smart they are and deprive you of the opportunity to figure it out yourself,

Well i could just say this.

if(currentMillis - previousMills >= 120000)

{

digitalWrite(One lamp, LOW); 
PM = CM; 

}


//And then do one again with the updated value.. 


if(currentMillis - previousMills >= 240000)  //4 min... 

{

digitalWrite(Another lamp, LOW); 
PM = CM; 

}

But this didn't work for me either.

What's the "PM = CM" thing supposed to do?

Save the time that has gone by so the next one can piggy back on it from 2 min to 4 min etc..?
I am following the "BlinkWithoutDelay" example. I know that it might not apply here but i am new to this.

Please let me know how wrong i am. It helps out.

Every two minutes you want the program to do something different. Time off two minute increments and change the action.

pseudo code
#define set(x)   x = 1
#define clr(x)    x = 0

byte time_action1, time_action2, time_action3, time_action4;

UL currentMillis, prevMillis;

setup -> do setup stuff

loop()
  currentMillis = millis();
  if((currrentMills - prevMillis >= 1st_time_interval) && !time_action1)
      do the first stuff here, and
      set(time_action1)    // this keeps it from entering again until time_action1 is cleared

  if((currrentMills - prevMillis >= 2bdt_time_interval) && !time_action2)
      do the first stuff here, and
      set(time_action2)    // this keeps it from entering again until time_action2 is cleared

  if((currrentMills - prevMillis >= 3rd_time_interval) && !time_action3)
      do the first stuff here, and
      set(time_action3)    // this keeps it from entering again until time_action3 is cleared

  if((currrentMills - prevMillis >= 4th_time_interval) [&& !time_action1])  // that second part of the test can by dropped if is the last
      do the first stuff here, and
      set(time_action4)    // only necessary if there will be another
      clear(time_action1);
      clear(time_action2);
      clear(time_action3);
      prevMillis = currentMillis; // all flags have been cleared and time reset to start all over
end loop

Thanks guys.

I tried with cases. It works fine now!