🛠 Afficher sur un OLED I2C SSD1306 et déboguer le bus
Objectives
Set up a standalone display on your RP2040 board: the RP2040's I2C (2 controllers, mappable to any GPIO — datasheet) driven by MicroPython, using the classic OLED SSD1306 128×64 module. You will mainly learn how to scan an I2C bus — the skill that saves you when you don't know if the module is dead, miswired, or at address 0x3C or 0x3D.
Hardware
- 1 × generic RP2040 board (free pins, here GP4/GP5)
- 1 × SSD1306 OLED module with 4 pins (VCC, GND, SCL, SDA), powered at 3V3
- Wiring: VCC→3V3, GND→GND, SDA→GP4, SCL→GP5; SSD1306 modules already have their pull-up resistors (2.2–4.7 kΩ) — do not add more
- MicroPython rp2 firmware + the
ssd1306.pydriver (official micropython-lib library, to be copied to the board using Thonny)
Complete Code
# scan_i2c.py — d'abord, trouver le module
from machine import I2C, Pin
i2c = I2C(0, sda=Pin(4), scl=Pin(5), freq=400000)
print('adresses vues:', i2c.scan) # attendu: [60] soit 0x3C
# oled_demo.py — afficher température interne + texte
import ssd1306, time
from machine import Temp
oled = ssd1306.I2C(128, 64, device=i2c) # adresse 0x3C détectée
try:
temp = Temp # capteur interne (MicroPython >= 1.22)
except NameError:
from machine import ADC
_a = ADC(4) # fallback : canal ADC4 interne
def read_T:
mv = _a.read_u16 * 3.3 / 65535
return 27.0 - (mv - 0.706) / 0.001721
else:
def read_T:
return temp.temperature
oled.text('RP2040 generique', 0, 0, 1)
oled.text('I2C 400 kHz OK', 0, 10, 1)
while True:
oled.text('T: %6.2f C' % read_T, 0, 30, 1)
oled.show
time.sleep_ms(500)
Expected Verification
i2c.scan returns [60] (0x3C in decimal — the other possible address for the SSD1306 is 0x3D, set by a jumper on the module). The screen displays text lines and the temperature of the RP2040's internal sensor, which rises when you touch the chip. Disconnect SDA: scan returns [] — the bus is alive, and so is the driver.
Common Errors
- Empty
scan: SDA/SCL swapped (most frequent), module not properly powered, or wrong I2C controller number (I2C(1, ...)with different pins). - Bus stuck at 0: a slave "stuck" after a reset; 9 clock pulses release the bus — rewiring or
machine.resetis often enough. - Screen on but completely black: forgot
oled.show— the SSD1306 has its own RAM, nothing displays without a transfer. - Confusing drivers: there are
SSD1306_128_64andSSD1306_128_32— a 32-line module with the 64-line driver displays ghost lines. - Pulling the line to ground with a pinched cable: I2C remains "busy" and the scan fails for all devices.
- Frequency too high on long cables: switch to
freq=100000before investigating further.
Other tutorials for this board
- Piloter la LED RGB embarquée WS2812 d'une carte RP2040 générique
- Avoir une console série sur une carte sans pont USB (UART0)
- Jouer une mélodie avec un buzzer passif et le PWM
- Logger sur carte microSD en SPI (mode carte)
- Interruptions GPIO et alarmes matérielles avec le Pico SDK
- Transformer la carte en clavier USB HID avec TinyUSB
Code examples for this board
clignotante.pyPythonbouton-interruption.pyPythonpwm-servo.pyPythonlecture-adc.pyPythonneopixel.pyPythonoled-i2c.pyPython