# CircuitPython I2C and PicoCalc I2C keyboard

**URL:** <https://forum.clockworkpi.com/t/circuitpython-i2c-and-picocalc-i2c-keyboard/22370>\
**Category:** PicoCalc\
**Tags:** firmware\
**Created:** [May 14, 2026, 1:54pm UTC](https://forum.clockworkpi.com/t/circuitpython-i2c-and-picocalc-i2c-keyboard/22370 "2026-05-14T13:54:14Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![danh](https://yyz1.discourse-cdn.com/flex029/user_avatar/forum.clockworkpi.com/danh/32/16636_2.png) [@danh](https://forum.clockworkpi.com/u/danh)\
**Post date:** [May 14, 2026, 1:54pm UTC](https://forum.clockworkpi.com/t/circuitpython-i2c-and-picocalc-i2c-keyboard/22370/1 "2026-05-14T13:54:14Z")

</div>

I am one of the CircuitPython core developers. A user asked about running CircuitPython on the PicoCalc, which I didn’t know about. I heard that there was an issue getting the CircuitPython I2C implementation to talk to the STM32-based I2C keyboard. It worked with MicroPython but not CIrcuitPython. Someone made a custom build of CIrcuitPython which provided a different I2C implementation to get around this problem, but no one opened an issue with us about it.

The CircuitPython I2C implementation is very close to the MicroPython implementation, except that it includes a check for pull-ups on the I2C lines. So it’s unclear to me why it wouldn’t work. It was also reported that our `bitbangio` implementation of I2C didn’t work also, which is even stranger, because it shares no code with the hardware-based `busio` implementation.

I am interested in fixing the I2C issue in CircuitPython, if it is still present. If someone has further technical details, I’d be interested in hearing them.

(I also understand there was non-technical conflict related to the CircuitPython implementation. My interest here is only technical.)

---

<div class="post-metadata">

**Author:** ![jblanked](https://yyz1.discourse-cdn.com/flex029/user_avatar/forum.clockworkpi.com/jblanked/32/17438_2.png) [@jblanked](https://forum.clockworkpi.com/u/jblanked)\
**Post date:** [May 14, 2026, 2:38pm UTC](https://forum.clockworkpi.com/t/circuitpython-i2c-and-picocalc-i2c-keyboard/22370/2 "2026-05-14T14:38:07Z")

</div>

Hey welcome to the forums!

Picoware has a CircuitPython implementation for the PicoCalc:

> **[GitHub - jblanked/Picoware: Open-source custom firmware for PicoCalc, Video...](https://github.com/jblanked/Picoware)**
>
> Open-source custom firmware for PicoCalc, Video Game Module, and other Raspberry Pi Pico devices

---

<div class="post-metadata">

**Author:** ![danh](https://yyz1.discourse-cdn.com/flex029/user_avatar/forum.clockworkpi.com/danh/32/16636_2.png) [@danh](https://forum.clockworkpi.com/u/danh)\
**Post date:** [May 14, 2026, 2:38pm UTC](https://forum.clockworkpi.com/t/circuitpython-i2c-and-picocalc-i2c-keyboard/22370/3 "2026-05-14T14:38:56Z")

</div>

Maybe this was fixed and is no longer an issue? [Fix i2c slave scl freeze if read address first recieved by shtirlic · Pull Request #25 · clockworkpi/PicoCalc · GitHub](https://github.com/clockworkpi/PicoCalc/pull/25)

Easy test: load CircuitPython on the Pico. Try this in the REPL  
`import busio`  
`i2c = busio.I2C(scl=board.<proper SCL pin>, sda=board.<proper SDA pin>) # I don’t know the pins needed`  
`i2c.try_lock()`  
`i2c.scan()`  
The keyboard should respond as an I2C device at a particular address.

---

<div class="post-metadata">

**Author:** ![danh](https://yyz1.discourse-cdn.com/flex029/user_avatar/forum.clockworkpi.com/danh/32/16636_2.png) [@danh](https://forum.clockworkpi.com/u/danh)\
**Post date:** [May 14, 2026, 2:40pm UTC](https://forum.clockworkpi.com/t/circuitpython-i2c-and-picocalc-i2c-keyboard/22370/4 "2026-05-14T14:40:14Z")

</div>

@jblanked Thanks! So are you using just the latest vanilla CircuitPython build for the particular Pi Pico version that’s plugged in, or do you have a specially-built UF2?

---

<div class="post-metadata">

**Author:** ![jblanked](https://yyz1.discourse-cdn.com/flex029/user_avatar/forum.clockworkpi.com/jblanked/32/17438_2.png) [@jblanked](https://forum.clockworkpi.com/u/jblanked)\
**Post date:** [May 14, 2026, 2:43pm UTC](https://forum.clockworkpi.com/t/circuitpython-i2c-and-picocalc-i2c-keyboard/22370/5 "2026-05-14T14:43:11Z")

</div>

I am using a custom-built UF2. It uses C modules to connect with the hardware.

You can try out the builds here:

> **[Picoware/builds/CircuitPython at main · jblanked/Picoware](https://github.com/jblanked/Picoware/tree/main/builds/CircuitPython)**
>
> main/builds/CircuitPython

and the source here:

> **[Picoware/src/CircuitPython at main · jblanked/Picoware](https://github.com/jblanked/Picoware/tree/main/src/CircuitPython)**
>
> main/src/CircuitPython

---

<div class="post-metadata">

**Author:** ![danh](https://yyz1.discourse-cdn.com/flex029/user_avatar/forum.clockworkpi.com/danh/32/16636_2.png) [@danh](https://forum.clockworkpi.com/u/danh)\
**Post date:** [May 14, 2026, 3:04pm UTC](https://forum.clockworkpi.com/t/circuitpython-i2c-and-picocalc-i2c-keyboard/22370/6 "2026-05-14T15:04:06Z")

</div>

Nice! So it looks like you are using the raw pico-sdk I2C calls instead of `busio.I2C` in your custom CircuitPython build.  
I don’t have a PicoCalc, and it looks like getting one will take months or I’ll need to pay a premium. My main interest is in making sure vanilla CircuitPython is able to talk to the STM32 on the keyboard properly.

---

<div class="post-metadata">

**Author:** ![jblanked](https://yyz1.discourse-cdn.com/flex029/user_avatar/forum.clockworkpi.com/jblanked/32/17438_2.png) [@jblanked](https://forum.clockworkpi.com/u/jblanked)\
**Post date:** [May 14, 2026, 3:14pm UTC](https://forum.clockworkpi.com/t/circuitpython-i2c-and-picocalc-i2c-keyboard/22370/7 "2026-05-14T15:14:52Z")

</div>

> [@danh](#):
>
> My main interest is in making sure vanilla CircuitPython is able to talk to the STM32 on the keyboard properly.

Ahh I see, my apologies. Unfortunately, no one has been able to get it to work. There has been three or four (public) attempts from other developers on this forum.

---

<div class="post-metadata">

**Author:** ![ernst](https://avatars.discourse-cdn.com/v4/letter/e/9f8e36/32.png) [@ernst](https://forum.clockworkpi.com/u/ernst)\
**Post date:** [May 14, 2026, 6:26pm UTC](https://forum.clockworkpi.com/t/circuitpython-i2c-and-picocalc-i2c-keyboard/22370/8 "2026-05-14T18:26:17Z")

</div>

Using Thonny with Adafruit CircuitPython 10.2.1 on Pico 2

```auto
>>> import busio
>>> import board
>>> i2c = busio.I2C(board.GP7, board.GP6)
>>> i2c.try_lock()
True
>>> i2c.scan>()
[31] 
>>>

```

---

<div class="post-metadata">

**Author:** ![danh](https://yyz1.discourse-cdn.com/flex029/user_avatar/forum.clockworkpi.com/danh/32/16636_2.png) [@danh](https://forum.clockworkpi.com/u/danh)\
**Post date:** [May 14, 2026, 7:22pm UTC](https://forum.clockworkpi.com/t/circuitpython-i2c-and-picocalc-i2c-keyboard/22370/9 "2026-05-14T19:22:15Z")

</div>

@ernst Thanks very much. I have another user who verified that as well, using the PicoCalc 1.6 BIOS.

The test program below to test the keyboard also worked for that user. Load it and press keyboard buttons. I used Claude to cook up a quick test after pointing it to some info about the keyboard I2C device.

So the answer to my original query is that CircuitPython `busio.I2C` now works, and my guess is that it’s because of [https://github.com/clockworkpi/PicoCalc/pull/25](https://github.com/clockworkpi/PicoCalc/pull/25).

This means that much more can now be written in CircuitPython itself instead of resorting to custom C code in a custom CircuitPython build. I don’t intend to do that myself, but I’m glad the original issue seems to be resolved.

> **code.py keyboard test program**
>
