Is there a cleaner way of only running an action once on loop?

384 Views Asked by At

I have a button that I am taking input from and a light that toggles when I press the button.

Right now I am normally toggling the light once in the loop function and it's kind of messy.

I don't want it to constantly toggle when the button is held down.

Here is my current code:

bool inboxLightsEnabled = false;

void setup() {

  //Analog pin mode
  pinMode(A0, INPUT);

  //Digital pin mode
  pinMode(2, OUTPUT);
  
}

bool buttonPressRecieved = false;

void loop() {
  
  if(analogRead(A0) >= 1000) {
    if(!buttonPressRecieved) {
      
      //The button has been pressed and not recieved yet so process it
      inboxLightsEnabled = !inboxLightsEnabled;
      
      buttonPressRecieved = true; //We have received the button press so make sure we don't receive it again
      
    }
  } else {
    buttonPressRecieved = false; //The button stopped being pressed so make this false
  }

  digitalWrite(2, inboxLightsEnabled);
  
}

It's ok if it's not possible to make this cleaner but I need to know if it can be done.

Also, I am using analogRead because digitalRead seemed to flicker between on and off when I used it as an input.

Does anyone know?

2

There are 2 best solutions below

0
On BEST ANSWER

Mabe this will help:

bool buttonState = false, buttonStateBefore = false;
void loop()
{
    buttonSate = digitalRead(ButtonPin);
    if(buttonState > buttonStateBefore) doStuff();
    buttonStateBefore = buttonState;
}

This would trigger a function on a button press. Don't know if this helps because your question isn't really clear to me, but i think this might do it. How it works: When the loop is running and the button is pressed the buttonState is true and buttonStateBefore is false. True being >1 and false being 0, true is bigger then false. Therefore the function doStuff() gets called. After that the buttonStateBefore is the buttonState so its also true. If the button is still pressed in the next circle both of them are true and therefore the function isn't called.

0
On

Not sure what the analogRead() for as you didn't explain it.

As far as a toggle operation is concerned, it can be done with a single line as:

digitalWrite(2, !digitalRead(2));