How to halt code while button is pressed?

So, I need to be able to press a button and for it to advance or decrease a variable by 1. But I need the code to pause while the button is pressed so that the same press is not counted multiple times. With what im trying right now, it halts the code but it never resumes after the button is released because the way im halting stops it from ever seeing that the button was released. Any suggestions?

Code:

int led1 = 13; // pin connected to led 1
int led2 = 12; // pin connected to led 2
int led3 = 11; // pin connected to led 3
int downButton = 7; // button used to decrease value
int upButton = 2;   // button used to increase value
int ledValue = 0;
void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);
  pinMode(downButton, INPUT);
  pinMode(upButton, INPUT);
  pinMode(3, OUTPUT);
  digitalWrite(led1, LOW);
  digitalWrite(led2, LOW);
  digitalWrite(led3, LOW);
}

void loop() {
  
  // put your main code here, to run repeatedly:
  digitalWrite(3, HIGH);
  Serial.println(ledValue);
  if (ledValue == 1){
    digitalWrite(led1, HIGH);
  } else {
    digitalWrite(led1, LOW);
  }
  if (ledValue == 2){
    digitalWrite(led2, HIGH);
  } else {
    digitalWrite(led2, LOW);
  }
  if (ledValue == 3){
    digitalWrite(led3, HIGH);
  } else {
    digitalWrite(led3, LOW);
  }
    if (digitalRead(upButton) == 1){
      ledValue = (ledValue + 1);
      while(digitalRead(upButton) == 1) {
        delayMicroseconds(digitalRead(1));
      }
      }
     
  
    
}

New people should avoid using while{ } as it can be blocking; use it for fast advancing situations only.


Look at when a switch changes state.


Where do you ever reset ledValue ?


Always show us a good schematic of your proposed circuit.
Show us a good image of your ‘actual’ wiring.
Give links to components.


Edit

FYI

1 Like

What is "it"?

Produce a flowchart telling about the intended flow in the code.
What's the big picture of the project?

That's not the normal solution, which is to detect when the button state has changed, not what it is.

https://docs.arduino.cc/built-in-examples/digital/StateChangeDetection

Thank you for the help, I tried implementing this method, and it works, but only once, it will not count past 1.

Show us your attempt.

How is the switch wired ?

This project is not fully written out, I'm testing as I go, but it is meant to have 2 buttons which raise or decrease a number. That number in turn lights up an led corresponding to that number. Upon completion it will not be lighting up leds but turning on solenoids after passing through a circuit amplifying it to 12 volts instead of 5.

Its a button with one side hooked to 5 volts and the other hooked to input pin 2, with a pulldown resistor to prevent floating

Assume the pull-down goes to the pin and GND (0v).

Yes.

Show us your attempt.

Sorry, I thought I did.

Code:

int led2 = 12; // pin connected to led 2
int led3 = 11; // pin connected to led 3
int downButton = 7; // button used to decrease value
int upButton = 2;   // button used to increase value
int ledValue = 0;
int upButtonState = 0;
int lastUpButtonState = 0;
int downButtonState = 0;
int lastDownButtonState = 0;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);
  pinMode(downButton, INPUT);
  pinMode(upButton, INPUT);
  pinMode(3, OUTPUT);
  digitalWrite(led1, LOW);
  digitalWrite(led2, LOW);
  digitalWrite(led3, LOW);
}

void loop() {
  Serial.println("begin");
  // put your main code here, to run repeatedly:
  digitalWrite(3, HIGH);
  //read buttons
  upButtonState = digitalRead(upButton);
  downButtonState = digitalRead(downButton);

  //compare buttonState to previous state
  if (upButtonState != lastUpButtonState) {
    // if state has changed changed ledValue
    if (upButtonState == HIGH){
      ledValue++; }}
  if (downButtonState != lastDownButtonState) {
    // if state has changed changed ledValue
    if (downButtonState == LOW){
      ledValue--; }
    delay(50);
  }
  // print state
  Serial.println("lastUpButtonState");
  Serial.println(lastUpButtonState);
  Serial.println("lastDownButtonState");
  Serial.println(lastDownButtonState);

  // save state for next round
  lastUpButtonState = upButtonState;
  lastDownButtonState = downButtonState;

  Serial.println("ledValue");
  Serial.println(ledValue);
  if (ledValue == 1){
    digitalWrite(led1, HIGH);
  } else {
    digitalWrite(led1, LOW);
  }
  if (ledValue == 2){
    digitalWrite(led2, HIGH);
  } else {
    digitalWrite(led2, LOW);
  }
  if (ledValue == 3){
    digitalWrite(led3, HIGH);
  } else {
    digitalWrite(led3, LOW);
  }
    
     
  
    
} ```

After pressing a button serial shows all values as 1.

18:33:57.001 -> lastUpButtonState
18:33:57.001 -> 1
18:33:57.001 -> lastDownButtonState
18:33:57.048 -> 1
18:33:57.048 -> up Button
18:33:57.048 -> 1
18:33:57.048 -> down button
18:33:57.094 -> 1
18:33:57.094 -> ledValue
18:33:57.094 -> 1

You are only supposed to do this when a state change is detected, not every time through loop().

In fairness, the example sketch does the same. :face_with_raised_eyebrow:

I remedied this, but am still having the same behavior.

Code:

int led1 = 13; // pin connected to led 1
int led2 = 12; // pin connected to led 2
int led3 = 11; // pin connected to led 3
int downButton = 7; // button used to decrease value
int upButton = 2;   // button used to increase value
int ledValue = 0;
int upButtonState = 0;
int lastUpButtonState = 0;
int downButtonState = 0;
int lastDownButtonState = 0;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);
  pinMode(downButton, INPUT);
  pinMode(upButton, INPUT);
  pinMode(3, OUTPUT);
  digitalWrite(led1, LOW);
  digitalWrite(led2, LOW);
  digitalWrite(led3, LOW);
}

void loop() {
  Serial.println("begin");
  // put your main code here, to run repeatedly:
  digitalWrite(3, HIGH);
  //read buttons
  upButtonState = digitalRead(upButton);
  downButtonState = digitalRead(downButton);

  //compare buttonState to previous state
  if (upButtonState != lastUpButtonState) {
    // if state has changed changed ledValue
    if (upButtonState == HIGH){
      ledValue++; }
   lastUpButtonState = upButtonState;
      }
  if (downButtonState != lastDownButtonState) {
    // if state has changed changed ledValue
    if (downButtonState == LOW){
      ledValue--; }
   lastDownButtonState = downButtonState;
      }
    delay(50);
 
  // print state
  Serial.println("lastUpButtonState");
  Serial.println(lastUpButtonState);
  Serial.println("lastDownButtonState");
  Serial.println(lastDownButtonState);
  Serial.println("up Button");
  Serial.println(digitalRead(upButton));
  Serial.println("down button");
  Serial.println(digitalRead(downButton));

  Serial.println("ledValue");
  Serial.println(ledValue);
  if (ledValue == 1){
    digitalWrite(led1, HIGH);
  } else {
    digitalWrite(led1, LOW);
  }
  if (ledValue == 2){
    digitalWrite(led2, HIGH);
  } else {
    digitalWrite(led2, LOW);
  }
  if (ledValue == 3){
    digitalWrite(led3, HIGH);
  } else {
    digitalWrite(led3, LOW);
  }
    
     
  
    
}```

Try:

const byte led1                 = 13; //pin connected to led 1
const byte led2                 = 12; //pin connected to led 2
const byte led3                 = 11; //pin connected to led 3
const byte downButton           = 7;  //button used to decrease value
const byte upButton             = 2;  //button used to increase value

byte upButtonState              = 0;
byte lastUpButtonState          = 0;
byte downButtonState            = 0;
byte lastDownButtonState        = 0;

int ledValue                    = 0;

//********************************************^************************************************
void setup()
{
  // put your setup code here, to run once:
  Serial.begin(9600);
  
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);

  pinMode(downButton, INPUT);
  pinMode(upButton, INPUT);

  digitalWrite(led1, LOW);
  digitalWrite(led2, LOW);
  digitalWrite(led3, LOW);

} //END of   setup()


//********************************************^************************************************
void loop()
{
  //*********************************
  upButtonState = digitalRead(upButton);

  if (upButtonState != lastUpButtonState)
  {
    //update to the new state
    lastUpButtonState = upButtonState;

    // if state has changed changed ledValue
    if (upButtonState == HIGH)
    {
      ledValue++;

      if (ledValue > 3)
      {
        ledValue = 3;
      }
    }
  }

  //*********************************
  downButtonState = digitalRead(downButton);

  if (downButtonState != lastDownButtonState)
  {
    //update to the new state
    lastDownButtonState = downButtonState;

    // if state has changed changed ledValue
    if (downButtonState == HIGH)
    {
      ledValue--;

      if (ledValue < 1)
      {
        ledValue = 1;
      }
    }
  }

  //*********************************
  if (ledValue == 1)
  {
    digitalWrite(led1, HIGH);
  }

  else
  {
    digitalWrite(led1, LOW);
  }

  //*********************************
  if (ledValue == 2)
  {
    digitalWrite(led2, HIGH);
  }

  else
  {
    digitalWrite(led2, LOW);
  }

  //*********************************
  if (ledValue == 3)
  {
    digitalWrite(led3, HIGH);
  }

  else
  {
    digitalWrite(led3, LOW);
  }

  //*********************************
  Serial.print("ledValue = ");
  Serial.println(ledValue);

} //END of   loop()

What does this do?

It either does delay for one micro second or it does not.
On uno it will likely delay for more than one micro second as the precision of delayMicrosecond is around 4 micro second.
Question remaining: is this OP's intention?


// https://forum.arduino.cc/t/how-to-halt-code-while-button-is-pressed/1021719

//********************************************^************************************************
//  LEDsControlledBySwitches.ino
//
//
//  Version   YY/MM/DD     Comments
//  =======   ========     ========================================================
//  1.00      22/08/12     Running code
//
//********************************************^************************************************

#define PUSHED                    HIGH
#define RELEASED                  LOW

const byte heartbeatLED         = 13; //pin connected to heartbeat led

const byte led1                 = 12; //pin connected to led 1
const byte led2                 = 11; //pin connected to led 2
const byte led3                 = 10; //pin connected to led 3

const byte downButton           = 7;  //button used to decrease value
const byte upButton             = 2;  //button used to increase value

byte upButtonState              = 0;
byte lastUpButtonState          = 0;
byte downButtonState            = 0;
byte lastDownButtonState        = 0;

int ledValue                    = 0;

//timing stuff
unsigned long heartbeatMillis;
unsigned long switchMillis;


//                                       s e t u p ( )
//********************************************^************************************************
void setup()
{
  Serial.begin(9600);

  pinMode(heartbeatLED, OUTPUT);

  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT);

  pinMode(downButton, INPUT);
  pinMode(upButton, INPUT);

  digitalWrite(led1, LOW);
  digitalWrite(led2, LOW);
  digitalWrite(led3, LOW);

} //END of   setup()


//                                        l o o p ( )
//********************************************^************************************************
void loop()
{
  //*********************************                        heartbeat T I M E R
  //is it time to toggle the heartbeatLED ?
  if (millis() - heartbeatMillis >= 500ul)
  {
    //restart this TIMER
    heartbeatMillis = millis();

    //toggle the heartbeatLED
    digitalWrite(heartbeatLED, !digitalRead(heartbeatLED));
  }

  //*********************************                        checkSwitches T I M E R
  //is it time to check the switches ?
  if (millis() - switchMillis > 50)
  {
    //restart this TIMER
    switchMillis = millis();

    checkSwitches();
  }

} //END of   loop()


//                               c h e c k S w i t c h e s ( )
//********************************************^************************************************
//this function is called every 50ms, this effectively de-bounces the inputs
void checkSwitches()
{
  //*********************************                           u p B u t t o n
  upButtonState = digitalRead(upButton);

  //was there a change in the switch state ?
  if (upButtonState != lastUpButtonState)
  {
    //update to the new state
    lastUpButtonState = upButtonState;

    //if state has changed, change ledValue
    if (upButtonState == PUSHED)
    {
      ledValue++;

      if (ledValue > 3)
      {
        ledValue = 3;
      }

      else
      {
        Serial.print("ledValue = ");
        Serial.println(ledValue);
      }

      updateLEDs();
    }

  } //END of   upButton

  //*********************************                           d o w n B u t t o n
  downButtonState = digitalRead(downButton);

  //was there a change in the switch state ?
  if (downButtonState != lastDownButtonState)
  {
    //update to the new state
    lastDownButtonState = downButtonState;

    //if state has changed, change ledValue
    if (downButtonState == PUSHED)
    {
      ledValue--;

      if (ledValue < 1)
      {
        ledValue = 1;
      }

      else
      {
        Serial.print("ledValue = ");
        Serial.println(ledValue);
      }

      updateLEDs();
    }

  } //END of   downButton

} //END of   checkSwitches()


//                                  u p d a t e L E D s ( )
//********************************************^************************************************
void updateLEDs()
{
  //using switch/case might be a more effective way of doing the following
  
  //*********************************
  if (ledValue == 1)
  {
    digitalWrite(led1, HIGH);
  }

  else
  {
    digitalWrite(led1, LOW);
  }

  //*********************************
  if (ledValue == 2)
  {
    digitalWrite(led2, HIGH);
  }

  else
  {
    digitalWrite(led2, LOW);
  }

  //*********************************
  if (ledValue == 3)
  {
    digitalWrite(led3, HIGH);
  }

  else
  {
    digitalWrite(led3, LOW);
  }

} //END of   updateLEDs()


//********************************************^************************************************

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