I did a dead simple arduino + coding challenge which entails setting up 2 LED's and 2 corresponding buttons then code it to have the button turn the corresponding led on or off with each click. I noticed when I would click the button it would often do the correct action but the go through the loop again and change it back so I added a while loop to just hold the process until the button is released. Works pretty good but is there a better approach? I bet so. I could see other issues arising from holding the process completely. Also what Im more interested in is what would be the simplest way to make it work if you press both buttons at the same time?
// DEFINE ALL PINS
const int BUTTON_GREEN_PIN = 5;
const int BUTTON_RED_PIN = 6;
const int LED_GREEN_PIN = 7;
const int LED_RED_PIN = 8;
// DEFINE HIGH/LOW STATE VARIABLES
bool BUTTON_GREEN_STATE = LOW;
bool LED_GREEN_STATE = LOW;
bool BUTTON_RED_STATE = LOW;
bool LED_RED_STATE = LOW;
void setup() {
pinMode(BUTTON_GREEN_PIN, INPUT);
pinMode(LED_GREEN_PIN, OUTPUT);
pinMode(BUTTON_RED_PIN, INPUT);
pinMode(LED_RED_PIN, OUTPUT);
}
void loop() {
if(digitalRead(BUTTON_GREEN_PIN)){ // CHECK IF GREEN BUTTON IS PRESSED
LED_GREEN_STATE = !LED_GREEN_STATE; // REVERSE THE CURRENT STATE OF THE LED VARIABLE
digitalWrite(LED_GREEN_PIN, LED_GREEN_STATE); // UPDATE THE LED STATUS ELECTRONICALLY
while(digitalRead(BUTTON_GREEN_PIN)){} // HOLD OPEN LOOP WHILE THE BUTTON IS PRESSED TO AVOID LOOP-REPEAT
}
if(digitalRead(BUTTON_RED_PIN)){ // CHECK IF RED BUTTON IS PRESSED
LED_RED_STATE = !LED_RED_STATE; // REVERSE THE CURRENT STATE OF THE LED VARIABLE
digitalWrite(LED_RED_PIN, LED_RED_STATE); // UPDATE THE LED STATUS ELECTRONICALLY
while(digitalRead(BUTTON_RED_PIN)){} // HOLD OPEN LOOP WHILE THE BUTTON IS PRESSED TO AVOID LOOP-REPEAT
}
}
Not necessarily. Each LED/button pair can have its own state variable, which will need to have only 2 states/values. There may be no need to combine all 4 LEDs and buttons into a single, more complex state machine with 4 states, because
How have you got your buttons wired?
I looks like your buttons pull the input HIGH.
Do you have a pull down resistor, such as 10K, connected from the input to gnd to pull the input LOW when the button is open?
Can you please post a copy of your circuit, a picture of a hand drawn circuit in jpg, png?
Hand drawn and photographed is perfectly acceptable.
Please include ALL hardware, power supplies, component names and pin labels.
Forgive me if I'm missing something but I wrote this code without any "debounce delays" and it works perfectly now just based on this principal alone.
// CHECK IF BUTTON IS PRESSED THEN UPDATE BUTTON STATE
if (digitalRead(BUTTON_PIN)){
if (BUTTON_STATE == BUTTON_PREV_STATE) {BUTTON_STATE = !BUTTON_STATE;}
}
else {BUTTON_PREV_STATE = BUTTON_STATE;}
I understand the concept of button bounce but the main issues that I was having was the program looping and setting it back before I ever released the button. It seams to me as though these tiny little buttons that come with arduino kits are really optimized to minimize any button bounce. Anyway ya. The code I have now is working perfect no matter the duration I hold or tap the button. I can press both at the same time that works great. And its also controlled by a photo resistor Ill paste the whole thing here.
// DEFINE PINS-DEVICES
// green LED and associated components
const int LED_GREEN_PIN = 8;
bool LED_GREEN_STATE = LOW;
const int BUTTON_GREEN_PIN = 5;
bool BUTTON_GREEN_STATE = LOW;
bool BUTTON_GREEN_PREV_STATE = LOW;
const int PHOTOR_GREEN_PIN = A1;
int PHOTOR_GREEN_VALUE = 0;
// red LED and associated components
const int LED_RED_PIN = 9;
bool LED_RED_STATE = LOW;
const int BUTTON_RED_PIN = 6;
bool BUTTON_RED_STATE = LOW;
bool BUTTON_RED_PREV_STATE = LOW;
const int PHOTOR_RED_PIN = A0;
int PHOTOR_RED_VALUE = 0;
const int PHOTOR_LIGHT_THRESHOLD = 500; // photoresistor light value at which LED is triggered on
void setup() {
Serial.begin(9600);
pinMode(LED_GREEN_PIN, OUTPUT);
pinMode(BUTTON_GREEN_PIN, INPUT);
pinMode(LED_RED_PIN, OUTPUT);
pinMode(BUTTON_RED_PIN, INPUT);
}
void loop() {
// CHECK IF BUTTON IS PRESSED THEN UPDATE BUTTON STATE
if (digitalRead(BUTTON_GREEN_PIN)){
if (BUTTON_GREEN_STATE == BUTTON_GREEN_PREV_STATE) {BUTTON_GREEN_STATE = !BUTTON_GREEN_STATE;}
}
else {BUTTON_GREEN_PREV_STATE = BUTTON_GREEN_STATE;}
if (digitalRead(BUTTON_RED_PIN)){
if(BUTTON_RED_STATE == BUTTON_RED_PREV_STATE) {BUTTON_RED_STATE = !BUTTON_RED_STATE;}
}
else {BUTTON_RED_PREV_STATE = BUTTON_RED_STATE;}
// CHECK PHOTO-RESISTOR VALUES AND UPDATE VALUE
PHOTOR_GREEN_VALUE = analogRead(PHOTOR_GREEN_PIN);
PHOTOR_RED_VALUE = analogRead(PHOTOR_RED_PIN);
// UPDATE LED STATUS BASED ON BUTTON STATUS AND/OR PHOTO-RESISTOR SENSOR LEVEL
if (BUTTON_GREEN_STATE | PHOTOR_GREEN_VALUE < 500) {
LED_GREEN_STATE = HIGH;
} else {
LED_GREEN_STATE = LOW;
}
if (BUTTON_RED_STATE | PHOTOR_RED_VALUE < 500) {
LED_RED_STATE = HIGH;
} else {
LED_RED_STATE = LOW;
}
// DIRECT PROPER SIGNAL TO LED'S
digitalWrite(LED_GREEN_PIN, LED_GREEN_STATE);
digitalWrite(LED_RED_PIN, LED_RED_STATE);
}
My apologies. There definitely are times where I absolutely have it in me to solve the problems if I just think about it a little longer. However I just love getting advice from smart people in forums because even if I can figure it out on my own, surely most of the time there is a better way. Its from forums like this that I always learn cool little tricks . And like you mentioned I'm sure there's a faster, less memory intensive solution. That was one thing I was thinking when I wrote it is yes it seams to work perfect but its a lot of variables and if statements
I'm far from being a C++ expert but 4 variables, 2 ifs and 2 whiles doesn't seem lik a lot.
I would also be curiousto see if someone here could do better.
Im confused by why so many people do INPUT PULLUP. The purpose of that is just to invert the normal state right? Like if its a normally open momentary button, the input pullup would basically reverse that and make it act like a normally closed momentary button right? And if so how is that done? With an internal built in resistor something like that? And as for the added resistor. Your saying you can put on a resistor and it will act as a pull down? I do have a 10k resistor going from 1 leg of the button to the negative rail on the BB. I thought that was just to keep from burning things out like an LED requires one
Until I came to the Arduino forum, I never heard of using a Pull-down resistor for a button input. In my opinion it's bad practice and should never be used since it requires connecting a voltage source directly to a I/O pin.
Why is that bad? Well, in your haste to finish your code you accidentally swapped a few pin numbers and now your button pin is connected to an output and you set it low. Poof, end of Arduino.
This can never happen with a pull-up. Plus as @UKHeliBob said, it saves a resistor in many cases. When microcontroller manufacturer's started including them it was touted as a big selling feature.