Skip to main content
added comments to code
Source Link
Enric Blanco
  • 2.1k
  • 1
  • 14
  • 25
#include "Timer.h"

// Pin 13 has a LED connected on most Arduino boards.
// give it a name:
const int led = 13;
const int buttonPin = 2;

// declare state variables as global
bool buttonState = LOW;
bool buttonState_prev = LOW;
bool toggleBlinking;
bool blinkState;

// declare a Timer object so blinking can be done without loosing button presses
Timer timer_b;
int blink_id;

// the setup routine runs once when you press reset:
void setup() {
  // initialize the digital pin as an output.
  pinMode(led, OUTPUT);
  pinMode(buttonPin, INPUT_PULLUP);

  // initial state: toggle led each 1000 ms
  blink_id = timer_b.oscillate(led, 1000, HIGH);
  blinkState = true;
  toggleBlinking = false;
}

// the loop routine runs over and over again forever:
void loop() {
  // Update the timer (required)
  timer_b.update();

  // check if button has been pressed (HIGH to LOW),
  // then debounce it and raise toggle flag
  buttonState = digitalRead(buttonPin);
  if ((buttonState != buttonState_prev) && (buttonState_prev == HIGH)) {
    // simple button debounce (confirm press after some ms)
    delay (50); // may interfere with the timer?
    buttonState = digitalRead(buttonPin);
    if (buttonState != buttonState_prev) toggleBlinking = true;
  }

  // dokeep eithercurrent oneLED thingstate orunless another,the accordingbutton tohas buttonStatebeen pushed
  switch (blinkState) {
    case true:
      // if button has been pushed, stop blinking and change LED state
      if (toggleBlinking == true) {
        timer_b.stop (blink_id);
        blinkState = false;
      }
      break;
    case false:
      digitalWrite(led, LOW);
      // if button has been pushed, start blinking and change LED state
      if (toggleBlinking == true) {
        blink_id = timer_b.oscillate(led, 1000, HIGH);
        blinkState = true;
      }
      break;
  }

  buttonState_prev = buttonState;
  toggleBlinking = false;
}
#include "Timer.h"

// Pin 13 has a LED connected on most Arduino boards.
// give it a name:
const int led = 13;
const int buttonPin = 2;

// declare state variables as global
bool buttonState = LOW;
bool buttonState_prev = LOW;
bool toggleBlinking;
bool blinkState;

// declare a Timer object so blinking can be done without loosing button presses
Timer timer_b;
int blink_id;

// the setup routine runs once when you press reset:
void setup() {
  // initialize the digital pin as an output.
  pinMode(led, OUTPUT);
  pinMode(buttonPin, INPUT_PULLUP);

  // initial state: toggle led each 1000 ms
  blink_id = timer_b.oscillate(led, 1000, HIGH);
  blinkState = true;
  toggleBlinking = false;
}

// the loop routine runs over and over again forever:
void loop() {
  // Update the timer (required)
  timer_b.update();

  // check if button has been pressed (HIGH to LOW),
  // then debounce it and raise toggle flag
  buttonState = digitalRead(buttonPin);
  if ((buttonState != buttonState_prev) && (buttonState_prev == HIGH)) {
    // simple button debounce (confirm press after some ms)
    delay (50); // may interfere with the timer?
    buttonState = digitalRead(buttonPin);
    if (buttonState != buttonState_prev) toggleBlinking = true;
  }

  // do either one thing or another, according to buttonState
  switch (blinkState) {
    case true:
      if (toggleBlinking == true) {
        timer_b.stop (blink_id);
        blinkState = false;
      }
      break;
    case false:
      digitalWrite(led, LOW);
      if (toggleBlinking == true) {
        blink_id = timer_b.oscillate(led, 1000, HIGH);
        blinkState = true;
      }
      break;
  }

  buttonState_prev = buttonState;
  toggleBlinking = false;
}
#include "Timer.h"

// Pin 13 has a LED connected on most Arduino boards.
// give it a name:
const int led = 13;
const int buttonPin = 2;

// declare state variables as global
bool buttonState = LOW;
bool buttonState_prev = LOW;
bool toggleBlinking;
bool blinkState;

// declare a Timer object so blinking can be done without loosing button presses
Timer timer_b;
int blink_id;

// the setup routine runs once when you press reset:
void setup() {
  // initialize the digital pin as an output.
  pinMode(led, OUTPUT);
  pinMode(buttonPin, INPUT_PULLUP);

  // initial state: toggle led each 1000 ms
  blink_id = timer_b.oscillate(led, 1000, HIGH);
  blinkState = true;
  toggleBlinking = false;
}

// the loop routine runs over and over again forever:
void loop() {
  // Update the timer (required)
  timer_b.update();

  // check if button has been pressed (HIGH to LOW),
  // then debounce it and raise toggle flag
  buttonState = digitalRead(buttonPin);
  if ((buttonState != buttonState_prev) && (buttonState_prev == HIGH)) {
    // simple button debounce (confirm press after some ms)
    delay (50);
    buttonState = digitalRead(buttonPin);
    if (buttonState != buttonState_prev) toggleBlinking = true;
  }

  // keep current LED state unless the button has been pushed
  switch (blinkState) {
    case true:
      // if button has been pushed, stop blinking and change LED state
      if (toggleBlinking == true) {
        timer_b.stop (blink_id);
        blinkState = false;
      }
      break;
    case false:
      digitalWrite(led, LOW);
      // if button has been pushed, start blinking and change LED state
      if (toggleBlinking == true) {
        blink_id = timer_b.oscillate(led, 1000, HIGH);
        blinkState = true;
      }
      break;
  }

  buttonState_prev = buttonState;
  toggleBlinking = false;
}
code debugged and link to library included
Source Link
Enric Blanco
  • 2.1k
  • 1
  • 14
  • 25
#include "Timer.h"

// Pin 13 has a LED connected on most Arduino boards.
// give it a name:
const int led = 13;
const int buttonPin = 2;

// declare state variables as global
bool buttonState = LOW;
bool buttonState_prev = LOW;
bool toggleBlinking;
bool blinkState;

// declare a Timer object so blinking can be done without loosing button presses
Timer timer_b;
int blink_id;

// the setup routine runs once when you press reset:
void setup() {
  // initialize the digital pin as an output.
  pinMode(led, OUTPUT);
  pinMode(buttonPin, INPUT_PULLUP);

  // initial state: toggle led each 1000 ms
  blink_id = timer_b.oscillate(led, 1000, HIGH);
  blinkState = True;true;
  toggleBlinking = False;false;
}

// the loop routine runs over and over again forever:
void loop() {
  // Update the timer (required)
  timer_b.update();

  // check if button has been pressed (HIGH to LOW),
  // then debounce it and raise toggle flag
  buttonState = digitalRead(buttonPin);
  if ((buttonState != buttonState_prev) && (buttonState_prev == HIGH)) {
    // simple button debounce (confirm press after some ms)
    delay (50); // may interfere with the timer?
    buttonState = digitalRead(buttonPin);
    if (buttonState != buttonState_prev) toggleBlinking = True;true;
  }

  // do either one thing or another, according to buttonState
  switch (blinkState) {
    case Truetrue:
      if (toggleBlinking == Truetrue) {
        timer_b.stop (blink_id);
        blinkState = False;false;
      }
      break;
    case Falsefalse:
      digitalWrite(led, LOW);
      if (toggleBlinking == Truetrue) {
        blink_id = timer_b.oscillate(led, 1000, HIGH);
        blinkState = True;true;
      }
      break;
  }

  buttonState_prev = buttonState;
  toggleBlinking = False;false;
}

NOTE: You'll need to install the Timer.h libraryTimer.h library. Also, I HAVE NOTI'VE TESTED THEMY CODE, TAKE IT AS A FIRST STEP AND FURTHER DEVELOP THE IDEA YOURSELFIT WORKS.

#include "Timer.h"

// Pin 13 has a LED connected on most Arduino boards.
// give it a name:
const int led = 13;
const int buttonPin = 2;

// declare state variables as global
bool buttonState = LOW;
bool buttonState_prev = LOW;
bool toggleBlinking;
bool blinkState;

// declare a Timer object so blinking can be done without loosing button presses
Timer timer_b;
int blink_id;

// the setup routine runs once when you press reset:
void setup() {
  // initialize the digital pin as an output.
  pinMode(led, OUTPUT);
  pinMode(buttonPin, INPUT_PULLUP);

  // initial state: toggle led each 1000 ms
  blink_id = timer_b.oscillate(led, 1000, HIGH);
  blinkState = True;
  toggleBlinking = False;
}

// the loop routine runs over and over again forever:
void loop() {
  // Update the timer (required)
  timer_b.update();

  // check if button has been pressed (HIGH to LOW),
  // then debounce it and raise toggle flag
  buttonState = digitalRead(buttonPin);
  if ((buttonState != buttonState_prev) && (buttonState_prev == HIGH)) {
    // simple button debounce (confirm press after some ms)
    delay (50); // may interfere with the timer?
    buttonState = digitalRead(buttonPin);
    if (buttonState != buttonState_prev) toggleBlinking = True;
  }

  // do either one thing or another, according to buttonState
  switch (blinkState) {
    case True:
      if (toggleBlinking == True) {
        timer_b.stop (blink_id);
        blinkState = False;
      break;
    case False:
      if (toggleBlinking == True) {
        blink_id = timer_b.oscillate(led, 1000, HIGH);
        blinkState = True;
      break;
  }

  buttonState_prev = buttonState;
  toggleBlinking = False;
}

NOTE: You'll need to install the Timer.h library. Also, I HAVE NOT TESTED THE CODE, TAKE IT AS A FIRST STEP AND FURTHER DEVELOP THE IDEA YOURSELF.

#include "Timer.h"

// Pin 13 has a LED connected on most Arduino boards.
// give it a name:
const int led = 13;
const int buttonPin = 2;

// declare state variables as global
bool buttonState = LOW;
bool buttonState_prev = LOW;
bool toggleBlinking;
bool blinkState;

// declare a Timer object so blinking can be done without loosing button presses
Timer timer_b;
int blink_id;

// the setup routine runs once when you press reset:
void setup() {
  // initialize the digital pin as an output.
  pinMode(led, OUTPUT);
  pinMode(buttonPin, INPUT_PULLUP);

  // initial state: toggle led each 1000 ms
  blink_id = timer_b.oscillate(led, 1000, HIGH);
  blinkState = true;
  toggleBlinking = false;
}

// the loop routine runs over and over again forever:
void loop() {
  // Update the timer (required)
  timer_b.update();

  // check if button has been pressed (HIGH to LOW),
  // then debounce it and raise toggle flag
  buttonState = digitalRead(buttonPin);
  if ((buttonState != buttonState_prev) && (buttonState_prev == HIGH)) {
    // simple button debounce (confirm press after some ms)
    delay (50); // may interfere with the timer?
    buttonState = digitalRead(buttonPin);
    if (buttonState != buttonState_prev) toggleBlinking = true;
  }

  // do either one thing or another, according to buttonState
  switch (blinkState) {
    case true:
      if (toggleBlinking == true) {
        timer_b.stop (blink_id);
        blinkState = false;
      }
      break;
    case false:
      digitalWrite(led, LOW);
      if (toggleBlinking == true) {
        blink_id = timer_b.oscillate(led, 1000, HIGH);
        blinkState = true;
      }
      break;
  }

  buttonState_prev = buttonState;
  toggleBlinking = false;
}

NOTE: You'll need to install the Timer.h library. I'VE TESTED MY CODE AND IT WORKS.

major changes according to the clarifications of the OP.
Source Link
Enric Blanco
  • 2.1k
  • 1
  • 14
  • 25

EDITED

The Arduino loop() function makes the use of a while loop redundant in this case. Even worse: the way you've implemented that while loop prevents buttonState from being updated, thus getting stuck in the loop.

What you actually need is to use timers to blink the LED, and a 2-state machine driven by HIGH to LOW button transitions.

Try this instead:

#include "Timer.h"

// Pin 13 has a LED connected on most Arduino boards.
// give it a name:
const int led = 13;
const int buttonPin = 2;

// declare state variablevariables as global
bool buttonState = LOW;
bool buttonState_prev = LOW;
bool toggleBlinking;
bool blinkState;

// declare a Timer object so blinking can be done without loosing button presses
Timer timer_b;
int blink_id;

// the setup routine runs once when you press reset:
void setup() {
  // initialize the digital pin as an output.
  pinMode(led, OUTPUT);
  pinMode(buttonPin, INPUT_PULLUP); 

  // initial state: LOWtoggle led each 1000 ms
  digitalWriteblink_id = timer_b.oscillate(led, LOW1000, HIGH);
  blinkState = True;
  toggleBlinking = False;
}

// the loop routine runs over and over again forever:
void loop() 
 {
  // Update the timer (required)
  timer_b.update();

  // check if button has been pressed at(HIGH theto startLOW),
 of each// loop()then iterationdebounce it and raise toggle flag
  buttonState = digitalRead(buttonPin);
 
  // do either one thing orif another,((buttonState according!= tobuttonState_prev) buttonState
&& (buttonState_prev switch== (buttonStateHIGH)) {
    case// LOW:
simple button debounce (confirm press after digitalWrite(led,some HIGHms); 
   // turndelay the(50); LED// onmay (HIGHinterfere iswith the voltage level)timer?
    buttonState = delaydigitalRead(1000buttonPin);  
    if (buttonState != buttonState_prev) toggleBlinking = True;
  }

  // waitdo foreither aone second
thing or another, according to buttonState
 digitalWrite(led, LOWswitch (blinkState); {
   // turncase theTrue:
 LED off by making the voltageif LOW(toggleBlinking == True) {
      delay  timer_b.stop (1000blink_id); 
        blinkState = False;
     // waitbreak;
 for a second
 case False:
    break;
  if (toggleBlinking case== HIGH:True) {
      digitalWrite  blink_id = timer_b.oscillate(led, LOW1000, HIGH);
        blinkState = True;
      break;
  } 

  buttonState_prev = buttonState;
  toggleBlinking = False;
}

As you can see, it first checks the value of the button, then executes code according to that.

NOTE: There are better waysYou'll need to implementinstall the functionality you're looking forTimer.h library. Also, but I've just tried to do as few changes as possible to your code so you can grasp the specific problem that has been bugging youI HAVE NOT TESTED THE CODE, TAKE IT AS A FIRST STEP AND FURTHER DEVELOP THE IDEA YOURSELF.

The Arduino loop() function makes the use of a while loop redundant in this case. Even worse: the way you've implemented that while loop prevents buttonState from being updated, thus getting stuck in the loop.

Try this instead:

// Pin 13 has a LED connected on most Arduino boards.
// give it a name:
const int led = 13;
const int buttonPin = 2;

// declare state variable as global
bool buttonState = LOW;

// the setup routine runs once when you press reset:
void setup() {
  // initialize the digital pin as an output.
  pinMode(led, OUTPUT);
  pinMode(buttonPin, INPUT_PULLUP);
  // initial state: LOW
  digitalWrite(led, LOW);
}

// the loop routine runs over and over again forever:
void loop() 
 {
  // check if button has been pressed at the start of each loop() iteration
  buttonState = digitalRead(buttonPin);
 
  // do either one thing or another, according to buttonState
  switch (buttonState) {
    case LOW:
      digitalWrite(led, HIGH);   // turn the LED on (HIGH is the voltage level)
      delay(1000);               // wait for a second
      digitalWrite(led, LOW);    // turn the LED off by making the voltage LOW
      delay(1000);               // wait for a second
      break;
    case HIGH:
      digitalWrite(led, LOW);
  }
}

As you can see, it first checks the value of the button, then executes code according to that.

NOTE: There are better ways to implement the functionality you're looking for, but I've just tried to do as few changes as possible to your code so you can grasp the specific problem that has been bugging you.

EDITED

The Arduino loop() function makes the use of a while loop redundant in this case. Even worse: the way you've implemented that while loop prevents buttonState from being updated, thus getting stuck in the loop.

What you actually need is to use timers to blink the LED, and a 2-state machine driven by HIGH to LOW button transitions.

Try this instead:

#include "Timer.h"

// Pin 13 has a LED connected on most Arduino boards.
// give it a name:
const int led = 13;
const int buttonPin = 2;

// declare state variables as global
bool buttonState = LOW;
bool buttonState_prev = LOW;
bool toggleBlinking;
bool blinkState;

// declare a Timer object so blinking can be done without loosing button presses
Timer timer_b;
int blink_id;

// the setup routine runs once when you press reset:
void setup() {
  // initialize the digital pin as an output.
  pinMode(led, OUTPUT);
  pinMode(buttonPin, INPUT_PULLUP); 

  // initial state: toggle led each 1000 ms
  blink_id = timer_b.oscillate(led, 1000, HIGH);
  blinkState = True;
  toggleBlinking = False;
}

// the loop routine runs over and over again forever:
void loop() {
  // Update the timer (required)
  timer_b.update();

  // check if button has been pressed (HIGH to LOW),
  // then debounce it and raise toggle flag
  buttonState = digitalRead(buttonPin);
  if ((buttonState != buttonState_prev) && (buttonState_prev == HIGH)) {
    // simple button debounce (confirm press after some ms) 
    delay (50); // may interfere with the timer?
    buttonState = digitalRead(buttonPin); 
    if (buttonState != buttonState_prev) toggleBlinking = True;
  }

  // do either one thing or another, according to buttonState
  switch (blinkState) {
    case True:
      if (toggleBlinking == True) {
        timer_b.stop (blink_id); 
        blinkState = False;
      break;
    case False:
      if (toggleBlinking == True) {
        blink_id = timer_b.oscillate(led, 1000, HIGH);
        blinkState = True;
      break;
  } 

  buttonState_prev = buttonState;
  toggleBlinking = False;
}

NOTE: You'll need to install the Timer.h library. Also, I HAVE NOT TESTED THE CODE, TAKE IT AS A FIRST STEP AND FURTHER DEVELOP THE IDEA YOURSELF.

corrected misuse of "deadlock" concept
Source Link
Enric Blanco
  • 2.1k
  • 1
  • 14
  • 25
Loading
Source Link
Enric Blanco
  • 2.1k
  • 1
  • 14
  • 25
Loading