Raspberry Pi Pico W I2C/Piicodev Bug [Solved]

Hi Guys,

We’ve had a few reports of I2C issues with the Pi Pico W (i.e. when using PiicoDev gear), shown below:

We believe this is due to bugs in recent MicroPython builds. Below is a nightly build we have verified to work:
rp2-pico-w-20220831-unstable-v1.19.1-358-g0b26efe73.uf2.zip (495.8 KB)
Just extract it and copy it over to your Pico as you did when you first set up MicroPython.

Here’s an image of us using this build with a PiicoDev BME280:

Let us know if this works/didn’t work for you, or if the nightly/stable builds have fixed this issue down the line.



Thanks. That worked first up (I had previously set the correct pins).
Spend hours yesterday on this problem before discovering your solution.
I thought initially I had wasted a hell of a lot of time, however as a newby I learned
a hell of a lot about using Thonny and the Pico W. I had been using
firmware dated Sept 29th.



There’s a minor issue with attempting to stop the code running
in Thonny. Even Multiple clicks on the “Stop” button fail, and
Control-C in the Shell window sometimes does not work. In both
cases the “could not communicate” message is issued -

16.61 °C 989.4816 hPa 58.31348 %RH
16.61 °C 989.5022 hPa 58.32324 %RH
16.61 °C 989.5151 hPa 58.30176 %RH
PiicoDev could not communicate with module at address 0x77, check wiring
nan °C nan hPa nan %RH
16.62 °C 989.5008 hPa 58.30273 %RH
16.62 °C 989.5334 hPa 58.31348 %RH
16.62 °C 989.517 hPa 58.32422 %RH
16.62 °C 989.5154 hPa 58.31348 %RH
16.62 °C 989.4838 hPa 58.31348 %RH
PiicoDev could not communicate with module at address 0x77, check wiring
nan °C nan hPa nan %RH
16.62 °C 989.4551 hPa 58.25879 %RH
16.62 °C 989.4714 hPa 58.24805 %RH
16.62 °C 989.4861 hPa 58.21582 %RH

1 Like

My apologies, I did not specify that I’ve a Pico W and Piicodev BME280 on
a LiPo Expansion Board.

1 Like

Its a timing issue. The loop was repeating every 0.1s, the problem disappeared at loop time 1s.


Hi Peter,

There is some histeresis required between readings for diferent sensors, some as low 0.05 seconds (the MPU6050 and QMC6310 has a super high refresh rate!)


1 Like

The issue is still there in

It would be nice to have a resolution in the on-going development.
I suspect there are other fixes I’m missing having to use this out-of-date code.

Hi Peter,

Since the Pico W was released so quickly after it was announced it has meant open source projects like the micropython firmware are having to play catchup. Progress is coming along quickly though so I suspect it won’t be long until the I2C bug is fixed again in the latest nightly releases and you can go back to the very latest version.

For now, it doesn’t seem there are any features missing from the version we know doesn’t have the I2C bug.


Hi Peter,

Just one more thing worth mentioning. Generally nightly builds are automatically built and uploaded every night, regardless of whether they fixed/added/broke any features. Unless you have a specific feature or code change in mind, it’s probably just best to stick with what works.

I’m sure the next major release of MicroPython will have a definite fix.



Thanks for the update.

As of today this problem is still not solved. It caught me in my current project.
Thought my wiring or soldering was bad.

It would be confusing for someone if they did not know of it.
The links on the Micropython page do not include version -358-

Thanks for providing a download here.


(MicroPython maintainer here – happened to see this thread referenced here: 💥🐍 One of the features of MicroPython... - Core Electronics)

I’m not aware of any reports of I2C being broken on rp20240/Pico in MicroPython, so if you’re waiting for a fix then I don’t think there’s anything in the pipeline.

I’m taking a guess here but is it possible that somewhere (in Piicodev maybe) that constructs a default I2C instance? @Trent5487676 / @James ? I’ll copy below what I wrote on the FB post:

In summary, for the initial release of the Pico firmware the default pins for I2C/SPI were unspecified so an arbitrary choice was made in MicroPython. Later Raspberry Pi published defaults and updated the official pinout diagrams. So we were stuck with a difficult decision but decided to go with “match the official pinout”. This will be documented in the release notes for v1.20.

In general my recommendation is to always specify the sda/scl pins when using machine.I2C.

If you have issues like this come up, please always feel free to post at https://github.com/orgs/micropython/discussions (or raise an issue at https://github.com/micropython/micropython/issues) and get the attention of the core team quickly.


Don’t we just have egg on our face!
Yes within PiicoDev_Unified.py we were using the default I2C initialiser as found in the Raspberry Pi Pico MicroPython SDK document:

I’ve updated PiicoDev_Unified.py to set the I2C parameters explicitly and all appears to work well with Pico W. (commit 34940db)

Thanks for setting us on the right path @jimmo


Thanks @Michael glad it’s solved.

Yes we’re kind of in a rock and a hard place here with what to do here. I will contact Raspberry Pi about getting that SDK document updated.

But importantly we now match https://datasheets.raspberrypi.com/pico/Pico-R3-A4-Pinout.pdf and also the default pin in the Pico SDK (that’s actually how we implemented the change, we just removed our override and inherit it from the SDK).


This is still NOT working on the latest version of Micropython Pico W.
It is not related to pin or frequency assignment or the Core electronics I2C unified library.
My code is the same for all tests I did.
Version rp2-pico-w-20220908-unstable-v1.19.1-378-g24678fe45 works ok.
Version rp2-pico-w-20220909-unstable-v1.19.1-387-gcacc96d98 and subsequent versions do not.

Somewhere after -378- a change must have been introduced to make it fail.
I don’t have the versions in between.

The code fails on i2c.writeto_mem().
The device I am using is LCD1602 RGB Module, 16x2 Characters LCD, RGB Backlight, 3.3V/5V, I2C SKU: CE07881 $21.65. The driver is from the Waveshare Web site. Probably I could rewrite the driver to make it work, unsure.

Anyway my project works with -378- so that is what I will use for now.


@James46717 That range of commits is exactly the commits where I changed the default pin assignments. There is no other changes affecting the rp2/Pico port in that range.

I can see that the driver you’re referencing explicitly sets the pins though. I will investigate.



At the top of that driver (RGB1602.py) it goes

from machine import Pin,I2C

RGB1602_SDA = Pin(4)
RGB1602_SCL = Pin(5)

RGB1602_I2C = I2C(0,sda = RGB1602_SDA,scl = RGB1602_SCL ,freq = 400000)

Unfortunately don’t have an I2C RGB1602 handy, but using that exact code I am able to communicate with a different i2c device on pins 4&5 (on both Pico & Pico W). (FWIW, 4&5 are the default pins now).

Here are some things to try at the REPL (with expected output)

>>> import RGB1602
>>> RGB1602.RGB1602_I2C
I2C(0, freq=399361, scl=5, sda=4)
>>> RGB1602.RGB1602_I2C.scan()
[62, 96]

If that doesn’t work, then before importing RGB1602, trye

>>> from machine import SoftI2C, Pin
>>> soft = SoftI2C(sda=Pin(4), scl=Pin(5))
>>> soft.scan()
[62, 96]

It’s really interesting that you’ve narrowed it down to that exact range of commits…there’s really nothing else that affects Pico in that range.


@jimmo Thanks for your reply.
I have been investigating how the datasheet for the LCD and have a few ideas.
i2c.scan() works and displays the correct addresses.
The LCD driver fails on i2c.writetomem()
Will try your suggestion and post later, don’t have time to do that right now.
Also want to try a mod to the driver.


EDIT: Changed the frequency to 100000 and it now works, strange.
The LCD clock is 270khz (I think), probably the I2C was defaulting to 400000, and a little too fast.

Supports the statement of always set the I2C parameters, don’t rely on them to somehow be right.


The previous test of changing the frequency was rushed, it was not tested properly. I was unable to duplicate it later.

After some investigation and trying a number of things, I decided to modified the RGB1602 driver to accept an I2C instance rather than creating its own. Similar to the Makerverse RTC driver Core Electronics developed. This in my opinion is the way a library should work. The software using the library determines the pins and other parameters.

Loaded rp2-pico-w-20221014-unstable-v1.19.1-544-g89b320737 being the latest version and it works nicely. Tried a number of previous versions and they all work !!! Don’t ask me why.

Apologies for pointing the finger at the OS when it was the driver all along. The Waveshare products are good as far as manufacturing goes but the software is sometimes lacking. Not going to worry why it now works and why it worked for one version but not the next. Going to move on.

Sorry if I caused any grief.


Hi James

Agree wholeheartedly. I only have one Waveshare product.

LCD1602 RGB Module, 16x2 Characters LCD, RGB Backlight, 3.3V/5V, I2C Bus.

I have had this for some time and gave up on it until I have more time (and inclination) to investigate and try to get it working. I ran a couple of demos and some pretty basic sketches with no joy.
It produced the demo screen OK and I can print anything to it as long is the content is enclosed in “”. That is it will print strings but numbers??? Another story altogether. Probably something I am doing wrong or I have missed. Will get to it eventually.
Needless to say that is the only Waveshare product I have and will remain the only one until I manage to sort out what I have done wrong (if anything) with this one.
I had a bit of bother with that I2C backpack device too until I found another library that works very well. I intend to try this library with the Waveshare display soon and see if that works. If it uses the same IC it might just work.
Cheers Bob