0

I have a program that flashes three LED in sequence indefinitely. How can O program a pushbutton to pause the program in the middle of the code?

Also, can I modify the code so that pressing the button a second time would speed up the flashing of the LED?

Each time I try to use a pushbutton to pause the program, it only pauses it once the program loops back to the beginning.

Here's my code at the moment (sorry, it's not very clean):

int ledpins[]   = {4, 5, 6};
int buttonpin   = 3;
int buttonstate = 0;

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

  for (int pin = 6; pin > 3; pin--) {
    pinMode(ledpins[pin], OUTPUT);
  }
  pinMode(buttonpin, INPUT);
}

void loop() {
  buttonstate = digitalRead(buttonpin);
  if (buttonstate == HIGH) {
    digitalWrite(ledpins, HIGH);
  }
  if (buttonstate == LOW) {
    for (int pin = 4; pin < 7; pin++) {
      digitalWrite(pin, HIGH);
      delay(200);
      digitalWrite(pin, LOW);
    }
    for (int pin = 6; pin > 3; pin--) {
      digitalWrite(pin, HIGH);
      delay(200);
      digitalWrite(pin, LOW);
    }
  }
}
  • 2
    Take a look at 'Blink without delay'. – tttapa Dec 27 '17 at 23:56
  • 2
    please reformat you code so that it is properly indented and properly spaced – jsotola Dec 28 '17 at 3:11
  • 1
    1) In setup(), you are accessing ledpins[6], which is out of bounds. 2) In loop(), digitalWrite(ledpins, HIGH) makes no sense, as ledpins is not an integer. – Edgar Bonet Dec 28 '17 at 12:26
1

The problem in this code is that the for loops are blocking with delay for 1.2 seconds and only once that ends does the code come back around to check the button. You should instead use the loop function itself to handle the looping and use the Blink Without Delay method of timing to handle the timing. In that way the loop function is never blocked from running and can run thousands of times per second, never missing any presses of the buttons. And also in this way you would be able to pause the program at any point, not just once every 1.2 seconds.

|improve this answer|||||
-1

I think you can use an interrupt for the button. In the handler you can set a state variable somethink like buttonPressed.

It could look like this in the handler:

....
if(buttonPressed != true){
buttonPressed = true;   //This only for the first time
}
else if(buttonPressed){
buttonPressed = false; //Delete the first flag 
speedTime = xxx;       //This only for the second press
}
....

It could look like this in loop (you can set it to the top or bottom of your code):

....

while(buttonPressed){
//Do nothing (pause the programm)
}

....

Before setup write this and replace the 200 in loop with speedTime:

....
int speedTime = 200;
....

To pause your code you will need to wait until you are at the point with while(buttonPressed). For example at the top or bottom. When you push a second time before you are at this point you will only change the time.

If you do not want to wait a time to pause than you will replace this delay(200) functions with something better.

|improve this answer|||||
  • Since you still have to wait until the top of the loop to check that variable, how exactly does this change the situation? You're still in the same boat with having to wait to react to the button press and now you have the added overhead of the interrupt. – Delta_G Feb 28 '18 at 0:20
-1

I would just use a pin interrupt and if the button is pressed the interrupt routine sets a flag (ie flag=1). Then in you loop just have a statement that says calls a function that is just a while loop which waits until flag variable is 0 again. The interrupt function just toggles the flag variable every time the button is pushed. So first time button is pressed the program loops and the second time the button is pressed program execution leaves the routine and goes back to your loop().

|improve this answer|||||

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.