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_SSD1306 instance 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_DISPLAY macro and including Wire.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/ and lib/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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →