Ok, wiring a button to an Arduino isn't really that hard.. But what if you're low on resistors? What if you only want to run logic once per press? Let's make that stuff simple too!
Why Use Resistors?
If you don't add a resistor to your circuit, you will see a lot of noise and your readings will be all over the place! In the Arduino tutorial linked above they use a 10 K ohm pull down to ground to reduce noise.
I'm not going to go too deep in to Ohm's law, just know the higher the value less power is wasted, but the noise pickup will be greater.
Use A Built-in Pull Up Resistor!
Arduino has built in Pull Up Resistors, you just need to turn them on! There are internal 20K-ohm resistors used to pulled up 5V. But note, this configuration causes the input to read HIGH when the switch is open, and LOW when it is closed.
//setting Pinmode to INPUT_PULLUP, instead of basic INPUT
pinMode(BUTTON_PIN, INPUT_PULLUP);
Sweet, our circuit just got a little simpler!
Handling Button Presses
If you read the button pin in your loop, you'll get a flood of readings when you are pressing it. This can be great if you want to do something while the button is pressed. But what about running only one action per "press"?
I have three buttons wired up, we'll just track if one was pressed, and clear the settings after about two seconds.
#define RED_BTN 10
#define YLW_BTN 11
#define GRN_BTN 12
unsigned long lastRead = 0;
unsigned int readOffset = 1000; //max MS between resets
int lastButtonPressed = 0;
int buttonTimeout = 0;
void setup()
{
Serial.begin(9600);
pinMode(RED_BTN, INPUT_PULLUP);
pinMode(YLW_BTN, INPUT_PULLUP);
pinMode(GRN_BTN, INPUT_PULLUP);
}
void loop()
{
buttonLogic(); //check for a press event every loop
if (millis() - lastRead > readOffset) //run this part every 1000 milliseconds
{
// Record read time
lastRead = millis();
if (--buttonTimeout < 0) {
lastButtonPressed = 0; // reset button press after button timeout is hit
buttonTimeout = 0;
}
}
}
void buttonLogic() {
if (buttonPressed(RED_BTN)) {
Serial.println("Red, Stop!");
}
if (buttonPressed(YLW_BTN)) {
Serial.println("Yellow, hurry up!");
}
if (buttonPressed(GRN_BTN)) {
Serial.println("Green, Go time!");
}
}
const int PRESSED = LOW; // LOW means pressed when using INPUT_PULLUP
bool buttonPressed(int btn) {
//Check if button is being pressed
int state = digitalRead(btn);
if (state == PRESSED) {
// Check if first time pressed or different button
if (lastButtonPressed != btn) {
// Track which button was last pressed, set timeout cycles and return true
lastButtonPressed = btn;
buttonTimeout = 2;
return true;
}
}
// when button is not being pressed,
// or the same button has already been pressed, return false
return false;
}
This logic will only print to serial once per press (or every two seconds if you hold it in).
Looking for more cool stuff? Check out the Pool Bot Series I'm writing
Top comments (1)
Great post