# Adafruit Py Qt 2040 - Thonny - Piicodev

**URL:** <https://forum.core-electronics.com.au/t/adafruit-py-qt-2040-thonny-piicodev/20043>\
**Category:** Support\
**Created:** [25 May 2024 07:25 UTC](https://forum.core-electronics.com.au/t/adafruit-py-qt-2040-thonny-piicodev/20043 "2024-05-25T07:25:45Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![Pixmusix](https://yyz2.discourse-cdn.com/flex028/user_avatar/forum.core-electronics.com.au/pixmusix/32/9719_2.png) [@Pixmusix](https://forum.core-electronics.com.au/u/Pixmusix)\
**Post date:** [25 May 2024 07:25 UTC](https://forum.core-electronics.com.au/t/adafruit-py-qt-2040-thonny-piicodev/20043/1 "2024-05-25T07:25:45Z")

</div>

Hiya.

Got a wiring issue needing some assistance debugging.

### Code

I’m using Thonny.  
Running this code.

```python
import neopixel
import machine

from PiicoDev_SSD1306 import *
from PiicoDev_Unified import sleep_ms

#Init Neopixel
np_pow = machine.Pin(11, machine.Pin.OUT)
np = machine.Pin(12, machine.Pin.OUT)
np_pow.value(1)
px = neopixel.NeoPixel(np, 1)

def pukPix(v):
    px[0] = (v, 0, v)
    px.write()
    sleep_ms(100)
    
def flickerNeopixel():
    for i in range(0,12):
        v = (i % 2) * 255
        pukPix(v)
    pukPix(0)

#Init Display
display = create_PiicoDev_SSD1306() #Onboard Neopixel flickers if you remove this line

while True:
    flickerNeopixel() #HERE I AM!
    sleep_ms(1000)

```

### Files

I created and uploaded these files

- Download the _PiicoDev Unified Library_: [PiicoDev\_Unified.py](https://raw.githubusercontent.com/CoreElectronics/CE-PiicoDev-Unified/main/PiicoDev_Unified.py) (right-click, “save link as”).
- Download the device module: [PiicoDev\_SSD1306.py](https://raw.githubusercontent.com/CoreElectronics/CE-PiicoDev-SSD1306-MicroPython-Module/main/PiicoDev_SSD1306.py) (right-click, “save link as”)

### Lib install

Lastly I made sure my PC running thonny had Piicodev library.

```auto
pip install piicodev

```

```auto
pip show piicodev
Name: piicodev
Version: 1.10.0
Summary: Drivers for the PiicoDev ecosystem of sensors and modules
Home-page: https://github.com/CoreElectronics/CE-PiicoDev-PyPI
Author: Core Electronics
Author-email: production.inbox@coreelectronics.com.au
License: UNKNOWN
Location: C:\Users\optim\AppData\Local\Programs\Python\Python311\Lib\site-packages
Requires: smbus2
Required-by:

```

### Setup Pic

 ![441929617_463731829347692_6106700114905950255_n](https://canada1.discourse-cdn.com/flex028/uploads/core_electronics/original/2X/a/a36a2de6d22f8dd4b6d54731ac12357ec0ef65ac.jpeg)

### Error

I’m getting the following error.

> PiicoDev could not communicate with module at address 0x3C, check wiring

On this [thread](https://forum.core-electronics.com.au/t/i2c-issues-on-pico-w/17570/3) I noticed to check the addr pins are unsoldered.  
mine seem to have a connection?  
What does that mean? could that be the source of my problem?

 ![445562398_854571379815107_1386765019255898092_n](https://canada1.discourse-cdn.com/flex028/uploads/core_electronics/original/2X/f/f60893c2530bd975d6aa1d841e32cead96bdac9c.jpeg)

Any other sanity checks to try?  
Thanks champs. 💪  
Pix ❣

---

<div class="post-metadata">

**Author:** ![Jeff105671](https://yyz2.discourse-cdn.com/flex028/user_avatar/forum.core-electronics.com.au/jeff105671/32/3729_2.png) [@Jeff105671](https://forum.core-electronics.com.au/u/Jeff105671)\
**Post date:** [25 May 2024 09:00 UTC](https://forum.core-electronics.com.au/t/adafruit-py-qt-2040-thonny-piicodev/20043/2 "2024-05-25T09:00:53Z")

</div>

Start by checking whether or not there is a device at address 0x3C.  
[Raspberry Pi | How to Scan and Detect I2C Addresses | Adafruit Learning System](https://learn.adafruit.com/scanning-i2c-addresses/raspberry-pi)

Your device appears to have a switch for the address selection, not solder tabs. If you change the switch you should see the address change in the I2C bus scan. That would show that the device you are seeing in the scan is the SSD1306.

---

<div class="post-metadata">

**Author:** ![Pixmusix](https://yyz2.discourse-cdn.com/flex028/user_avatar/forum.core-electronics.com.au/pixmusix/32/9719_2.png) [@Pixmusix](https://forum.core-electronics.com.au/u/Pixmusix)\
**Post date:** [25 May 2024 10:19 UTC](https://forum.core-electronics.com.au/t/adafruit-py-qt-2040-thonny-piicodev/20043/3 "2024-05-25T10:19:27Z")

</div>

Thanks Jeff.

Doesn’t seem like there is a windows port of the i2c tools.  
No worries, I’ll wait till I’m back in the studio with linux or OSX.  
I’ll be in touch.

---

<div class="post-metadata">

**Author:** ![Jeff105671](https://yyz2.discourse-cdn.com/flex028/user_avatar/forum.core-electronics.com.au/jeff105671/32/3729_2.png) [@Jeff105671](https://forum.core-electronics.com.au/u/Jeff105671)\
**Post date:** [25 May 2024 11:01 UTC](https://forum.core-electronics.com.au/t/adafruit-py-qt-2040-thonny-piicodev/20043/4 "2024-05-25T11:01:55Z")

</div>

You don’t need any special Windows support for Pi code - it’s the same for any platform. For instance:  
[Raspberry Pi Pico: I2C Scanner (MicroPython) | Random Nerd Tutorials](https://randomnerdtutorials.com/raspberry-pi-pico-i2c-scanner-micropython/#i2c-scanner)

---

<div class="post-metadata">

**Author:** ![Pixmusix](https://yyz2.discourse-cdn.com/flex028/user_avatar/forum.core-electronics.com.au/pixmusix/32/9719_2.png) [@Pixmusix](https://forum.core-electronics.com.au/u/Pixmusix)\
**Post date:** [25 May 2024 12:10 UTC](https://forum.core-electronics.com.au/t/adafruit-py-qt-2040-thonny-piicodev/20043/5 "2024-05-25T12:10:26Z")

</div>

Ah I see it’s a python library not a Linux package.

Thanks for the link 👍  
Based on the [pinout of the qt py](https://learn.adafruit.com/adafruit-qt-py-2040/pinouts) I have two i2c outs so I modified the code you linked to search both of them.

```python
from machine import Pin, SoftI2C

def scani2c(i2c):
    devices = i2c.scan()
    if len(devices) == 0:
      print("No i2c device !")
    else:
      print('i2c devices found:', len(devices))
      for device in devices:
        print("I2C hexadecimal address: ", hex(device))

i2c_0 = SoftI2C(scl=Pin(25), sda=Pin(24))
i2c_1 = SoftI2C(scl=Pin(23), sda=Pin(22))

print('I2C_0 SCANNER')
scani2c(i2c_0)
print('i2c_1 SCANNER')
scani2c(i2c_1)

```

> I2C\_0 SCANNER  
> No i2c device !  
> i2c\_1 SCANNER  
> i2c devices found: 1  
> I2C hexadecimal address: 0x3c

I was expecting the i2c\_0 scanner to detect the qt py Audio BFF but I guess that’s a future problem.

i2c\_1 did detect the OLED display which is good news.  
The piicodev example code I found didn’t seem to require me to specify the address. I wonder if I’m supposed to modify the [PiicoDev\_SSD1306.py](https://raw.githubusercontent.com/CoreElectronics/CE-PiicoDev-SSD1306-MicroPython-Module/main/PiicoDev_SSD1306.py) device module file. It’s from [CE’s Raspberry Pi Pico Guide](https://core-electronics.com.au/guides/piicodev-oled-ssd1306-raspberry-pi-pico-guide/), which also uses an RP2040, but may not have the same SCL and SDA GPIO pinouts.  
Happy to have a dig through that.  
Any other thoughts to try while I’m at it? 🙂

---

<div class="post-metadata">

**Author:** ![Pixmusix](https://yyz2.discourse-cdn.com/flex028/user_avatar/forum.core-electronics.com.au/pixmusix/32/9719_2.png) [@Pixmusix](https://forum.core-electronics.com.au/u/Pixmusix)\
**Post date:** [25 May 2024 12:31 UTC](https://forum.core-electronics.com.au/t/adafruit-py-qt-2040-thonny-piicodev/20043/6 "2024-05-25T12:31:06Z")

</div>

Quick followup.

The constructor of the Piicodev OLED display made it look like I might be able to pass in the SCL and SDA pin.

```python
def create_PiicoDev_SSD1306(address=0x3C,bus=None, freq=None, sda=None, scl=None, asw=None):
   #...

```

However, the [piicodev SSD1306 github README implies this is just for the Rpi Pico.](https://github.com/CoreElectronics/CE-PiicoDev-SSD1306-MicroPython-Module)

---

<div class="post-metadata">

**Author:** ![Jeff105671](https://yyz2.discourse-cdn.com/flex028/user_avatar/forum.core-electronics.com.au/jeff105671/32/3729_2.png) [@Jeff105671](https://forum.core-electronics.com.au/u/Jeff105671)\
**Post date:** [25 May 2024 21:58 UTC](https://forum.core-electronics.com.au/t/adafruit-py-qt-2040-thonny-piicodev/20043/7 "2024-05-25T21:58:06Z")

</div>

> [@Pixmusix](#):
>
> i2c\_1 did detect the OLED display which is good news.

You detected _something_ at that address. If you have more than one i2c device installed then you need to ensure that all are detected, otherwise you can’t be sure that the device you saw at 0x3C is the SSD1306. Or, unplug any other devices so that only the SSD1306 could be detected. Or, flip the address switch and run the scan again to confirm that it is detected at the alternate address (0X3D).

When you confirm that it is the SSD1306 that you have identified you need to change the constructor to use i2c\_1. It looks like you can use the bus parameter (that worked for the scan): SDA/SCL parameters are listed as only for the Pico.

If that all works then it is likely that the same adjustment is needed for any other I2C device.

---

<div class="post-metadata">

**Author:** ![Pixmusix](https://yyz2.discourse-cdn.com/flex028/user_avatar/forum.core-electronics.com.au/pixmusix/32/9719_2.png) [@Pixmusix](https://forum.core-electronics.com.au/u/Pixmusix)\
**Post date:** [26 May 2024 00:02 UTC](https://forum.core-electronics.com.au/t/adafruit-py-qt-2040-thonny-piicodev/20043/8 "2024-05-26T00:02:22Z")

</div>

> [@Jeff105671](#):
>
> If you have more than one i2c device installed then you need to ensure that all are detected, otherwise you can’t be sure that the device you saw at 0x3C is the SSD1306.

I ran those tests unplugging the audiobff and re-running. Confirmed that it really is the OLED. 👍. For future I can distinguish the bus’s with the `machine.Pin()` objects I pass in to create my i2c\_1 scanner. If the AudioBFF was found it would only be on the I2c\_0 bus. The OLED is the only device on BUS 1.

### i2c bus arguments…

A bit more digging and I did figure out what I was supposed to pass in.  
The piicodev\_ssd1306 lib constructor actually calls the [create\_unified\_i2c()](https://github.com/CoreElectronics/CE-PiicoDev-Unified/blob/main/PiicoDev_Unified.py#L33) constructor. It tries to figure out if you’re on Linux or Esp32 etc. In my case it gives up and passes the call to an [I2CUnifiedMachine()](https://github.com/CoreElectronics/CE-PiicoDev-Unified/blob/main/PiicoDev_Unified.py#L33).  
Inside that constructor there is the if block below which just checks for… a bus. Could be anything.

```python
if bus is not None and sda is not None and scl is not None:
            print('Using supplied bus, sda, and scl to create machine.I2C() with freq: {} Hz'.format(freq))
            self.i2c = I2C(bus, freq=freq, sda=sda, scl=scl)

```

So for example here is my first attempt at specifying the bus.

```python
oled = create_PiicoDev_SSD1306(address=0x3C, bus=1, scl=Pin(23), sda=Pin(22))

```

And that got me this… PROGRESS!!

> i2c devices found: 1  
> I2C hexadecimal address: 0x3c  
> Using supplied bus, sda, and scl to create machine.I2C() with freq: 400000 Hz

Unfortuantely, this also silences the error. 😛

```python
oled = create_PiicoDev_SSD1306(address=0x3C, 
  bus="
  These beauteous forms, 
  Through a long absence, have not been to me 
  As is a landscape to a blind man’s eye: 
  But oft, in lonely rooms, and ’mid the din 
  Of towns and cities, I have owed to them, 
  In hours of weariness, sensations sweet", 
  scl=Pin(23), 
  sda=Pin(22))

```

Gotta love python 😛  
@Jeff I think you’re right it is requiring me to specify the bus. I think It wants the integer 1 but I’m not sure why.

Ultimately, piicodev i2c is just a wrapper around machine.i2c().  
If you[read the docs on the machine.i2c github](https://github.com/micropython/micropython/blob/master/docs/library/machine.I2C.rst) it says

> I2C.init(scl, sda, \*, freq=400000)  
> Initialise the I2C bus with the given arguments:  
> – scl is a pin object for the SCL line  
> – sda is a pin object for the SDA line  
> – freq is the SCL clock rate

I’m actually not sure why I need to specify the bus at all at this point or what it … does?

I found this article and I guess I’ll give it a read on the train home.  
If anyone would love to save me the trouble I’d really appreciate it 😅

> **[slva704.pdf](https://www.ti.com/lit/an/slva704/slva704.pdf?ts=1716609588238&ref_url=https%253A%252F%252Fwww.google.com%252F)**
>
> 125.31 KB

### TL;DR

The bottom line is that the [CE Piicodev\_ SSD1306 README](https://github.com/CoreElectronics/CE-PiicoDev-SSD1306-MicroPython-Module/tree/main) does specify that the range is supposed to be (0,1). I assume that integers not floats.  
I’m not certain how to figure out which one I am, or what it does. 😛

---

<div class="post-metadata">

**Author:** ![Jeff105671](https://yyz2.discourse-cdn.com/flex028/user_avatar/forum.core-electronics.com.au/jeff105671/32/3729_2.png) [@Jeff105671](https://forum.core-electronics.com.au/u/Jeff105671)\
**Post date:** [26 May 2024 00:30 UTC](https://forum.core-electronics.com.au/t/adafruit-py-qt-2040-thonny-piicodev/20043/9 "2024-05-26T00:30:28Z")

</div>

The required values for bus are 0 or 1. If the type is not specified then you can assume integer, as integer can be promoted if required. Failing to specify the type for an argument is a common problem in Arduino library references and perhaps the habit is spreading. _i2c0_ and _i2c1_ are part of the Pi device definition. Using those terms means that code can be moved between different devices that may have different pin definitions for the same function, because the device definition maps the labels to the correct pins. Which one you use depends on how the bus is connected.

From my reading I would assume you don’t use SCL and SDA in the constructor (leave it as none) because bus #1 is already defined as using the alternate pins. You would supply SDA and SCL if you were using pins that are not defined for either bus #0 or bus #1, or if there was no usable bus definition for a particular device. However the code snippet you have quoted (if it applies to your device - you have to look at context for code snippets) suggests that if one of bus sda and scl is not none then all of them must be provided. Whether or not that is the case depends on whether sda and scl get assigned default values if they are passed as none. But you have code that works, so that’s not an issue.

The datasheet you reference is interesting reading (TI documentation is always very good) but probably not helpful for your case. The detail in that document is what the library is trying to simplify down to the minimum set of configuration and operation commands to make the bus devices usable. Having now got the constructor working you can move on with the debugging.

---

<div class="post-metadata">

**Author:** ![Michael](https://yyz2.discourse-cdn.com/flex028/user_avatar/forum.core-electronics.com.au/michael/32/3545_2.png) [@Michael](https://forum.core-electronics.com.au/u/Michael)\
**Post date:** [27 May 2024 06:41 UTC](https://forum.core-electronics.com.au/t/adafruit-py-qt-2040-thonny-piicodev/20043/10 "2024-05-27T06:41:10Z")

</div>

> [@Pixmusix](#):
>
> I’m actually not sure why I need to specify the bus at all at this point or what it … does?

Because the Pico port of MicroPython does require a bus number: [Hardware I2C](https://docs.micropython.org/en/latest/rp2/quickref.html#hardware-i2c-bus)

You’ve really hammered the edges of our PiicoDev docs @Pixmusix and I commend you! I’m sure we could have done a better job when putting them together… but it _is_ an open source project 😃 Pull requests welcomed.

I’m glad your project is on track 🥳

---

<div class="post-metadata">

**Author:** ![Michael](https://yyz2.discourse-cdn.com/flex028/user_avatar/forum.core-electronics.com.au/michael/32/3545_2.png) [@Michael](https://forum.core-electronics.com.au/u/Michael)\
**Post date:** [27 May 2024 06:41 UTC](https://forum.core-electronics.com.au/t/adafruit-py-qt-2040-thonny-piicodev/20043/11 "2024-05-27T06:41:43Z")

</div>

> [@Pixmusix](#):
>
> ```auto
> oled = create_PiicoDev_SSD1306(address=0x3C, 
> bus="
> These beauteous forms, 
> Through a long absence, have not been to me 
> As is a landscape to a blind man’s eye: 
> But oft, in lonely rooms, and ’mid the din 
> Of towns and cities, I have owed to them, 
> In hours of weariness, sensations sweet", 
> scl=Pin(23), 
> sda=Pin(22))
> 
> ```

this is particularly unhinged. We did not include error handling for this case 😅

---

<div class="post-metadata">

**Author:** ![Pixmusix](https://yyz2.discourse-cdn.com/flex028/user_avatar/forum.core-electronics.com.au/pixmusix/32/9719_2.png) [@Pixmusix](https://forum.core-electronics.com.au/u/Pixmusix)\
**Post date:** [28 May 2024 01:55 UTC](https://forum.core-electronics.com.au/t/adafruit-py-qt-2040-thonny-piicodev/20043/12 "2024-05-28T01:55:16Z")

</div>

I think you can have “too much documentation” though right?. 🙂  
If you document the piicodev ecosystem for every variation of micro-controller it will end up making the documentation inaccessible for beginners.  
I figured it out in the end, and I had this forum as an alternate support network.
