OC
OceanRemote
Low-code IoT platform

⚡ ESP32 GPIO Not Working - Complete Fix Guide

⚠️ Symptom: Your ESP32 GPIO pin doesn't respond – it stays HIGH, stays LOW, or doesn't change state when you try to control it.

🔍 Common Causes of GPIO Issues

  • 📌 Input-Only Pins – GPIO 34, 35, 36, 39 are input-only (cannot be used as outputs)
  • 📌 Strapping Pins – GPIO 0, 2, 5, 12, 15 affect boot behavior
  • 📌 Pin Already in Use – Some pins are used by internal functions (flash, PSRAM, etc.)
  • 📌 Incorrect Pin Mode – Using INPUT mode when you need OUTPUT
  • 📌 Floating Pin – No pull-up/pull-down resistor on input pins
  • 📌 Voltage Level Issues – ESP32 is 3.3V, not 5V tolerant on most pins

📊 ESP32 GPIO Pin Reference

Pin TypeGPIO NumbersNotes
Safe for OUTPUT 4, 16, 17, 18, 19, 21, 22, 23, 25, 26, 27, 32, 33 Best choices for beginners
Use with Caution 0, 2, 5, 12, 15 Affects boot; avoid if possible
Input Only 34, 35, 36, 39 Cannot be used as OUTPUT!
ADC1 (Good with WiFi) 32, 33, 34, 35, 36, 37, 38, 39 Use these for analog sensors
ADC2 (WiFi issues) 0, 2, 4, 12, 13, 14, 15, 25, 26, 27 Unreliable when WiFi is active

1️⃣ Check Your Pin Mode Configuration

❌ WRONG - Using input-only pin as output:

pinMode(34, OUTPUT);  // GPIO 34 is INPUT ONLY!
digitalWrite(34, HIGH);  // This will NOT work

✅ CORRECT - Use proper output pins:

pinMode(4, OUTPUT);   // GPIO 4 is safe for output
digitalWrite(4, HIGH);  // This works!

🔧 Test with this simple sketch:

void setup() {
    Serial.begin(115200);
    pinMode(4, OUTPUT);
}

void loop() {
    digitalWrite(4, HIGH);
    Serial.println("Pin 4 HIGH");
    delay(1000);
    digitalWrite(4, LOW);
    Serial.println("Pin 4 LOW");
    delay(1000);
}

2️⃣ Avoid Strapping Pins at Boot

These pins affect how your ESP32 boots. Avoid using them or ensure proper pull-up/down resistors:

PinBoot BehaviorRecommendation
GPIO 0LOW = Download modePull HIGH (10kΩ to 3.3V)
GPIO 2Must be HIGH or floatingAvoid or pull HIGH
GPIO 5LOW = SD card modePull HIGH
GPIO 12LOW = 1.8V flashPull HIGH (critical!)
GPIO 15LOW = boot from SDPull HIGH
💡 Pro Tip: If your ESP32 won't boot or goes into download mode, check what's connected to these pins!

3️⃣ Add Pull-up or Pull-down Resistors

Floating input pins cause random readings. Use internal or external resistors:

Using internal pull-up (software):

pinMode(4, INPUT_PULLUP);  // Enable internal pull-up

Using internal pull-down (ESP32 only):

pinMode(4, INPUT_PULLDOWN);  // Enable internal pull-down

External resistor (more reliable for critical applications):

// Add 10kΩ resistor between GPIO and 3.3V for pull-up
// Add 10kΩ resistor between GPIO and GND for pull-down

4️⃣ Check Voltage Levels - 3.3V vs 5V

⚠️ CRITICAL: ESP32 is NOT 5V tolerant! Applying 5V to most pins can destroy the chip.

Use a level shifter for 5V devices:

// Connect 5V sensor through level shifter:
// 5V Sensor Output → Level Shifter (5V side)
// Level Shifter (3.3V side) → ESP32 GPIO

For analog inputs, use a voltage divider:

// Convert 5V to 3.3V:
// Use 2.2kΩ and 3.3kΩ resistors
// Max voltage: 5V * (3.3 / (2.2 + 3.3)) = 3.0V

5️⃣ Test with Minimal Hardware

Disconnect everything and test with just an LED:

// LED connected between GPIO 4 and GND (with 220Ω resistor)
void setup() {
    pinMode(4, OUTPUT);
}

void loop() {
    digitalWrite(4, HIGH);
    delay(500);
    digitalWrite(4, LOW);
    delay(500);
}

If the LED blinks, your ESP32 is working! Then add components one by one.

📋 Complete ESP32 GPIO Reference

GPIOInputOutputNotes
0Boot mode (LOW = download)
1UART TX (avoid)
2Boot mode, built-in LED
3UART RX (avoid)
4Safe to use
5Boot mode (VSPI CS)
6-11--Connected to flash (do not use)
12Boot mode (must be HIGH)
13ADC2 (WiFi issues)
14ADC2 (WiFi issues)
15Boot mode (must be HIGH)
16Safe to use
17Safe to use
18Safe (SPI SCK)
19Safe (SPI MISO)
21Safe (I2C SDA)
22Safe (I2C SCL)
23Safe (SPI MOSI)
25Safe (DAC)
26Safe (DAC)
27Safe
32Safe (ADC1)
33Safe (ADC1)
34-39INPUT ONLY!

✅ Best Practices for GPIO Pins

  • Use GPIO 4, 16, 17, 18, 19, 21, 22, 23, 25, 26, 27, 32, 33 for reliable operation
  • Avoid GPIO 0, 2, 5, 12, 15 unless you understand boot implications
  • Remember: GPIO 34-39 are input only – never use them as outputs!
  • Add pull-up/pull-down resistors to all input pins
  • Use level shifters for 5V sensors
  • Test each pin with a simple blink sketch before connecting components

❓ Frequently Asked Questions

Q: Why won't my ESP32 boot when I connect something to GPIO 0?

A: GPIO 0 is a strapping pin. When pulled LOW at boot, it puts the ESP32 into download mode. Add a 10kΩ pull-up resistor to keep it HIGH during boot.

Q: Can I use GPIO 1 and 3 for other things?

A: GPIO 1 (TX) and 3 (RX) are used for serial communication. You can use them, but you won't see Serial Monitor output.

Q: Why are my analog readings wrong when WiFi is on?

A: You're probably using ADC2 pins (GPIO 0,2,4,12-15,25-27). Use ADC1 pins (GPIO 32-39) for analog readings when WiFi is active.

Q: Does OceanRemote support custom pin mapping?

A: Yes! OceanRemote's firmware generator lets you configure which GPIO pins to use for relays and sensors. Try it free →

🚀 Need Ready-to-Use Firmware?

OceanRemote generates code with:

  • ✓ Pre-configured GPIO pins
  • ✓ Relay and sensor support
  • ✓ WiFi and cloud connection
  • ✓ No coding required
Generate Firmware →

✅ Quick Checklist