Home > Software engineering >  Trying to press a button and toggle an LED flash at 2Hz until i press the button again
Trying to press a button and toggle an LED flash at 2Hz until i press the button again

Time:10-14

i'm trying to learn coding and this has really stumped me so i thought i would ask you lovely people.

basically i'm trying to press a button and have an LED toggle on that is flashing on and off twice in a second, this will be continuous until i press the button again that will turn it off.

here is my code so far.

bool latch = false;

void setup(){
pinMode(1, INPUT);
pinMode(13, OUTPUT);
}
void loop(){
if (digitalRead(1)){
  latch = !latch;
}
if (latch == 1){
  digitalWrite(13, HIGH);
  delay(1000);
  digitalWrite(13, LOW);
  delay(1000);
}else{
  digitalWrite(13, LOW)
}
}

CodePudding user response:

Because of the calls to delay(1000), your code requires you to press the button in the exact split-second instant when digitalRead(1) is called. The Arduino cannot listen for button presses while delay() is in action. Also, you call delay(1000) twice, which flashes the LED on and off once in two seconds, not twice in once second.

The solution is to make a counter that counts how many milliseconds have passed since the last time the LED was toggled on or off. The loop will add 1 to counter every millisecond, so that when counter is equal to or greater than 500 (half a second), the LED toggles on or off.

Here is a program that starts blinking the LED (on-and-off in 1 second) when the button is pressed, and stops blinking when the button is pressed again. There are more explanations in the code.

bool latch = false;
bool led_state = false;

// How many milliseconds it has been since the last LED state change
int counter = 0;

void setup() {
  pinMode(2, INPUT);
  pinMode(13, OUTPUT);
}
void loop() {

  // Check if the button was pressed
  if (digitalRead(2)){

    // If the button was pressed, wait half a second before toggling latch,
    // to "de-bounce" the button (prevent it from sending multiple clicks for
    // one press)
    delay(300);
    latch = !latch;
  }

  // If we are in on state (latch == true)...
  if (latch) {

    // ...add 1 to the counter and wait 1 millisecond...
    counter  = 1;
    delay(1);

    // ...and toggle the LED state if 500 milliseconds have passed.
    // This we know because counter >= 500.
    if (counter >= 500) {
      if (led_state == true) led_state = false;
      else if (led_state == false) led_state = true;
      counter = 0;
    }
    digitalWrite(13, led_state);

  // If we are in off state, turn the LED off
  } else {
    digitalWrite(13, false);
  }
}

If you have any questions, or something wasn't what you wanted, let me know!

CodePudding user response:

I did some experimenting with a simulator similar to what i assume you setup is(use this to setup your situation for future Arduino questions to make it easier for people to understand and help)

https://wokwi.com/arduino/projects/312378906051084864

Besides adding a missing semi-colon here, and working with what i assume your knowledge of programming is

Before

}else{
  digitalWrite(13, LOW)
}

After

}else{
  digitalWrite(13, LOW);
}

I made the small change to your if statement and this makes it work with some specific uses you must tap the button to turn it on and hold it when you think the interval is about to expire. This is because of your use of the delay function which basically stops all execution of your program until the interval is over. So the pin associated with you button must be high after the delay intervals and during if latch is evaluated

if (digitalRead(1)){
  latch = true;
}else{
latch = false;
}

RECOMMENDED ALTERNATIVE

If you are interested in a better slightly more advance application of code i found this reference which provides a way to make a led blink without the use of the delay function

https://www.arduino.cc/en/Tutorial/BuiltInExamples/BlinkWithoutDelay

  • Related