blink a led with push button

Hello, I am a beginner in Arduino programming. My request may seem simple, but I do not know how.

Basically, I have an Arduino board, an LED and a push button. I want to ensure that a first click on the button can blink (loop) an LED, and so, in one second click on this button, the LED will turn off. So on ...

Thank you really for future help!

(bad english spotted :-[ )

Look at the state change detection example in the IDE.

Keisan - Have a look at this and remember "Google is your friend " 8) http://forum.arduino.cc/index.php?topic=58284.0

Here, have this one on me and learn from it

const byte buttonPin = A1;
const byte ledPin = 13;
boolean flashing = false;
byte currentButtonState = HIGH;
byte previousButtonState = HIGH;
unsigned long currentTime;
unsigned long onoffStarted;
long flashPeriod = 1000;

void setup()
{
  pinMode(buttonPin, INPUT_PULLUP);
  pinMode(ledPin, OUTPUT);
}

void loop()
{
  currentButtonState = digitalRead(buttonPin);
  if (currentButtonState != previousButtonState && currentButtonState == LOW)  //button has become pressed
  {
    flashing = !flashing;
  }
  previousButtonState = currentButtonState;          //save the button state for the next check

  if (flashing)
  {
    currentTime = millis();
    if (currentTime - onoffStarted > flashPeriod)  //if the flash period ended ?
    {
      digitalWrite(ledPin, !digitalRead(ledPin));  //flip the state of the LED
      onoffStarted = currentTime;                  //save the time when it occured
    }
  }
  else
  {
    digitalWrite(ledPin, HIGH);  //force the LED off if not flashing
  }
}

It would be simpler to use delay() for the flashing but that would make it impossible to read the button during the delay(). Note also that the flashing is turned on/off when the button [u]becomes[/u] pressed rather than when it [u]is[/u] pressed. It is almost certain that using millis() for timing and detecting the change of button state will be useful in your future programs. Note also the use of INPUT_PULLUP in setting the pinMode() of the button pin. This ensures that the pin is always at a known state rather than floating at an uncertain voltage.

Depending on your wiring you may need to change the logic of the LED control portion of the program which assumes that the LED is off when its pin is taken HIGH.

Hello UKHeliBob I used the code that you posted and it works Great... I tried to modify the code to use 2 LED's but I can't get to work properly... Here is the code that I modified it blinks really dimm...

const byte buttonPin = A1;
const byte ledPin = 13;
const byte ledPin2 = 12;
boolean flashing = false;
byte currentButtonState = HIGH;
byte previousButtonState = HIGH;
unsigned long currentTime;
unsigned long onoffStarted;
long flashPeriod = 150;
long flashPeriod2 = 500;

void setup()
{
  pinMode(buttonPin, INPUT_PULLUP);
  pinMode(ledPin, OUTPUT);
  pinMode(ledPin2, OUTPUT);
}

void loop()
{
  currentButtonState = digitalRead(buttonPin);
  if (currentButtonState != previousButtonState && currentButtonState == LOW)  //button has become pressed
  {
    flashing = !flashing;
  }
  previousButtonState = currentButtonState;          //save the button state for the next check

  if (flashing)
  {
    currentTime = millis();
    if (currentTime - onoffStarted > flashPeriod)  //if the flash period ended ?
    {
      currentTime = millis();
    if (currentTime - onoffStarted > flashPeriod2)  //if the flash period ended ?
    {
      digitalWrite(ledPin, !digitalRead(ledPin));  //flip the state of the LED
      onoffStarted = currentTime;                  //save the time when it occured
    }
    digitalWrite(ledPin2, !digitalRead(ledPin2));  //flip the state of the LED
      onoffStarted = currentTime;                  //save the time when it occured
    
  }
  else
  {
    digitalWrite(ledPin, LOW);  //force the LED off if not flashing
  }
  digitalWrite(ledPin2, LOW);  //force the LED off if not flashing
  }
}

Here is a short video...

Video

Thanks

I tried to modify the code to use 2 LED's

How exactly do you mean?

but I can't get to work properly.

How exactly do you mean?

That code is all mangled up in it's logic. Do currentTime = millis() only once in the loop.

I tried to modify the code to use 2 LED's

What do you want the two LEDs to do ? Flash at different rates perhaps ?

Yes flash at different rates... Thanks

OK. Start with my code and as a crude way of doing what you want, copy the code in the if (flashing) block, paste it back in the block, change the names of all the variables and use a different value for the new flashPeriod variable. There are neater ways to do it using arrays but get it working in any way you can first.

I redid the code and got rid of most of the errors...

const byte buttonPin = A1;
const byte ledPin = 13;
const byte ledPin2 = 12;
boolean flashing = false;
byte currentButtonState = HIGH;
byte previousButtonState = HIGH;
unsigned long currentTime;
unsigned long onoffStarted;
long flashPeriod = 1000;
long flashPeriod2 = 500;

void setup()
{
  pinMode(buttonPin, INPUT_PULLUP);
  pinMode(ledPin, OUTPUT);
  pinMode(ledPin2, OUTPUT);
}

void loop()
{
  currentButtonState = digitalRead(buttonPin);
  if (currentButtonState != previousButtonState && currentButtonState == LOW)  //button has become pressed
  {
    flashing = !flashing;
  }
  previousButtonState = currentButtonState;          //save the button state for the next check

  if (flashing)
  {
    currentTime = millis();
    if (currentTime - onoffStarted > flashPeriod)  //if the flash period ended ?
    {
      digitalWrite(ledPin, !digitalRead(ledPin));  //flip the state of the LED
      onoffStarted = currentTime;                  //save the time when it occured
      
      if (currentTime - onoffStarted > flashPeriod2)  //if the flash period ended ?
    
      digitalWrite(ledPin2, !digitalRead(ledPin2));  //flip the state of the LED
      onoffStarted = currentTime;                  //save the time when it occured
    
  }
  else
  {
    digitalWrite(ledPin, HIGH);  //force the LED off if not flashing
    
    digitalWrite(ledPin2, HIGH);  //force the LED off if not flashing
  }
}

Except these errors...

Arduino: 1.6.3 (Windows 7), Board: "Arduino Nano, ATmega328"

Build options changed, rebuilding all

sketch_jun12a.ino: In function 'void loop()':

sketch_jun12a.ino:48:1: error: expected '}' at end of input

Error compiling.

Any suggestions? Thanks

Put one more } at the very end to mate with this one: void loop() {

If you do Ctrl-T, t it will let you know of mis-matched () and {} also. You can click your cursor to the right of ) and } and use the scroll bar to see where the mating ( and { is.

Or double click to the right of a { or a } and have the whole code block that it encloses highlighted

OK I got the errors fixed but only LED 1 will light up and blink…
Here is the code and a short video…

const byte buttonPin = A1;
const byte ledPin = 13;
const byte ledPin2 = 12;
boolean flashing = false;
byte currentButtonState = HIGH;
byte previousButtonState = HIGH;
unsigned long currentTime;
unsigned long onoffStarted;
long flashPeriod = 300;
long flashPeriod2 = 500;

void setup()
{
  pinMode(buttonPin, INPUT_PULLUP);
  pinMode(ledPin, OUTPUT);
  pinMode(ledPin2, OUTPUT);
}

void loop()
{
  currentButtonState = digitalRead(buttonPin);
  if (currentButtonState != previousButtonState && currentButtonState == LOW)  //button has become pressed
  {
    flashing = !flashing;
  }
  previousButtonState = currentButtonState;          //save the button state for the next check

  if (flashing)
  {
    currentTime = millis();
    if (currentTime - onoffStarted > flashPeriod)  //if the flash period ended ?
    {
      digitalWrite(ledPin, !digitalRead(ledPin));  //flip the state of the LED
      onoffStarted = currentTime;                  //save the time when it occured
      
      if (currentTime - onoffStarted > flashPeriod2)  //if the flash period ended ?
    
      digitalWrite(ledPin2, !digitalRead(ledPin2));  //flip the state of the LED
      onoffStarted = currentTime;                  //save the time when it occured
    } 
  }
  else
  {
    digitalWrite(ledPin, LOW);  //force the LED off if not flashing
    
    digitalWrite(ledPin2, LOW);  //force the LED off if not flashing
  }
}

Video

if (currentTime - onoffStarted > flashPeriod)  //if the flash period ended ?
    {
      digitalWrite(ledPin, !digitalRead(ledPin));  //flip the state of the LED
      onoffStarted = currentTime;                  //save the time when it occured
      
      if (currentTime - onoffStarted > flashPeriod2)  //if the flash period ended ?
    
      digitalWrite(ledPin2, !digitalRead(ledPin2));  //flip the state of the LED
      onoffStarted = currentTime;                  //save the time when it occured
    }

You'll only have a few microseconds between the 2 time comparisons, not hundreds of milliSeconds. So the code will do the first write, not the 2nd, and spend the other time turning them both off.

You need to use a "state" tracker: bothOff 1on, 2on psuedocode example:

void setup(){
state = bothOff
}
void loop(){
if (state==bothOff & time to turn 1 on met){ 
// same time tracking you had above, just added the "state" test
turn on 1
state = 1on
set 1 turn off time
}
if (state==1on & 1 turn off time met){
turn off 1
turn on 2
state = 2on
set 2 turn off time
}
if (state==2on and 2 turn off time met){
turn off 2
state = both off
set 1 turn on time
}
} // end loop

I am still not up to figuring out how to enter the code like that. Do you want me to replace the code in the top box with the code in the bottom box? Thanks

Sigh!

Here you go:

// Blink without "delay()" - multi!

const int led1Pin =  13;    // LED pin number
const int led2Pin =  12;
const int led3Pin =  11;
const int button1 =  A1;

int led1State = LOW;        // initialise the LED
int led2State = LOW;
int led3State = LOW;
char bstate1 = 0;
char togl1 = LOW;

unsigned long count1 = 0;   // will store last time LED was updated
unsigned long count2 = 0;
unsigned long count3 = 0;
unsigned long bcount1 = 0; // button debounce timer.  Replicate as necessary.

// Have we completed the specified interval since last confirmed event?
// "marker" chooses which counter to check 
boolean timeout(unsigned long *marker, unsigned long interval) {
  if (millis() - *marker >= interval) { 
    *marker += interval;    // move on ready for next interval
    return true;       
  } 
  else return false;
}

// Deal with a button read; true if button pressed and debounced is a new event
// Uses reading of button input, debounce store, state store and debounce interval.
// Routines by Paul__B of Arduino Forum
boolean butndown(char button, unsigned long *marker, char *butnstate, unsigned long interval) {
  switch (*butnstate) {               // Odd states if was pressed, >= 2 if debounce in progress
  case 0: // Button up so far, 
    if (button == HIGH) return false; // Nothing happening!
    else { 
      *butnstate = 2;                 // record that is now pressed
      *marker = millis();             // note when was pressed
      return false;                   // and move on
    }

  case 1: // Button down so far, 
    if (button == LOW) return false; // Nothing happening!
    else { 
      *butnstate = 3;                 // record that is now released
      *marker = millis();             // note when was released
      return false;                   // and move on
    }

  case 2: // Button was up, now down.
    if (button == HIGH) {
      *butnstate = 0;                 // no, not debounced; revert the state
      return false;                   // False alarm!
    }
    else { 
      if (millis() - *marker >= interval) {
        *butnstate = 1;               // jackpot!  update the state
        return true;                  // because we have the desired event!
      }
      else 
        return false;                 // not done yet; just move on
    }

  case 3: // Button was down, now up.
    if (button == LOW) {
      *butnstate = 1;                 // no, not debounced; revert the state
      return false;                   // False alarm!
    }
    else { 
      if (millis() - *marker >= interval) {
        *butnstate = 0;               // Debounced; update the state
        return false;                 // but it is not the event we want
      }
      else 
        return false;                 // not done yet; just move on
    }
  default:                            // Error; recover anyway
    {  
      *butnstate = 0;
      return false;                   // Definitely false!
    }
  }
}

void setup() {
  pinMode(led1Pin, OUTPUT);      
  pinMode(led2Pin, OUTPUT);      
  pinMode(led3Pin, OUTPUT);      
  pinMode(button1, INPUT);      
  digitalWrite(button1,HIGH);        // internal pullup all versions
}

void loop() {
  // Toggle switch if button debounced
  if (butndown(digitalRead(button1), &bcount1, &bstate1, 10UL )) {
    if (togl1 == LOW) {
      togl1 = HIGH;
    }
    else {
      togl1 = LOW; 
    } 
  } 

  // flash if toggle is on
  if (togl1 == HIGH) {

    // Act if the latter time (ms) has now passed on this particular counter,
    if (timeout(&count1, 150UL )) {
      if (led1State == LOW) {
        led1State = HIGH;
      }
      else {
        led1State = LOW; 
      } 
      digitalWrite(led1Pin, led1State);
    } 

    if (timeout(&count2, 500UL )) {
      if (led2State == LOW) {
        led2State = HIGH;
      }
      else {
        led2State = LOW; 
      } 
      digitalWrite(led2Pin, led2State);
    } 

    if (timeout(&count3, 77UL )) {
      if (led3State == LOW) {
        led3State = HIGH;
      }
      else
        led3State = LOW; 
      digitalWrite(led3Pin, led3State);
    }      
  }
  else {
    led1State = LOW; 
    led2State = LOW; 
    led3State = LOW; 
    digitalWrite(led1Pin, led1State);
    digitalWrite(led2Pin, led2State);
    digitalWrite(led3Pin, led3State);
  } 
}

Note: Button always goes to ground, using internal pull-up.

That works perfectly... Thanks so much

There is one more thing that I need to add
to this sketch; it is a non blinking LED…
I tried adding just another line for the LED but it doesn’t work…
Can someone give me some info as how to add one to this sketch?
Thanks
Mike

Please explain exactly what you want and post your attempt at doing it.