The Adafruit Feather ecosystem standardizes microcontroller development, but the underlying silicon changes. If you are migrating from the classic HUZZAH32 to the modern ESP32-S3 Feather, assuming the GPIO mappings are identical will brick your I2C bus or trap your board in a boot loop. Below is the definitive hardware map for the current-generation ESP32-S3 Feather alongside the legacy HUZZAH32.
The Complete ESP32 Feather Pinout Reference
This table maps the physical silk screen labels on the Feather header to the internal Espressif GPIO numbers. Always reference the 'S3 GPIO' column for boards purchased in 2025 or later.
| Feather Silk Label | ESP32-S3 GPIO | Classic HUZZAH32 GPIO | Function & Hardware Notes |
|---|---|---|---|
| RST | CHIP_EN (EN) | CHIP_EN (EN) | Active low reset. Internally pulled up. Tie to GND via 10kΩ for manual reset switches. |
| 3V3 | N/A (Power) | N/A (Power) | Output from the onboard LDO. Max continuous draw: 600mA (S3) / 500mA (HUZZAH32). |
| VUSB / VBUS | N/A (Power) | N/A (Power) | Raw USB 5V. Bypasses the LDO. Use for 5V sensor power, not logic. |
| GND | N/A (Ground) | N/A (Ground) | Common ground. Tied to the USB Type-C shield and mounting holes. |
| A0 | GPIO 4 | GPIO 26 | ADC1 channel. Safe to use with WiFi active. 12-bit resolution (0-4095). |
| A1 | GPIO 5 | GPIO 25 | ADC1 channel. Safe to use with WiFi active. |
| A2 / SDA | GPIO 3 (SDA) | GPIO 23 (SDA) | Warning: S3 uses GPIO 3 for default Wire library I2C. Classic uses GPIO 23. |
| A3 / SCL | GPIO 4 (SCL) | GPIO 22 (SCL) | Warning: S3 uses GPIO 4 for default I2C. Classic uses GPIO 22. Do not cross-wire. |
| A4 | GPIO 6 | GPIO 34 | Classic GPIO 34 is input only. S3 GPIO 6 is bidirectional. |
| A5 | GPIO 7 | GPIO 35 | Classic GPIO 35 is input only. S3 GPIO 7 is bidirectional. |
| SCK | GPIO 36 | GPIO 5 | SPI Clock. Shared with the onboard QSPI flash on some variants; verify schematic. |
| MOSI | GPIO 35 | GPIO 18 | SPI Master Out Slave In. |
| MISO | GPIO 37 | GPIO 19 | SPI Master In Slave Out. |
| RX | GPIO 38 | GPIO 16 | Default Hardware UART0 RX. Connected to USB-to-Serial bridge. |
| TX | GPIO 39 | GPIO 17 | Default Hardware UART0 TX. Connected to USB-to-Serial bridge. |
| NEOPIXEL | GPIO 33 | N/A | Onboard WS2812B. Requires `pinMode(NEOPIXEL_POWER, OUTPUT); digitalWrite(HIGH);` to enable. |
Rows People Get Wrong (And How to Fix Them)
When bench-testing these boards, three specific pinout assumptions cause 90% of integration failures.
1. The I2C Bus Swap
On the original HUZZAH32, the default I2C pins (SDA/SCL) were GPIO 23 and 22. On the ESP32-S3 Feather, Adafruit remapped these to GPIO 3 and GPIO 4 to optimize PCB routing. If you hardcode Wire.begin(23, 22) on an S3 board, your BME280 or OLED will silently fail to initialize. Always use Wire.begin(SDA, SCL) and let the Adafruit board definition resolve the correct pins via the variant.h file.
2. The Strapping Pin Boot Trap
The ESP32-S3 uses specific GPIOs (0, 3, 45, 46) as 'strapping pins' to determine boot mode. GPIO 0 on the S3 Feather is routed to the boot button. If you wire a sensor that pulls GPIO 0 LOW during power-up, the chip will enter the serial bootloader and your application code will never run. Fix: Never use strapping pins for continuous sensor inputs unless you add a 10kΩ pull-up resistor to 3V3 to ensure it defaults HIGH at boot.
3. Input-Only ADC Confusion
If you are porting legacy code from the classic HUZZAH32, you might rely on GPIO 34, 35, 36, or 39 for analog readings. On the original ESP32, these are strictly input-only (no internal pull-ups, no output capability). The S3 eliminates this restriction on its mapped A4/A5 pins, but if you are using a raw ESP32-WROOM-32 breakout masquerading as a Feather, attempting to digitalWrite() to GPIO 34 will do nothing.
Sensor Wiring Color Codes: IEC vs NEC vs Legacy Standards
A pinout reference is only half the battle; interpreting the wire colors on the sensors you plug into those pins is where regional standards collide. When wiring bare-lead sensors (like PT100 RTDs or raw load cells) to your Feather's terminal blocks, you must know which standard the sensor manufacturer followed.
| Standard / Region | DC Positive (+) | DC Negative (-) | Signal / Data | Protective Earth |
|---|---|---|---|---|
| IEC 60446 (EU / UK / Industrial) | Brown | Blue | Black or White | Green/Yellow Stripe |
| NEC 70 (US / Canada DC Power) | Red (or Brown) | Black (or Blue) | White (or Yellow) | Green (or Bare) |
| Maker / Hobbyist (Adafruit, SparkFun) | Red | Black | Yellow, White, or Blue | N/A (Rarely used) |
| Legacy 4-20mA (Industrial) | Red | Black | White | Green/Shield |
Which standard applies to you? If you are buying sensors from AliExpress or generic Amazon vendors, they almost universally use the Maker/Hobbyist standard (Red/Black/Yellow). If you are integrating industrial M12 pigtail sensors from Omron or Sick, they strictly follow IEC 60446 (Brown/Blue/Black). Splicing an IEC Brown wire into a Feather VBUS (5V) expecting it to be a signal line will instantly fry the ESP32's 3.3V LDO.
Safe Interpretation When Silk Screen Markings Fade
Feather boards used in high-humidity environments or subjected to repeated header mating will lose their white silk screen text. If you cannot read the pin labels, do not guess. Use this bench procedure to safely map the board:
- Establish Ground Truth: Set your multimeter to continuity mode. Probe the metal shield of the USB Type-C connector. This is tied directly to GND. Map all header pins that beep to this shield—these are your GND pins.
- Locate 3V3: Power the board via USB. Set your DMM to DC Voltage. Probe the known GND pins with your black lead. Sweep the red lead across the remaining pins. The pin reading a stable 3.28V–3.32V is your 3V3 rail.
- Locate VUSB: Using the same DMM setup, find the pin reading 4.8V–5.2V. This is VBUS.
- Identify I2C via Pull-ups: With the board unpowered, set your DMM to resistance (Ω). Measure between your known 3V3 pin and the remaining data pins. The two pins that read approximately 4.7kΩ to 10kΩ (due to internal or external I2C pull-up resistors) are your SDA and SCL lines.
- Verify with the Schematic: Cross-reference your findings with the official Adafruit Eagle schematics to confirm the exact GPIO mapping for your specific board revision.
ESP32 Feather Pinout FAQ
Can I use 5V logic sensors directly with the ESP32 Feather GPIOs?
No. The ESP32-S3 and classic HUZZAH32 are strictly 3.3V logic devices. While the VBUS pin outputs 5V to power external modules, feeding a 5V digital signal back into any GPIO (like RX, SDA, or A0) will degrade the silicon over time or cause immediate latch-up. Use a bidirectional logic level converter (like the BSS138-based Adafruit 4-channel converter) between the 5V sensor TX and the ESP32 RX pin.
Why does my ESP32 Feather fail to enter download mode when a sensor is connected to GPIO 0?
GPIO 0 is a strapping pin that dictates boot mode. During firmware upload, the Arduino IDE or PlatformIO needs GPIO 0 pulled LOW while the EN (Reset) pin is toggled. If your external sensor is actively driving GPIO 0 HIGH (e.g., a push-button wired to VCC, or an active-high digital sensor), it overrides the USB-to-serial bridge's attempt to pull it LOW. Disconnect the sensor from GPIO 0 during flashing, or redesign the circuit to include a 10kΩ pull-up and a manual boot button.
What is the maximum continuous current I can draw from the Feather 3V3 pin?
On the modern ESP32-S3 Feather, the onboard AP2112 LDO regulator is rated for 600mA continuous, provided you have adequate airflow and an ambient temperature below 40°C. On the older HUZZAH32, the ME6211 LDO is limited to roughly 500mA. However, the ESP32 itself draws up to 250mA during peak WiFi transmission bursts. Therefore, your external 3.3V sensor load should not exceed 300mA on the S3, or 200mA on the classic HUZZAH32, to prevent brownout resets.
How do I map the Feather RX/TX pins to hardware UART1 or UART2?
The physical pins labeled 'RX' and 'TX' on the Feather header are hardwired to UART0, which is shared with the onboard USB-to-Serial chip for programming and debugging. If you need to connect an external GPS or cellular modem, do not use these pins. Instead, utilize the ESP32's GPIO matrix to route UART1 or UART2 to any available digital pins (e.g., A0 and A1). In the Arduino IDE, initialize this with Serial1.begin(9600, SERIAL_8N1, RX_PIN, TX_PIN); using your chosen GPIOs. Consult the Espressif ESP32-S3 Datasheet to ensure your chosen pins are not reserved for the SPIRAM or Octal Flash interfaces.






