Fix MicroPython “OSError: [Errno 19] ENODEV” on I2C
No device answered at the I2C address you used. Scan the bus, check SDA/SCL pins match the I2C(…) call, and confirm the address.
Community draft — report a mistake
What you see
>>> from machine import Pin, I2C
>>> i2c = I2C(0, sda=Pin(4), scl=Pin(5))
>>> i2c.scan()
[]
>>> i2c.writeto(0x3c, b'\x00')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
OSError: [Errno 19] ENODEV>>> from machine import Pin, I2C >>> i2c = I2C(0, sda=Pin(4), scl=Pin(5)) >>> i2c.scan() [] >>> i2c.writeto(0x3c, b'\x00') Traceback (most recent call last): File "<stdin>", line 1, in <module> OSError: [Errno 19] ENODEV
ENODEV is MicroPython’s way of saying “nobody answered at that address”. It is the same problem as I2C device not found on Arduino, and the same checks apply.
Quick fix — try in order
- 1
Scan first
print([hex(a) for a in i2c.scan()]). An empty list means no device is answering — wiring or power.
- 2
Match pins to the I2C peripheral (Pico)
On the Pico, I2C0 SDA/SCL must be GP0/1, 4/5, 8/9, 12/13, 16/17 or 20/21; I2C1 uses GP2/3, 6/7, 10/11, 14/15, 18/19 or 26/27. Mixing them raises an error or fails.
- 3
Use the address the scan returns
Common: 0x3C for SSD1306, 0x76/0x77 for BME280, 0x27/0x3F for LCD backpacks.
- 4
Check power and ground
Most modules run at 3.3 V on the Pico; make sure GND is shared.
Why it happens
What is ENODEV?
The I2C driver sent the address and got no acknowledgement — no device at that address on that bus.
Wrong I2C bus number
I2C(0) and I2C(1) are different controllers with different allowed pins.
Missing pull-ups
Bare chips need 4.7 kΩ pull-ups on SDA and SCL; most breakout boards include them.
Board-specific notes
Pico W: Check pins with the Pico W pinout (filter: I2C).
Parts: SSD1306 OLED · BME280 — pinout, voltage and library notes.
Did this fix it?
Thanks — that helps us keep this page right.