Go Down

Topic: blink a led with push button (Read 11353 times) previous topic - next topic

Keisan

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  :-[ )

Grumpy_Mike

Look at the state change detection example in the IDE.

Pedro147

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

UKHeliBob

Here, have this one on me and learn from it
Code: [Select]

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 becomes pressed rather than when it is 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.
Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

jameskirk

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...

Code: [Select]

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

Grumpy_Mike

Quote
I tried to modify the code to use 2 LED's
How exactly do you mean?

Quote
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.


UKHeliBob

Quote
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 ?
Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

jameskirk

Yes flash at different rates...
Thanks

UKHeliBob

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.
Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

jameskirk

#9
Jun 12, 2015, 06:25 pm Last Edit: Jun 12, 2015, 06:28 pm by jameskirk
I redid the code and got rid of most of the errors...
Code: [Select]

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

CrossRoads

Put one more } at the very end to mate with this one:
void loop()
{
Designing & building electrical circuits for over 25 years.  Screw Shield for Mega/Due/Uno,  Bobuino with ATMega1284P, & other '328P & '1284P creations & offerings at  my website.

CrossRoads

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.
Designing & building electrical circuits for over 25 years.  Screw Shield for Mega/Due/Uno,  Bobuino with ATMega1284P, & other '328P & '1284P creations & offerings at  my website.

UKHeliBob

Or double click to the right of a { or a } and have the whole code block that it encloses highlighted
Please do not send me PMs asking for help.  Post in the forum then everyone will benefit from seeing the questions and answers.

jameskirk

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

Code: [Select]
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

CrossRoads

Code: [Select]

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:
Code: [Select]

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


Designing & building electrical circuits for over 25 years.  Screw Shield for Mega/Due/Uno,  Bobuino with ATMega1284P, & other '328P & '1284P creations & offerings at  my website.

Go Up