Using millis() while two affecting two tasks

using Arduino Mega with two LEDs and two push buttons, each button turns on another led (BTN1_PIN, BTN2_PIN, LED1, LED2)

I want when button1 is pushed the ledPin1 to turn HIGH and the same for button2 and ledPin2

but it should include this:

When button1 is pressed a 7-second timer starts, during those 7 seconds if button2 is pushed it won't work. Once the 7 seconds are up pushing button2 turns on ledPin2 again.

Last part: If button1 is pushed and starts the 7 seconds timer...if at any point button1 is pushed again- the timer restarts and pauses button2 for 7 seconds

I have written the following

#include <InputDebounce.h>

#define LED1  11
#define LED2  12
#define BTN1_PIN 53
#define BTN2_PIN 22

const unsigned long eventInterval = 7000;
bool btn1Flag = false;
unsigned long previousTime = 0;
int button1State = 0;         // variable for reading the pushbutton status
int button2State = 0;         // variable for reading the pushbutton status
int lastButton1State;    // the previous state of button
int currentButton1State; // the current state of button
int led1State = LOW;     // the current state of LED
int lastButton2State;    // the previous state of button
int currentButton2State; // the current state of button
int led2State = LOW;     // the current state of LED
void setup() {
  // initialize digital pin LED_BUILTIN as an output.
  pinMode(LED1, OUTPUT);
  pinMode(LED2, OUTPUT);
  pinMode(BTN1_PIN, INPUT);
  pinMode(BTN2_PIN, INPUT);
  currentButton1State = digitalRead(BTN1_PIN);
  currentButton2State = digitalRead(BTN2_PIN);
}


void loop() {
  /* Updates frequently */
  unsigned long currentTime = millis();
  lastButton1State    = currentButton1State;      // save the last state
  currentButton1State = digitalRead(BTN1_PIN); // read new state
  lastButton2State    = currentButton2State;      // save the last state
  currentButton2State = digitalRead(BTN2_PIN); // read new state

  if (lastButton1State == HIGH && currentButton1State == LOW)
  {
    led1State = !led1State;
    digitalWrite(LED1, led1State);
    //iteratin: 1 (if 100ms - 0  <=  3000 will give me true 
    if (currentTime - previousTime >= eventInterval) {
      //set the btnFlat with fale
      previousTime = currentTime;
      //if the user presses the button1 at any moment
      if (currentButton1State == HIGH)
      {
        //I will reset my interval time. by adding the interval time to my current time and assign it to my NEW eventInterval time again
        previousTime = currentTime;
      }
       btn1Flag = true;
    }
  }
  if ((lastButton2State == HIGH && currentButton2State == LOW) && btn1Flag)
  {
    led2State = !led2State;
    digitalWrite(LED2, led2State);
  }
}

but it doesn't seem to work. I don't know where to start. any help would be appreciated
Thanks

You should only save lastButton?State when currentButton?State changes, so you need to move those assignments into the "if" block. Also, the if (currentButton1State == HIGH) statement will never be reached, so that may be removed from the code.

bool timerStarted = false;

void loop() {
  unsigned long currentTime = millis();
  currentButton1State = digitalRead(BTN1_PIN); // read new state
  currentButton2State = digitalRead(BTN2_PIN); // read new state

  if (lastButton1State == HIGH && currentButton1State == LOW)
  {
    led1State = !led1State;
    digitalWrite(LED1, led1State);
    lastButton1State    = currentButton1State;      // save the last state
    timerStarted = true;
    previousTime = currentTime;
  }
    
  if (timerStarted && (currentTime - previousTime >= eventInterval)) {
    //set the btnFlat with fale
    //if the user presses the button1 at any moment
     btn1Flag = true;
     timerStarted = false;
  }

  if ((lastButton2State == HIGH && currentButton2State == LOW) && btn1Flag)
  {
    lastButton2State    = currentButton2State;      // save the last state
    led2State = !led2State;
    digitalWrite(LED2, led2State);
  }
}

use a button library to make your code easier to develop (Once you get that working you could implement your own button handling if you want to get rid of the library)

this has the advantage of offering a programming API that is close to your specifications

can you clarify what "pushed" mean ? Is that "as long as the button is down" or more like a click on the push button ?

what happens if button2 is already held down when you press button1: does the 7 second timer kicks in anyway in case you release button2?

how are the LEDs turning off?

Thanks for sharing your code works, but only at the first run. it doesn't work through out the life of the program
only the first 7 seconds

#include <Button.h>
#define LED1  12
#define LED2  11
#define BTN1_PIN 53
#define BTN2_PIN 22

Button button1(BTN1_PIN);
Button button2(BTN2_PIN);

const unsigned long eventInterval = 7000;
bool btn1Flag = false;
unsigned long previousTime = 0;
int currentButton1State; // the current state of button
int currentButton2State; // the current state of button
int led1State = LOW;     // the current state of LED
int led2State = LOW;     // the current state of LED
bool timerStarted = false;

void setup() {
  // initialize digital pin LED_BUILTIN as an output.
  pinMode(LED1, OUTPUT);
  pinMode(LED2, OUTPUT);
  button1.begin();
  button2.begin();
}


void loop() {
  unsigned long currentTime = millis();
  currentButton1State = button1.read(); // read button1 new state
  currentButton2State = button2.read(); // read button2 new state

  if (button1.released())
  {
    led1State = !led1State;
    digitalWrite(LED1, led1State);
    timerStarted = true;
    previousTime = currentTime;
  }
  if (timerStarted && (currentTime - previousTime >= eventInterval))
  {
    btn1Flag = true;
    timerStarted = false;
    previousTime = currentTime;
  }
  if (button2.released() && btn1Flag)
  {
    led2State = !led2State;
    digitalWrite(LED2, led2State);
  }
}

Fix ver0.3
I have added the button library. Thank you it's clearer now. it is still missing something. because the code works for the first 7 seconds only. then it behaves normally
I have two logic errors now

  1. I must press button 1 on the first run (which is not the case - because I want to let the user press button 1 or button 2 at any moment).
  2. If the user pressed Button 1. It supposes to block Button 2 Input for 7 seconds. If the user during those 7 seconds press Button 1 again (changed button 1 state). it is supposed to reset the 7 seconds timer.

can you clarify what press means ? (see questions in previous post)

it's a push-button. Click on the push button. not holding it.
Hope that clarified everything.
sorry for the confusion
Hope this helps

how are the LEDs turning off?
what if you keep the finger on the button?

1 Like

Thanks a lot, it works now guys. I just want to share with you the final results

#include <Button.h>
#define LED1  12
#define LED2  11
#define BTN1_PIN 53
#define BTN2_PIN 22

Button button1(BTN1_PIN);
Button button2(BTN2_PIN);

const unsigned long eventInterval = 7000;
bool btn1Flag = true;
unsigned long previousTime = 0;
int led1State = LOW;     // the current state of LED
int led2State = LOW;     // the current state of LED
bool timerStarted = false;

void setup() {
  // Initialize digital pin LED1, LED2 as outputs.
  pinMode(LED1, OUTPUT);
  pinMode(LED2, OUTPUT);
  // Initialize Buttons1, Button2
  button1.begin();
  button2.begin();
  Serial.begin(9600);
}


void loop() {
  unsigned long currentTime = millis();
  if (button1.released())
  {
    btn1Flag = false;
    timerStarted = true;
    led1State = !led1State;
    digitalWrite(LED1, led1State);
    previousTime = currentTime;
  }
  if (timerStarted && (currentTime - previousTime >= eventInterval))
  {
    btn1Flag = true;
    timerStarted = false;
  }
  if (button2.released() && btn1Flag)
  {
    Serial.println("Button 2 pressed");
    led2State = !led2State;
    digitalWrite(LED2, led2State);
  }
}

consider a more extendable approach

// check multiple buttons and toggle LEDs

enum { Off = HIGH, On = LOW };

byte pinsLed [] = { 10, 11, 12 };
byte pinsBut [] = { A1, A2, A3 };
#define N_BUT   sizeof(pinsBut)

byte butState [N_BUT];

// -----------------------------------------------------------------------------
int
chkButtons ()
{
    for (unsigned n = 0; n < sizeof(pinsBut); n++)  {
        byte but = digitalRead (pinsBut [n]);

        if (butState [n] != but)  {
            butState [n] = but;

            delay (10);     // debounce

            if (On == but)
                return n;
        }
    }
    return -1;
}

// -----------------------------------------------------------------------------
void
loop ()
{
    switch (chkButtons ())  {
    case 2:
        digitalWrite (pinsLed [2], ! digitalRead (pinsLed [2]));
        break;

    case 1:
        digitalWrite (pinsLed [1], ! digitalRead (pinsLed [1]));
        break;

    case 0:
        digitalWrite (pinsLed [0], ! digitalRead (pinsLed [0]));
        break;
    }
}

// -----------------------------------------------------------------------------
void
setup ()
{
    Serial.begin (9600);

    for (unsigned n = 0; n < sizeof(pinsBut); n++)  {
        pinMode (pinsBut [n], INPUT_PULLUP);
        butState [n] = digitalRead (pinsBut [n]);
    }

    for (unsigned n = 0; n < sizeof(pinsLed); n++)  {
        digitalWrite (pinsLed [n], Off);
        pinMode      (pinsLed [n], OUTPUT);
    }
}

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