Going faster everytime...

Okay so i have a program that have two buttons.
One button will start a timer with 4 lamps for 2 min, and each lamp is for 30 sec.

When it hits the 2 min mark it will make three small "pip" sounds.

But when both buttons are pressed at the same time for 1 sec then it will reset.

However the longer i am using this, the shorter it works. So 30 sec becomes a lot lower than 30 sec. And that makes the timer less and less...

So something is wrong with the millis...

int sound = 3;
int led4 = 4;
int led5 = 5;
int led6 = 6;
int led7 = 7;
int buttonPin = 2;
int buttonPin2 = 9;
long CM = 0;
long Interval = 0;
long cat = 0;
long pip = 1;
long Lamp = 0;
long Tone = 100;
int action = 0; 
int adding = 0;
int powerdown = 0;

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

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



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




  if (reading2 == LOW)
  {
    adding++;
  }
  else
  {
    adding = 0;
  }





  if (Interval == 1) 
  {
    if (CM - Lamp >= 30000) 
    {
      Lamp = CM;  
      pip = 1;
      action++;         
      if (action >= 5)
      {
        action = 0;
      }
    }
    switch (action)
    {
      case 0:
        digitalWrite(4, HIGH);     
        digitalWrite(5, HIGH);
        digitalWrite(6, HIGH);
        digitalWrite(7, HIGH);
        break;
      case 1:
        digitalWrite(4, LOW);      
        break;
      case 2:
        digitalWrite(5, LOW);    
        break;
      case 3:
        digitalWrite(6, LOW);     
        break;
      case 4:
        digitalWrite(7, LOW);     
        Interval = 0;             
        cat = 1;
        break;
      case 5:
        delay(10);
        break;
      default:
        break;
    }
  }


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





  if (adding >= 1)
  {
    CM = powerdown;
  }

  if ((reading == LOW) && (reading2 == LOW))
  {

  }
  else
  {
    CM = powerdown;
  }
  if (CM - powerdown >= 1000)
  {
    Interval = 0;
    pip = 1;
    cat = 0;
    Tone = CM; 
    Lamp = CM;  
    digitalWrite(4, LOW);
    digitalWrite(5, LOW);
    digitalWrite(6, LOW);
    digitalWrite(7, LOW);
  }

}

So something is wrong with the millis...

That's an interesting conclusion.

Well i don't see anything else that could mess it all up.

Put it this way.

Look at all the posts on the forum today, this week, even, saying that there's something wrong with millis.

Do you think you maybe should be looking elsewhere, more closely?

What i mean is that there is not actually something wrong with millis... but how i use it.
sigh.

use unsigned long for all millis variables.
you should debounce the buttons.

    Lamp = 0;

This is an unusual thing to do. The variable 'Lamp' contains the time the latest 30-second interval was started. If you set it to zero and the sketch has been running more than 30 seconds, the timer for the 30-second cycle will end immediately. I suspect you should either NOT be setting Lamp at all OR you should be setting it to CM to start a new 30-second interval.

    CM = powerdown;

This is an unusual thing to do. You WERE using 'CM' to hold the Current Milliseconds. That value is used with the start time of an interval to calculate the elapsed time. I suspect you should have a different variable to store the start of an interval. If you change CM you can no longer use it for calculating elapsed time.

I can safely say that it still is not working. It is still going too fast somehow.

Lexianlex:
I can safely say that it still is not working. It is still going too fast somehow.

You need to post the latest version of your program so we can see the changes.

It would also help if you use meaningful names for your variables so we can “read” the program like a story.

Put Serial.print() statements into your program so you can see how the values in variables are changing. Maybe things are not what you think they are.

…R

@OP

1. Hopefully, the following diagram has represented your hardware setup
led4x.png
Figure-1: 4 LED, 1 Buzzer, and 2 Buttons

2. Hopefully, these are the goals you want to achieve; if not, revise it and post back. The intention is to help/guide you in the logical way so that you know what you are doing (want to do), and you can eventually make your program working.

(1) When K1 or K2 is closed, the following events will happen:
(a) L4 will remain ON for 30-sec;
(b) After 30-sec time, L4 goes OFF; L5 comes ON, and it remains ON for 30-sec;
(c) After 30-sec time, L5 goes OFF; L6 comes ON, and it remains ON for 30-sec;
(d) After 30-sec time, L6 goes OFF; L7 comes ON, and it remains ON for 30-sec;
(e) After 120-sec time (2-min), the Buzzer beeps makes short beeps for 3 times;
(f) The cycle will repeat from Step-1.

3. While the above process has been going ON and you close K1 and K2 simultaneously and hold them closed for 1-sec, all LEDs and Buzzer will be reset (OFF).

4. The following Flow Chart attempts to partly describe the events of Step-2. Let us try to convert this Flow Chart into Arduino Coding. If there is some good results, we may proceed to add the next event.


Figure-2: Flow Chart describing events (partly) of Step-2

led4x.png

GolamMostafa:
@OP

1. Hopefully, the following diagram has represented your hardware setup
led4x.png
Figure-1: 4 LED, 1 Buzzer, and 2 Buttons

Sorry to Hijack this thread, but...

@GolamMostafa

What software do you use to create those wiring diagrams?

I am still using the one that i sent from the begining.

GolamMostafa:
@OP

1. Hopefully, the following diagram has represented your hardware setup
led4x.png
Figure-1: 4 LED, 1 Buzzer, and 2 Buttons

2. Hopefully, these are the goals you want to achieve; if not, revise it and post back. The intention is to help/guide you in the logical way so that you know what you are doing (want to do), and you can eventually make your program working.

(1) When K1 or K2 is closed, the following events will happen:
(a) L4 will remain ON for 30-sec;
(b) After 30-sec time, L4 goes OFF; L5 comes ON, and it remains ON for 30-sec;
(c) After 30-sec time, L5 goes OFF; L6 comes ON, and it remains ON for 30-sec;
(d) After 30-sec time, L6 goes OFF; L7 comes ON, and it remains ON for 30-sec;
(e) After 120-sec time (2-min), the Buzzer beeps makes short beeps for 3 times;
(f) The cycle will repeat from Step-1.

3. While the above process has been going ON and you close K1 and K2 simultaneously and hold them closed for 1-sec, all LEDs and Buzzer will be reset (OFF).

This is all good, and i know that everything on my board is working and yes i am doing the program in almost the same manner.

But i think that the problem is about how i reset the value of millis so that everytime i start the program it won't get faster. And the same goes for when i press both the buttons at the same time.

Lexianlex:
I am still using the one that i sent from the begining.

That suggests that you have taken no notice of any of the advice you were given in Replies #5 and #6?

…R

Lexianlex:
This is all good, and i know that everything on my board is working and yes i am doing the program in almost the same manner.

But i think that the problem is about how i reset the value of millis so that everytime i start the program it won’t get faster. And the same goes for when i press both the buttons at the same time.

Because I faced great great difficulties to read the meanings of the codes of your sketch, I had to draw the hardware block diagram (Fig-1, Post#9) and the flow chart (Fig-2, Post#9) in order to motivate you/myself to understand the sequence of events that have been going on. Now, you can check that the codes of your sketch are in line with the logic of the flow chart, and accordingly you can revise your codes.

Notice in the flow chart that the 30-sec delay and the 1-sec delay; these two delays have to be created using two different objects in such a way so that you can monitor their endings. An attempt to generate both delays using millis() function will overlap everything?

@darrob
I use Visio-2007 program to create these diagrams; it’s a manual procedure.

Robin2:
That suggests that you have taken no notice of any of the advice you were given in Replies #5 and #6?

...R

I have. But even then it didnt work. I thought that giving everything its own "millis" would work. And i got rid of the CM = 0 or Lamp = 0. But even then nothing seems to add up.

Have you posted the latest version of your code ?

Lexianlex:
I have. But even then it didnt work.

I had hoped that my Reply #8 would have prompted you to post the code with those changes so we could see exactly what you tried. The devil is in the detail.

...R

Robin2:
The devil is in the detail.

Please, give tips on how to extract essentials from the details.

GolamMostafa:
Please, give tips on how to extract essentials from the details.

I cannot see that comment being any value to the OP.

What I meant when I said "the devil is in the detail" is that the OP may have tried to implement a suggestion but made a small error which resulted in it not working.

...R

UKHeliBob:
Have you posted the latest version of your code ?

int sound = 3;
int led4 = 4;
int led5 = 5;
int led6 = 6;
int led7 = 7;
int buttonPin = 2;
int buttonPin2 = 9;
long CM = 0;
long Interval = 0;
long cat = 0;
long pip = 1;
long Lamp = 0;
long Tone = 100;
int action = 0;
int adding = 0;
int powerdown = 0;

void setup()
{
  pinMode(2, INPUT_PULLUP); //TWO BUTTONS!
  pinMode(9, 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();          //MY MILLIS
  int reading = digitalRead(buttonPin);   //READING MY BUTTONS!
  int reading2 = digitalRead(buttonPin2);



  if (reading == LOW)     
  {
    Interval = 1;       //THE FIRST BUTTON WILL ACTIVATE MY CODE!
  }




  if (reading2 == LOW)
  {
    adding++;         //THE SECOND BUTTON SHALL ONLY ACT WHEN BOTH THE SECOND AND FIRST 
  }                   //BUTTON ARE PRESSED TOGETHER FOR ATLEAST 1 SEC.
  else
  {
    adding = 0;
  }





  if (Interval == 1)      //IF WE PRESS THE FIRST BUTTON THEN WE CAN ONLY ACTIVATE THE CODE ONCE!
  {
    if (CM - Lamp > 30000)    //EVERY 30 SEC WE TURN OFF 1 OUT OF OUR 4 LIGHTS!
    {
      Lamp = CM;
      pip = 1;
      action++;
      if (action >= 5)
      {
        action = 0;
      }
    }
    switch (action)
    {
      case 0:
        digitalWrite(4, HIGH);
        digitalWrite(5, HIGH);
        digitalWrite(6, HIGH);
        digitalWrite(7, HIGH);
        break;
      case 1:
        digitalWrite(4, LOW);
        break;
      case 2:
        digitalWrite(5, LOW);
        break;
      case 3:
        digitalWrite(6, LOW);
        break;
      case 4:
        digitalWrite(7, LOW);
        Interval = 0;
        cat = 1;
        break;
      case 5:
        delay(10);
        break;
      default:
        break;
    }
  }


  if (cat == 1)     //ONCE THE LAMP CODE IS DONE THEN THE SOUND CODE STARTS
  {
    if (CM - Tone > 150)
    { 
      Tone = CM;
      tone(sound, 400, 50);
      Serial.println("Ljud");

      pip++;
    }
  }
  if (pip == 4)   //ONCE WE HAVE HEARD A SOUND MAKE A "PIP" 3 TIMES THEN IT RESTARTS. AND "PIP = 1" FROM THE BEGINING!
  {
    Interval = 0;
    pip = 1;
    cat = 0;
  }





  if (adding >= 1)    //WHEN THE SECOND BUTTON IS PUSHED THEN SOMETHING HAPPENS
  {
    CM = powerdown;   
  }

  if ((reading == LOW) && (reading2 == LOW))
  {

  }
  else
  {
    CM = powerdown;
  }
  if (CM - powerdown >= 1000)   //WHEN BOTH BUTTONS ARE PUSHED THEN WE SHUT EVERYTHING OFF! 
  {
    Interval = 0;
    pip = 1;
    cat = 0;

    digitalWrite(4, LOW);
    digitalWrite(5, LOW);
    digitalWrite(6, LOW);
    digitalWrite(7, LOW);
  }

}
// The thing is that we have 1 value for every different time, which is CM. So maybe that makes things more difficult. 
// However when runing this code, the time almost goes faster and fast until a point when i push the button and we instantly 
// skip the lamps and the sounds comes right after that...