Trying to understand bool with button push and millis

Hi folks.
Im working on an airsoft bomb.
I want to make a button that when held for 60 Seconds it changes the game status to bomb defused.

I use millis to start a timer when the game begins.
and when the time runs out the prop writes bomb exploded.

I guess i have to use boolean i just dont know how it works.

The defuse button im working on is now without boolean it looks like this and it doesnt work.
The press registers i see that on the LCD.
Defusetimer is set to 6000 but millis is ofc alot higher then that when you get to press it.
ive been trying to set something like this:

defuseTimer = currentMillis + defusetimer;

That ofc. keep updating the defuseTimer whitch was not my intention.

while (toggleArmeret == true) {
   unsigned long currentMillis = millis();
    if((rledState == HIGH) && (currentMillis - previousMillis >= OnTime))
  {
    rledState = LOW;  // Turn it off
    previousMillis = currentMillis;  // Remember the time
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print("Bombe ARMERET!");
    lcd.setCursor(0,1);
    lcd.print(currentMillis);
    digitalWrite(rledPin, rledState);  // Update the actual LED
    tone(buzzerPin, 3500);
    delay(500);
    noTone(buzzerPin);

  }
  else if ((rledState == LOW) && (currentMillis - previousMillis >= OffTime))
  {
    rledState = HIGH;  // turn it on
    previousMillis = currentMillis;   // Remember the time
    lcd.clear();


    digitalWrite(rledPin, rledState);	  // Update the actual LED
  }
      if (currentMillis >= armerTimer) {
        toggleArmeret = false;
        toggleS2Armeret = true;
      }
      
    //Hvis desarmer knappen trykkes desarmer bomben.
      if (digitalRead(desarmerPin) == false) {
        unsigned long defuseStart;
        const unsigned long defuseTimer = 6000;
        defuseStart = millis();
        lcd.clear();
        lcd.setCursor(0,0);
        lcd.print(defuseTimer);
        lcd.setCursor(0,1);
        lcd.print(defuseStart);
         
        if ((currentMillis - defuseStart >= defuseTimer) && (digitalRead(desarmerPin == false))) {

      toggleDesarmeret = true;
      toggleArmeret = false;
      togglePassiv = false;
      digitalWrite(rledPin, LOW);
        }
       }
  }

Think of "armMillis" instead of defuse millis:

if( armed && (currentMillis - armedMillis > defuseInterval)) {
  boom();
} 

I know how to make it explode.
I dont know how to hold a button for 60 Seconds to defuse it.

That won't work past rollover.

unsigned long defuseTimer;
const unsigned long defusetimer = 60000;
...
// and when the button is first held down and debounced
defuseTimer = millis();
...
// elapsed time while button is held down
if ( currentMillis - defuseTimer >= defusetimer )
{
// defused
}

// you will have to code for button not held down for 60s.
// possibly make a countdown
// elapsed time = now - start time
// it's about unsigned subtraction that always works to the limit of the timer variables.... unsigned millis is good for just over 49.7 days.

You need to study and understand the "state change" sketch from the IDE's Examples menu.

1 Like

Thank you for your answer it makes sense but doesnt work.
I was proberbly to tired when i wrote this.
I just updated the code to show what happens from bomb armed to push on defuse button.

What happens with your example is that if the bomb have been armed for a while more then 60000 millis and i press defusebutton it defuse instantly.

i changed the variables to defuseStart and defuseTimer cause the other thing was just confusing.

I think i need to make the defuse timer be currentMillis + 60000 but not updating every millisecond and i just cant figure out how to do that.

I tryed to read it a few times i guess i cant figure out how it works with my current problem. I dont know how to add 60000 to currentMillis and make it a constant not an updating number.

Your problem is that while the button is pressed, your code is continuously adding 60000 to millis(). You want to do that once only, at the moment when the button changes state, from not being pressed, to being pressed. That's what the state change example sketch is about.

1 Like

You didn't set the start time for the defuse properly.

I gave you clues only. I won't write the code for you.

So long.

Do you mean that you do not know how to measure time from when a button was pressed?

Then learn the StateChangeDetection example.

bool buttonActivated = (digitalRead(ButtonPin) == LOW);
if( buttonActivated != lastButtonActivationState){  // Change?
  lastButtonActivationState = buttonActivated;
  if(buttonActivated){ // just pressed
     buttonActivationMillis = currentMillis;
  } 
}

Or that you don't know how to count 60 seconds from a timestamp and act:

if( armed && buttonActivated && (currentMillis - buttonActivationMillis > 60000)){
   armed = false;
   defuse();
}

...which is essentially just state-change-detection on (currentMillis - buttonActivationMillis > 60000).

Thanks alot @DaveX and @PaulRB
You pointed me in the right direction.
I got it working with a ++ counter adding seconds to a counter. Ill look more into the other examples you helped with. This is much appriciated.
Definatly makes it worth asking the internet for help with people as patient as you guys :slight_smile:

Have a nice one :).

1 Like

I hope its ok to ask a question off topic :slight_smile:
Im building a menu using updateMenu()

I can read the code on the guide i follow, but there is for example no explenation on why there suddenly is a
void updateMenu
part in the program.
I understand what it does but cant seem to google my way into the word to read about it.

The arduino programming docs doesnt show anything about updateMenu

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