Programming issue with push button to keep LED on

I went through all the examples in the book (Make: Getting started…)
and kept getting the flashing LED.
It compiled fine and uploaded fine as well, I even added the additional code from Tami Takamiya and fiddled with the delay and tried a new resisitor, but it still just flashes when I press the button.

<
//Turn on LED while the button is pressed and leave on
const int LED = 13; // The pin for the LED
const int BUTTON = 7; //the input where the
//pushbutton is connected
int val=0; //val will be used to store the state
//of the input pin
int old_val=0; //this vriable stores the previous
// value of “val”
int state=0; //0=LED offand 1 =LED on
void setup() {
pinMode(LED, OUTPUT); //tell Arduino LED is an ouput
pinMode(BUTTON, INPUT); //and BUTTON is an input
}

void loop(){
val = digitalRead(BUTTON); //read input valuse and store it
//yum,fresh
//Check if there was a transition
if ((val == HIGH)&&(old_val == LOW))
if ((val ==LOW)&&(old_val == HIGH)){
state = 1 - state;
delay(20);
}
old_val = val; // val is now old, let’s store it

if (state == 1){
digitalWrite(LED,HIGH);//turn LED ON
} else {
digitalWrite(LED,LOW);
}
}

Thank you in advance

Hey,
I'm having a little bit of confusion reading the code but I don't think that matters that much. Anyways, one thing I can see is under I believe void loop, I think you have digitalRead instead of digitalWrite... Maybe I am just making it up! :slight_smile:

Hey,
Here is an example of what I would put in... (It doesn't matter exactly how you code it though)

(Also, cant remember the pin you were using, but just change the '7' to what pin number you are using)

void setup() {
pinMode(7, OUTPUT)

void loop() {
digitalWrite(7, HIGH)

Just FYI... I didn't try this code so maybe I am missing something. Probably I shouldn't be putting something up that I don't know if works. :confused:
Anyhow, what you can do it wire it differently...
Wiring is:

Wire 'GRD' to '-' on breadboard.
Wire '5V' pin to '+' on breadboard.
Look at Getting Started with the Arduino - Controlling the LED (Part 1) wiring for just LED.
Now, take your button and put it on board.
Wire one side of the switch to '-', and the other side to '+'.

. . . . . . .
. . | . | . .
__ BUT __
TON
. . | . | . .
. . . . . . .
. . , . , . .
. . | . | . .

. . . . .
. . . . . "-"
. . . . . . "+"

/\ /
| |
These are wires

These are just for checking... Basically you need 5V and a GRD wired to breadboard. LED and BUTTON can just needs to be wired to both. Overall, you just need power and it should work.

I tried all of those and nothing
I downloaded the program you suggested and it worked for the momentary switch, but when I modified to get the circuit to stay on when I release the switch it did nothing.

Atleast I know the breadboard and my Arduino board are both good.

Thank you for the link to trouble shooting

Verga

This code doesn't make any sense:

if ((val == HIGH)&&(old_val == LOW))
if ((val ==LOW)&&(old_val == HIGH)){
  state = 1 - state;
  delay(20);
}

If you get a LOW to HIGH transition and pass the first condition then you won't pass the second condition because it is testing for HIGH to LOW transition. If you get a HIGH to LOW transition you will never pass the first condition.

You need to remove one level of condition depending on how your button is wired.

wanjd:
Hey,
Here is an example of what I would put in… (It doesn’t matter exactly how you code it though)

(Also, cant remember the pin you were using, but just change the ‘7’ to what pin number you are using)

void setup() {
pinMode(7, OUTPUT)

void loop() {
digitalWrite(7, HIGH)

Just FYI… I didn’t try this code so maybe I am missing something. Probably I shouldn’t be putting something up that I don’t know if works. :confused:

Why would you configure a button as an output?

ToddL1962:
This code doesn't make any sense:

if ((val == HIGH)&&(old_val == LOW))

if ((val ==LOW)&&(old_val == HIGH)){
  state = 1 - state;
  delay(20);
}




If you get a LOW to HIGH transition and pass the first condition then you won't pass the second condition because it is testing for HIGH to LOW transition. If you get a HIGH to LOW transition you will never pass the first condition.

You need to remove one level of condition depending on how your button is wired.

I literally copied it word for word from page 50 Make: Getting started with Arduino.
There explanation was that if the switch was open (LOW) nothing would happen, but after the switch was closed (HIGH) that the circuit would loop and the LED would stay on.

There are several problems I see here. I see no pullup on the input pin, and I see no debouncing. In addition, as already pointed out, the if-statements make no sense.

I would have done it as

int last_state = 2;

loop()
   {
     int current_state = digitalRead(BUTTON);
     if(current_state != last_state)
        {
          delay(10);
          if(current_state == digitalRead(BUTTON))
             {
               last_state = current_state;
               digitalWrite(LED, last_state == 0 ? LOW : HIGH);
              }
         }
      }

The problem with all switches is that they are mechanical. This means the contacts "bounce". Here's what you think happens:

.......||||||||........|||||||........

In this diagram, the input value of the pin is low (...); the button is pressed and the input goes high (|||||) and the switch is released and it goes low again. But that's not what really happens. What happens is this:

.....................||...|.|..|.|||||||||||.|.|..................

As the switch makes contact, the physical mechanism does not make a solid connection, and you get some ups and downs before it settles in to being high. And when you release it, it may drop to GND and back up to +V a few times before it settles into being GND. It usually settles down in 10ms or so that's why the 10ms delay. You say "But I don't see the light flicker". Yes, our perceptual system is far too sluggish to detect this. But the computer isn't. In a few milliseconds, even the poor 16MHz Arduino AVR chip can read those pins hundreds, maybe even a couple thousand, times. It sees every bounce. Now, if it was supposed to COUNT the number of times is saw the button pressed, it might tell you a much larger number without the debouncing. In one demo I did, a single button press added 23 to the counter, by far the largest amount I ever saw. But a typical button press added 3 to 7 counts.

I do not see a pullup or pulldown in your circuit. A pullup resistor is a large-value resistor which connects the pin to +V. In this configuration, the button connects the input pin to GND. There is a similar mechanism called "pulldown", where a large-value resistor connects the pin to GND, and the button connects the pin to +V. In input, the pin must NEVER be in an "unknown" state, that is, not connected to a known voltage level. If it is not connected, you have no idea what you are going to read. Electrical noise will generate spurious inputs.

For an AVR chip, you should set the mode to INPUT_PULLUP, which connects a 30K-50K ohm resistor from the input pin to +V entirely within the chip, so you don't need an external pullup. Note that in this configuration, when the button is pressed, "pressed" reads as 0 and "released" reads as 1. In the case of the pulldown, pressed reads as 1 and released reads as 0, but for AVR chips, this requires an external resistor, so it is rarely used. Other chips have pulldown resistors as well. But I don't see how the circuit you have described could work. If you set BUTTON to INPUT_PULLUP and not INPUT, and invert the sense of the value, such as by changing the conditional to (last_state == 0 ? HIGH : LOW), it should work.

In my class, I present an SPDT switch, with one point wired to +V, the other to GND, and the center to the input pin. I ask "Will this work?" They usually say "yes" because the pin is always connected to a known voltage. Not true. The correct answer is "no", because there is a period of a huge number of microseconds when neither end is connected. If the pin is ever not connected, solidly, to a known voltage source, you will see behavior that looks like

.........|**|..|......
Where the * symbols indicate random voltages picked up by the unconnected pin. Now, if you wrote code that turned the LED on with one push and turned it off with another, when you pushed the button with no debouncing, you would have no idea what state it would end up in. And if you have no connection to the pin, and no debouncing, the LED would go on and off randomly as each noise transition was reported as a button press

There is a resister that is connected to the GND, it is only 10K I will change it out for the larger one and make the change you suggested in the code.

Thank you

ToddL1962:
Why would you configure a button as an output?

Hey,
I just put this as output if you were wanting to use one of those pins for your voltage or '+'. Really though, it doesn't matter if you have it there or not. As I said earlier, you can just take straight from the GRD and 5V plugs and not work about the input/output...
You probably know more about this than me ToddL1962. If I am making a mistake just Lmk and help me understand it. I would like to get all the help I can! :slight_smile: