Chapter 4: GPIO Input & Output Basics
Di chapter ini, kita akan belajar menggunakan GPIO sebagai INPUT (membaca button) dan OUTPUT (kontrol multiple LEDs). Mari kita buat traffic light sederhana dengan button!
GPIO sebagai INPUT
Hardware Setup: Push Button
┌─── 3.3V
│
└─── Resistor 10kΩ (Pull-up)
│
ESP32 Pin 5 ────────────┤
│
└─── Push Button ─── GND
Cara Kerja:
- Tidak ditekan: Pin 5 baca HIGH (3.3V dari pull-up resistor)
- Ditekan: Pin 5 baca LOW (0V karena connect ke GND)
Code: Read Button State
#define BUTTON_PIN 5
#define LED_PIN 2
void setup() {
pinMode(BUTTON_PIN, INPUT_PULLUP); // INPUT dengan internal pull-up
pinMode(LED_PIN, OUTPUT);
Serial.begin(115200);
}
void loop() {
int buttonState = digitalRead(BUTTON_PIN);
if (buttonState == LOW) { // Button ditekan
digitalWrite(LED_PIN, HIGH);
Serial.println("Button PRESSED - LED ON");
} else {
digitalWrite(LED_PIN, LOW);
Serial.println("Button RELEASED - LED OFF");
}
delay(100); // Debounce delay
}
Penjelasan:
INPUT_PULLUP:
- ESP32 punya internal pull-up resistor (10-50kΩ)
- Tidak perlu external resistor!
- Pin default HIGH, jadi button press = LOW
digitalRead():
- Membaca state pin (HIGH atau LOW)
- Return value:
HIGH(1) atauLOW(0)
Debouncing:
delay(100)mencegah multiple reads dari satu press- Button mechanical switch bisa “bounce” (flicker)
Button dengan Toggle
Sekarang kita buat button yang toggle (nyalakan/matikan setiap press):
#define BUTTON_PIN 5
#define LED_PIN 2
bool ledState = false;
bool lastButtonState = HIGH;
void setup() {
pinMode(BUTTON_PIN, INPUT_PULLUP);
pinMode(LED_PIN, OUTPUT);
Serial.begin(115200);
}
void loop() {
int buttonState = digitalRead(BUTTON_PIN);
// Detect button press (HIGH → LOW transition)
if (lastButtonState == HIGH && buttonState == LOW) {
ledState = !ledState; // Toggle LED state
digitalWrite(LED_PIN, ledState);
Serial.print("LED toggled: ");
Serial.println(ledState ? "ON" : "OFF");
delay(50); // Debounce
}
lastButtonState = buttonState;
}
Penjelasan:
lastButtonState= State button sebelumnya- Hanya toggle saat transisi HIGH → LOW (button ditekan)
- Mencegah multiple toggle dari satu press
Project: Traffic Light
Sekarang kita buat traffic light sederhana dengan 3 LED (Red, Yellow, Green) dan button untuk start cycle.
Hardware Setup:
Red LED → GPIO 4 ──┬─── LED ─── 220Ω ─── GND
Yellow LED → GPIO 16 ──┤
Green LED → GPIO 17 ──┘
Button → GPIO 5 ─── Button ─── GND
Code:
// Pin definitions
#define RED_LED 4
#define YELLOW_LED 16
#define GREEN_LED 17
#define BUTTON_PIN 5
bool isRunning = false;
void setup() {
pinMode(RED_LED, OUTPUT);
pinMode(YELLOW_LED, OUTPUT);
pinMode(GREEN_LED, OUTPUT);
pinMode(BUTTON_PIN, INPUT_PULLUP);
Serial.begin(115200);
Serial.println("Traffic Light Ready!");
}
void loop() {
// Check button press
if (digitalRead(BUTTON_PIN) == LOW) {
isRunning = !isRunning;
Serial.println(isRunning ? "Traffic Light START" : "Traffic Light STOP");
delay(300); // Debounce
}
if (isRunning) {
trafficLightCycle();
} else {
// Turn off all LEDs
digitalWrite(RED_LED, LOW);
digitalWrite(YELLOW_LED, LOW);
digitalWrite(GREEN_LED, LOW);
}
}
void trafficLightCycle() {
// Red light (Stop)
digitalWrite(RED_LED, HIGH);
digitalWrite(YELLOW_LED, LOW);
digitalWrite(GREEN_LED, LOW);
Serial.println("🔴 RED - STOP");
delay(5000); // 5 seconds
// Yellow light (Ready)
digitalWrite(RED_LED, LOW);
digitalWrite(YELLOW_LED, HIGH);
digitalWrite(GREEN_LED, LOW);
Serial.println("🟡 YELLOW - READY");
delay(2000); // 2 seconds
// Green light (Go)
digitalWrite(RED_LED, LOW);
digitalWrite(YELLOW_LED, LOW);
digitalWrite(GREEN_LED, HIGH);
Serial.println("🟢 GREEN - GO");
delay(5000); // 5 seconds
// Yellow light again before red
digitalWrite(RED_LED, LOW);
digitalWrite(YELLOW_LED, HIGH);
digitalWrite(GREEN_LED, LOW);
Serial.println("🟡 YELLOW - SLOW DOWN");
delay(2000); // 2 seconds
}
Multiple Buttons: LED Controller
Sekarang kita tambahkan 3 buttons untuk kontrol masing-masing LED:
Hardware Setup:
Button 1 → GPIO 5 ─── Button ─── GND (Control Red LED)
Button 2 → GPIO 18 ─── Button ─── GND (Control Yellow LED)
Button 3 → GPIO 19 ─── Button ─── GND (Control Green LED)
Code:
// LED pins
#define RED_LED 4
#define YELLOW_LED 16
#define GREEN_LED 17
// Button pins
#define BUTTON_RED 5
#define BUTTON_YELLOW 18
#define BUTTON_GREEN 19
// LED states
bool redState = false;
bool yellowState = false;
bool greenState = false;
void setup() {
// Set LED pins as output
pinMode(RED_LED, OUTPUT);
pinMode(YELLOW_LED, OUTPUT);
pinMode(GREEN_LED, OUTPUT);
// Set button pins as input with pull-up
pinMode(BUTTON_RED, INPUT_PULLUP);
pinMode(BUTTON_YELLOW, INPUT_PULLUP);
pinMode(BUTTON_GREEN, INPUT_PULLUP);
Serial.begin(115200);
}
void loop() {
// Check Red button
if (digitalRead(BUTTON_RED) == LOW) {
redState = !redState;
digitalWrite(RED_LED, redState);
Serial.println("Red LED: " + String(redState ? "ON" : "OFF"));
delay(300);
}
// Check Yellow button
if (digitalRead(BUTTON_YELLOW) == LOW) {
yellowState = !yellowState;
digitalWrite(YELLOW_LED, yellowState);
Serial.println("Yellow LED: " + String(yellowState ? "ON" : "OFF"));
delay(300);
}
// Check Green button
if (digitalRead(BUTTON_GREEN) == LOW) {
greenState = !greenState;
digitalWrite(GREEN_LED, greenState);
Serial.println("Green LED: " + String(greenState ? "ON" : "OFF"));
delay(300);
}
}
Advanced: Array untuk Multiple GPIOs
Jika punya banyak LED/button, pakai array untuk code lebih clean:
// Array of LED pins
int ledPins[] = {4, 16, 17, 18, 19, 21};
int numLeds = 6;
void setup() {
// Initialize all LED pins
for (int i = 0; i < numLeds; i++) {
pinMode(ledPins[i], OUTPUT);
}
}
void loop() {
// Knight Rider effect
for (int i = 0; i < numLeds; i++) {
digitalWrite(ledPins[i], HIGH);
delay(100);
digitalWrite(ledPins[i], LOW);
}
// Reverse direction
for (int i = numLeds - 1; i >= 0; i--) {
digitalWrite(ledPins[i], HIGH);
delay(100);
digitalWrite(ledPins[i], LOW);
}
}
Tips & Best Practices
1. Pull-up vs Pull-down
// Internal Pull-up (recommended)
pinMode(BUTTON_PIN, INPUT_PULLUP); // Default HIGH, press = LOW
// Internal Pull-down (jika tersedia)
pinMode(BUTTON_PIN, INPUT_PULLDOWN); // Default LOW, press = HIGH
// No pull (butuh external resistor)
pinMode(BUTTON_PIN, INPUT); // Floating, tidak stabil!
2. Debouncing yang Lebih Baik
unsigned long lastDebounceTime = 0;
unsigned long debounceDelay = 50;
void loop() {
int reading = digitalRead(BUTTON_PIN);
if (reading != lastButtonState) {
lastDebounceTime = millis();
}
if ((millis() - lastDebounceTime) > debounceDelay) {
if (reading != buttonState) {
buttonState = reading;
// Do something
}
}
lastButtonState = reading;
}
3. Non-blocking Code
Hindari delay() yang lama:
unsigned long previousMillis = 0;
const long interval = 1000;
void loop() {
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval) {
previousMillis = currentMillis;
// Do something every 1 second
}
// Code lain tetap jalan
}
Troubleshooting
Button Tidak Responsive
- ❌ Lupa
INPUT_PULLUP - ❌ Wiring salah
- ❌ Button rusak
LED Flicker
- ❌ Debounce delay terlalu kecil
- ❌ Power supply tidak stabil
Multiple LED Redup
- ❌ Power tidak cukup dari USB
- ❌ Terlalu banyak LED parallel
Solusi: Pakai external power supply 5V
Challenge Projects! 🎯
Challenge 1: Dice Roll
Buat 6 LED yang menyala random saat button ditekan (simulasi dadu).
Challenge 2: Simon Says Game
Buat game memory dengan 4 LED dan 4 button. LED blink dalam urutan random, user harus ikuti urutannya.
Challenge 3: Password Lock
Buat sistem “password” dengan 4 button. User harus tekan button dalam urutan benar untuk nyalakan LED.
Kesimpulan
Sekarang Anda sudah bisa:
✅ Menggunakan GPIO sebagai INPUT dengan pull-up ✅ Read button state dengan digitalRead() ✅ Membuat toggle button ✅ Kontrol multiple LEDs ✅ Debouncing untuk button stability ✅ Membuat project traffic light ✅ Non-blocking code dengan millis()
Next Steps
Dari sini, Anda bisa explore:
- PWM untuk kontrol brightness/motor speed
- Analog Input untuk read sensor (temperature, light, potentiometer)
- WiFi untuk IoT projects
- Bluetooth untuk wireless control
- I2C/SPI untuk sensor dan display modules
Selamat! Anda sudah menguasai fundamental ESP32! 🎉
Previous: ← Chapter 3 - Program Pertama
Tutorial Selesai! Lanjut explore ESP32 lebih dalam atau cek tutorial lainnya.