OC
OceanRemote
Low-code IoT platform
← Back to Course

Digital Input: Buttons and Switches

Digital Input: Buttons and Switches

🔘 Digital Input: Reading Buttons and Switches with ESP8266

🔘 What You'll Learn:

  • 🔌 Wire a button to ESP8266 using internal pull-up (no external resistor)
  • 💻 Read button presses with debounce to prevent false triggers
  • 💧 Use button for manual irrigation override
  • 🚨 Emergency stop button for pump safety

🔌 Button Wiring

Button Wiring (using internal pull-up):

    ESP8266 (NodeMCU)           Button
    ══════════════════           ══════
    GPIO0 (D3) ───────────────── Button Pin 1
    GND       ───────────────── Button Pin 2
    
    ⚠️ No external resistor needed - using INPUT_PULLUP!
    
    Button NOT pressed → GPIO reads HIGH (1)
    Button pressed     → GPIO reads LOW (0)
    
    ⚠️ GPIO0 is boot mode pin! Button may affect boot. 
    Use GPIO4 (D2), GPIO5 (D1), or GPIO14 (D5) for buttons instead.
    
💡 Recommended Pins for Buttons:
  • GPIO0 (D3): Works but affects boot (hold LOW during boot = flashing mode)
  • GPIO4 (D2), GPIO5 (D1), GPIO14 (D5): Safe choices, no boot issues
  • GPIO16 (D0): Only digital input, no pull-up (needs external resistor)

📖 Complete Button Code with Debouncing

#define BUTTON_PIN 4   // GPIO4 (D2)

bool lastState = HIGH;
unsigned long lastDebounce = 0;
const unsigned long DEBOUNCE_DELAY = 50;
int pressCount = 0;

void setup() {
    Serial.begin(115200);
    pinMode(BUTTON_PIN, INPUT_PULLUP);
    Serial.println("🔘 Button Monitor Ready - Press to test");
}

void loop() {
    bool reading = digitalRead(BUTTON_PIN);
    
    // Debounce logic
    if (reading != lastState) {
        lastDebounce = millis();
    }
    
    if ((millis() - lastDebounce) > DEBOUNCE_DELAY) {
        if (reading == LOW) {
            pressCount++;
            Serial.printf("✅ Button PRESSED! (Count: %d)\n", pressCount);
            // Add your action here
        }
    }
    lastState = reading;
}
    

💧 Farm Application: Manual Irrigation Override

#define BUTTON_PIN 4      // Manual override button
#define PUMP_RELAY 5      // Relay controls pump

bool lastState = HIGH;
unsigned long lastDebounce = 0;
unsigned long pumpStart = 0;
bool pumpRunning = false;
const int WATER_DURATION = 15;  // seconds

void setup() {
    pinMode(BUTTON_PIN, INPUT_PULLUP);
    pinMode(PUMP_RELAY, OUTPUT);
    digitalWrite(PUMP_RELAY, HIGH);  // Pump OFF
    
    Serial.begin(115200);
    Serial.println("💧 Manual pump control ready");
}

void waterPump(int seconds) {
    Serial.printf("💧 Pump ON for %d seconds\n", seconds);
    digitalWrite(PUMP_RELAY, LOW);   // Pump ON
    pumpRunning = true;
    pumpStart = millis();
    
    while (millis() - pumpStart < seconds * 1000) {
        // Check emergency stop during watering
        if (digitalRead(BUTTON_PIN) == LOW) {
            Serial.println("🛑 Emergency stop!");
            break;
        }
        delay(50);
    }
    
    digitalWrite(PUMP_RELAY, HIGH);  // Pump OFF
    pumpRunning = false;
    Serial.println("✅ Pump OFF");
}

void loop() {
    bool reading = digitalRead(BUTTON_PIN);
    
    if (reading != lastState) {
        lastDebounce = millis();
    }
    
    if ((millis() - lastDebounce) > 50) {
        if (reading == LOW && !pumpRunning) {
            Serial.println("🔘 Manual override triggered!");
            waterPump(WATER_DURATION);
        }
    }
    lastState = reading;
    
    delay(10);
}
    
📖 Farm Application:

A farmer installed a manual override button next to their automated irrigation controller. When they spotted a dry area, pressing the button watered that zone for 15 seconds without changing the automated schedule.

💡 Debounce Explained:
  • Mechanical buttons "bounce" for 5-20ms after press
  • Without debounce, one press looks like 10-100 presses
  • Solution: Wait 50ms after first change before accepting button state
  • Result: One press = one action
🎯 Key Takeaways:
  • ✅ Use INPUT_PULLUP for internal resistor (no external parts)
  • ✅ Button pressed = LOW (0V), released = HIGH (3.3V)
  • ✅ Always debounce (50-100ms delay) to prevent false triggers
  • ✅ Safe GPIO for buttons: GPIO4, GPIO5, GPIO14
  • ✅ Manual override lets operators intervene when needed
💡 Key Takeaways:
  • Apply these concepts directly to your farm or project.
  • Take notes on important details for the quiz.
  • Use the button below to track your progress.