// Connect some buttons per
// https://forum.arduino.cc/t/how-to-wire-and-program-a-button/1196000/2?u=davex
// https://forum.arduino.cc/t/share-tips-you-have-come-across/428745/999
// and https://forum.arduino.cc/t/wiring-a-button-pull-down-bad-vs-input-pullup-best/116298566
//
// Also demos blocking and non-blocking button reading and blinking
const byte S1Pin = 10; // external pull down Normally Open button
const byte S2Pin = 5; // external pull up Normally Open button
const byte S3Pin = 3; // Internal pullup Normally Open Button
const byte D1Pin = 8; // active low LED
const byte D2Pin = 7; // active high LED
const uint32_t interval = 1000;
void setup() {
Serial.begin(115200);
pinMode(S1Pin, INPUT); // rely on extrernal pull-down
pinMode(S2Pin, INPUT); // rely on extrernal pull-UP
pinMode(S3Pin, INPUT_PULLUP); // us internal pullup resistor
// Active LOW LED:
digitalWrite(D1Pin, HIGH); // turn off before setting as output
pinMode(D1Pin, OUTPUT); // Active LOW led
//digitalWrite(D1Pin,LOW); // turn on
// Active HIGH LED
pinMode(D2Pin, OUTPUT); // Active HIGH led
digitalWrite(D2Pin, LOW); // turn off
//digitalWrite(D2Pin,HIGH); // turn on
}
void loop() {
switch ( 1 ) { // Choose from scheme 1,2, or 3
case 1: blockingLoop(); break;// read the buttons and blink the lights using delay
case 2: nonBlockingLoop(); break; // poll the button and blink without delay
case 3: nonBlockingEdgeDetectionLoop(); break; // read the buttons changes and blink the lights cooperatively
}
}
void blockingLoop(void) {
int S1Active = digitalRead(S1Pin) == HIGH; // External oulldown is active HIGH
int S2Active = digitalRead(S2Pin) == LOW; // Exrernal pullup is active LOW
int S3Active = digitalRead(S3Pin) == LOW; // Internal pullup is active LOW
Serial.print( digitalRead(S1Pin) == LOW ? "S1=Open" : "S1 Closed");
Serial.print(' ');
Serial.print( digitalRead(S2Pin) == HIGH ? "S2=Open" : "S2=Closed");
Serial.print(' ');
Serial.println( S3Active ? "S3=Closed" : "S3=Open");
if (S1Active || S2Active || S3Active ) {
digitalWrite(D1Pin, digitalRead(D1Pin) == HIGH ? LOW : HIGH);
digitalWrite(D2Pin, digitalRead(D2Pin) == HIGH ? LOW : HIGH);
}
delay(interval); // pause for polling/blinking
}
void nonBlockingLoop(void) {
static uint32_t lastPoll = 0;
if (millis() - lastPoll > interval) {
lastPoll = millis();
int S1Active = digitalRead(S1Pin) == HIGH; // External oulldown is active HIGH
int S2Active = digitalRead(S2Pin) == LOW; // Exrernal pullup is active LOW
int S3Active = digitalRead(S3Pin) == LOW; // Internal pullup is active LOW
Serial.print( digitalRead(S1Pin) == LOW ? "S1=Open" : "S1 Closed");
Serial.print(' ');
Serial.print( digitalRead(S2Pin) == HIGH ? "S2=Open" : "S2=Closed");
Serial.print(' ');
Serial.println( S3Active ? "S3=Closed" : "S3=Open");
if (S1Active || S2Active || S3Active ) {
digitalWrite(D1Pin, digitalRead(D1Pin) == HIGH ? LOW : HIGH);
digitalWrite(D2Pin, digitalRead(D2Pin) == HIGH ? LOW : HIGH);
}
}
}
void nonBlockingEdgeDetectionLoop(void) {
const byte numSwitches = 3;
const uint8_t switchPins[] = {S1Pin, S2Pin, S3Pin};
const uint8_t InactiveLevels[] = {LOW, HIGH, HIGH};
const char *names [] = {"S1", "S2", "S3"};
const int debounceMs = 20;
static uint32_t changeTimes[numSwitches];
static int lastState[numSwitches]; // memory for edge detection
static uint32_t lastBlinkTime = 0;
uint32_t currentTime = millis();
for (int sw = 0 ; sw < numSwitches ; ++ sw) {
int currentState = digitalRead(switchPins[sw]);
// check for button state-changes
if (currentState != lastState[sw] && currentTime - changeTimes[sw] > debounceMs) {
lastState[sw] = currentState ;
changeTimes[sw] = currentTime;
Serial.print(names[sw]);
Serial.print(":");
Serial.print(currentState == InactiveLevels[sw] ? "Open" : "Closed");
Serial.println(".");
}
}
// Blink the LEDs while any button is active
// test all switches
bool anyActive = false;
for (int sw = 0; sw < numSwitches ; ++sw) {
if (lastState[sw] != InactiveLevels[sw]) {
anyActive = true;
}
}
if (anyActive && currentTime - lastBlinkTime > interval) {
lastBlinkTime = currentTime;
digitalWrite(D1Pin, digitalRead(D1Pin) == HIGH ? LOW : HIGH);
digitalWrite(D2Pin, digitalRead(D2Pin) == HIGH ? LOW : HIGH);
}
}
D1
Active LOW
D2
Active HIGH
SW1
See NOTE
SW2
SW3
R4
10K
External
pull-DOWN
R1
10K
External
Pull-up
R2
220R
R3
220R
Typical switch wiring and simple LED Connection
Best S3 -- Internal Pull Up -- pinMode(3,INPUT_PULLUP) -- Goes LOW on push
Good S2 -- External Pull Up -- pinMode(5,INPUT_PULLUP) -- Goes LOW on push
Bad S1 -- External Pull Down -- pinMode(10,INPUT_PULLUP) -- Goes HIGH on push
https://forum.arduino.cc/t/share-tips-you-have-come-across/428745/999
NOTE: SW1 & R4 circuit is not recommended as there is a possibility of shorting +5 to ground