How to Set Up ESP32-Bit-Pirate for I²C Communication: Complete Configuration Guide
Enable I²C on ESP32-Bit-Pirate by defining I2C_DISPLAY in your sketch, including the Arduino Wire library, and connecting peripherals to the default SDA (GPIO 21) and SCL (GPIO 22) pins.
The ESP32-Bit-Pirate firmware provides native support for I²C peripherals through the standard Arduino Wire library. This article explains how to configure I²C communication using the repository's built-in examples, with specific reference to the scannerGraphic.ino sketch that demonstrates an Adafruit SSD1306 OLED display over I²C.
Architecture of I²C Support in ESP32-Bit-Pirate
The I²C subsystem in this repository follows a layered architecture that abstracts hardware details while maintaining flexibility for different peripheral types.
Core Components
- Wire library — The foundation I²C driver for ESP32, automatically initialized by peripheral libraries such as Adafruit_SSD1306
- Compile-time peripheral selection — Display type chosen via macros in
scannerGraphic.ino(lines 45-47) - Display driver abstraction —
Adafruit_SSD1306instance receiving a reference to the Wire object (line 123)
Pin Mapping Defaults
The ESP32-Bit-Pirate board routes I²C to Arduino-compatible pins with these default assignments:
| Signal | ESP32 GPIO | Function |
|---|---|---|
| SDA | 21 | Serial data line |
| SCL | 22 | Serial clock line |
No additional pin configuration is required unless you need to remap the I²C bus to alternate GPIOs.
Enabling I²C in Your Sketch
Follow these steps to activate I²C mode in the graphic scanner example or your own code.
Step 1: Select I²C Display Mode
In lib/RF24/examples/scannerGraphic/scannerGraphic.ino, modify lines 45-47:
#define I2C_DISPLAY // Enable this for I²C OLED
// #define SPI_DISPLAY // Comment out SPI mode
Only one display macro may be defined at compile time.
Step 2: Install Required Libraries
Using the Arduino Library Manager or PlatformIO, install:
- Adafruit GFX Library — Base graphics primitives
- Adafruit SSD1306 — OLED display driver
These dependencies are also declared in the repository's platformio.ini.
Step 3: Hardware Connection
Connect your I²C peripheral to the board's header:
- SDA → Pin 21 (or labeled SDA header)
- SCL → Pin 22 (or labeled SCL header)
- VCC → 3.3 V
- GND → Ground
Step 4: Address Configuration
The default OLED address is 0x3D for 128×64 displays. For 128×32 displays, change to 0x3C:
#define SCREEN_ADDRESS 0x3C // For 128×32 OLED variants
I²C OLED Implementation Example
The complete initialization pattern from scannerGraphic.ino demonstrates proper setup:
// Choose I²C display (comment out SPI_DISPLAY)
#define I2C_DISPLAY
#include <Wire.h>
#include <Adafruit_SSD1306.h>
// OLED configuration
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
#define SCREEN_ADDRESS 0x3D // 0x3C for 128×32 displays
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
void setup() {
// Initialize OLED; Wire is started internally by begin()
if (!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
while (true); // Halt initialization on failure
}
display.clearDisplay();
// Continue with radio and scanner setup...
}
Critical detail: The call to display.begin() internally invokes Wire.begin()—no explicit Wire.begin() is required in your setup code when using the Adafruit library.
Direct Wire Library Usage
For non-display I²C peripherals, use the Wire library directly. This pattern applies to the PN532 NFC reader examples in the repository:
#include <Wire.h>
void setup() {
Wire.begin(); // SDA=GPIO21, SCL=GPIO22
Serial.begin(115200);
}
void loop() {
Wire.beginTransmission(0x50); // Target device address
Wire.write(0x00); // Register/sub-address
Wire.endTransmission();
Wire.requestFrom(0x50, 1); // Request 1 byte
if (Wire.available()) {
uint8_t val = Wire.read();
Serial.println(val);
}
delay(1000);
}
This approach is used in lib/PN532/examples/readMifare/readMifare.ino for NFC communication over I²C.
Key Source Files Reference
| File | Purpose |
|---|---|
lib/RF24/examples/scannerGraphic/scannerGraphic.ino |
Primary example showing I²C/SPI display selection |
lib/PN532/examples/readMifare/readMifare.ino |
NFC reader using direct Wire library calls |
platformio.ini |
Global dependencies and build configuration |
lib/Adafruit_SSD1306/ |
OLED driver library (bundled) |
lib/Adafruit_GFX/ |
Graphics primitives library (bundled) |
Troubleshooting ESP32-Bit-Pirate I²C Setup
| Symptom | Cause | Solution |
|---|---|---|
| Display won't initialize | Wrong I²C address | Try 0x3C instead of 0x3D |
| Compilation error "SPI_DISPLAY redefined" | Both macros active | Comment out #define SPI_DISPLAY |
| No signal on SDA/SCL | Wrong pins used | Verify GPIO 21/22 connection |
| Wire.begin() causes crash | Called twice | Remove explicit call when using Adafruit library |
Summary
- ESP32-Bit-Pirate I²C setup requires selecting the
I2C_DISPLAYmacro and includingWire.h - Default pins GPIO 21 (SDA) and GPIO 22 (SCL) need no configuration
- The Adafruit SSD1306 library handles
Wire.begin()internally—do not call it explicitly - Repository examples in
lib/RF24/examples/andlib/PN532/examples/provide working templates - Address 0x3D is standard for 128×64 OLEDs; use 0x3C for 128×32 variants
Frequently Asked Questions
Does ESP32-Bit-Pirate support custom I²C pin remapping?
Yes. While the default SDA/SCL pins are GPIO 21 and 22, you can specify alternate pins by calling Wire.begin(uint8_t sda, uint8_t scl) before initializing your peripheral. This overrides the default mapping without modifying the board's physical headers.
Why does my OLED show nothing even with correct wiring?
The most common cause is an incorrect I²C address. Many 128×64 OLED modules ship configured for 0x3C rather than 0x3D. Scan the I²C bus with a simple sketch to detect the actual address, or try both values in SCREEN_ADDRESS.
Can I use both I²C and SPI peripherals simultaneously?
Yes, but not for the display subsystem in the scanner example—the compile-time macros enforce mutual exclusion between I2C_DISPLAY and SPI_DISPLAY. For other combinations (I²C OLED + SPI radio), modify the sketch to remove the #ifndef guard that prevents both defines.
Is the Wire library included in the ESP32-Bit-Pirate firmware?
The Wire library is part of the ESP32 Arduino core, not bundled separately in this repository. The platformio.ini configuration ensures it's available during compilation. The repository includes wrapper examples demonstrating proper integration patterns.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →