I2C Connection to PCA9685

Connect the Raspberry Pi Pico to the PCA9685 servo controller via I2C

Step-by-step guide for connecting Raspberry Pi Pico to PCA9685 via I2C communication.

About I2C Communication

I2C (Inter-Integrated Circuit) is a two-wire serial communication protocol that allows the Raspberry Pi Pico to control the PCA9685 servo driver with just 4 connections: power, ground, clock, and data.

Advantages

  • • Only 2 signal wires (SCL, SDA)
  • • Supports multiple devices on same bus
  • • Built-in addressing (up to 127 devices)
  • • Reliable for short distances

Our Configuration

  • • I2C0 bus on Raspberry Pi Pico
  • • PCA9685 at address 0x40 (default)
  • • 100 kHz clock speed (standard mode)
  • • 3-5 retry attempts for reliability

I2C Wiring Connections

4-Wire Connection (Pico ↔ PCA9685)

SignalPico (GPIO / Pin)PCA9685Notes
SCL (Clock)GP1 (Physical Pin 2)SCL pin headerSynchronizes data transfer timing. Do not swap with SDA.
SDA (Data)GP0 (Physical Pin 1)SDA pin headerCarries data between devices. Do not swap with SCL.
VCC (Logic)3V3(OUT) (Pin 36)VCC pin headerPowers PCA9685 logic only (not servos). Pico can supply ~300mA.
GND (Ground)GND (Pin 3, 8, 13, 18, 23, 28, 33, or 38)GND pin headerCommon ground required between Pico, PCA9685 and power supply.

Connection Diagram


    Raspberry Pi Pico 2W              PCA9685 PWM Driver
    ┌──────────────────┐              ┌───────────────────┐
    │                  │              │                   │
    │  Pin 1  (GP0) ───┼──────────────┼───► SDA          │
    │                  │   (Green)    │                   │
    │  Pin 2  (GP1) ───┼──────────────┼───► SCL          │
    │                  │   (Yellow)   │                   │
    │  Pin 36(3V3)  ───┼──────────────┼───► VCC (3.3V)   │
    │                  │   (Red)      │                   │
    │  Pin 38 (GND) ───┼──────────────┼───► GND          │
    │                  │   (Black)    │                   │
    └──────────────────┘              └───────────────────┘

    Color coding (recommended):
    • Green or Blue  → SDA (Data)
    • Yellow or White → SCL (Clock)
    • Red            → VCC (3.3V Power)
    • Black or Brown → GND (Ground)

📷 I2C Wiring Photo Placeholder

Detailed photo showing actual wire connections will be added here

Pull-Up Resistors (Usually Not Needed)

Good News: Pull-Ups Already Included

Most PCA9685 breakout boards include built-in 10kΩ pull-up resistors on SCL and SDA lines. You do not need to add external resistors.

If communication fails, verify the PCA9685 board has pull-up resistors by checking for small resistors near the I2C connector (often labeled R1, R2 or marked "10K").

Testing I2C Connection

Step 1: Visual Inspection

  • ✓ Verify all 4 wires are securely connected
  • ✓ Confirm SCL and SDA are not swapped
  • ✓ Check for any loose connections
  • ✓ Ensure no wire strands are touching adjacent pins

Step 2: Power-On Test

  • 1. Connect Pico to computer via USB (do not connect servo power yet)
  • 2. Look for power LED on PCA9685 board (should light up)
  • 3. If LED doesn't light, check VCC and GND connections

Step 3: I2C Scan Test

Upload and run the Fabrica code. Check the serial console output:

I2C devices found: ['0x40'] Servo controller initialized at 0x40, 50 Hz

Success: If you see 0x40 in the list

Failure: If list is empty or different address appears

💡 Tip: Quick I2C Scan without running Fabrica

Paste this into the MicroPython REPL (Thonny or mpremote) to verify the connection immediately after wiring:

from machine import I2C, Pin

i2c = I2C(0, scl=Pin(1), sda=Pin(0), freq=100000)
devices = i2c.scan()
print("I2C devices found:", [hex(d) for d in devices])
# Expected: I2C devices found: ['0x40']

Troubleshooting I2C Issues

Problem: No I2C devices detected (empty list)

  • • Check SCL and SDA are connected to correct pins (GP1 and GP0)
  • • Verify PCA9685 power LED is on
  • • Try swapping SCL and SDA (common mistake)
  • • Ensure common ground between Pico and PCA9685
  • • Test with shorter I2C wires (<15cm)

Problem: Wrong address detected (not 0x40)

  • • Check if address jumpers on PCA9685 are soldered
  • • Update SERVO_CONTROLLER_ADDR in config.py with detected address
  • • Most boards default to 0x40 with no jumpers bridged

Problem: Intermittent communication errors

  • • Shorten I2C wires (keep under 30cm)
  • • Twist SCL and SDA wires together to reduce interference
  • • Keep I2C wires away from servo power cables
  • • Add 10kΩ pull-up resistors if board doesn't have them
  • • Check for damaged wires or poor contact

Code Configuration

I2C settings are defined in config.py:

# I2C Bus Configuration
I2C_CHANNEL = 0       # I2C bus number (0 or 1 on Pico)
SDA_PIN = 0           # GPIO pin for I2C data (GP0)
SCL_PIN = 1           # GPIO pin for I2C clock (GP1)
I2C_FREQ = 100000     # I2C frequency in Hz (100 kHz standard)
MAX_I2C_RETRIES = 3   # Maximum retries before failure

# PCA9685 Servo Controller Configuration
SERVO_CONTROLLER_ADDR = 0x40  # I2C address (hex)
PWM_FREQ = 50                 # PWM frequency (50 Hz for servos)

Only modify these values if you change address jumpers or need different I2C pins.