CircuitPython, Adafruit Feather RP2040 e I2C

L'RP2040 ha due controllori I2C - buono per esempio, quando vuoi far funzionare due dispositivi I2C con lo stesso indirizzo I2C.

Nella mia configurazione di prova, ho una scheda microcontrollore Adafruit Feather RP2040, e ho collegato due dei nostri Schede breakout BME688 - uno usando i pin SCL + SDA e uno usando A1 (per SCL) + A0 (per SDA).

Sto usando CircuitPython nella versione 7.0.0, che potete scaricare da qui.

Inoltre, ho installato tutte le librerie di Adafruit nella cartella lib sul Feather RP2040. (Il Feather RP2040 ha abbastanza spazio sulla sua Flash per permettere questo)

Potete scaricare queste librerie nella sezione Adafruit CircuitPython Bundle qui. (Ho scaricato adafruit-circuitpython-bundle-7.x-mpy-20211123.zip)

NotaPer installare queste librerie basta copiarle nella cartella lib del "drive" CIRCUITPY montato sul tuo computer. Naturalmente dovrai copiare solo le librerie, non gli esempi e le altre cose.

Il grande vantaggio nell'usare il materiale di Adafruit è che si ottiene una tonnellata di esempi che coprono molti chip popolari, e si può iniziare molto facilmente con esso. Ci sono cose come pilotare una scheda microSD usando SPI, leggere un RTC e leggere dal sensore BME680.

Testare I2C in CircuitPython

Ho la seguente configurazione, dato che voglio pilotare due dispositivi indipendentemente l'uno dall'altro (che in questo caso hanno gli stessi indirizzi):

Piuma RP2040 e due Schede breakout BME688

Notate che le nostre schede di breakout BME688 includono già i pullup per SDA e SCL. (Avete bisogno di pullup su SDA e SCL).

Nota 2: La nostra scheda di breakout BME688 ha l'opzione di cambiare l'indirizzo, quindi questo scenario è inteso a scopo dimostrativo.

Per guidare attraverso entrambi i set di pin in modo sequenziale (per scoprire i dispositivi), sto usando il seguente codice:

print("Scansione SCL / SDA")
i2c = busio.I2C(board.SCL, board.SDA)
# una scansione
i2c.try_lock()
print(i2c.scan())
i2c.unlock()
i2c.deinit()

print("Scansione A0 / A1")
si2c = busio.I2C(board.A1, board.A0)
# una scansione
si2c.try_lock()
print(si2c.scan())
si2c.unlock()

Nota: il i2c.deinit() è la chiave per far funzionare questo particolare esempio! (perché SCL / SDA e A0 / A1 hanno entrambi la stessa periferica hardware I2C - vedi sotto).

Questo dovrebbe produrre quanto segue:

Scansione SCL / SDA
[119]
Scansione A0 / A1
[119]

Qui, 119 è decimale per hex 0x77 - che è l'indirizzo della nostra scheda di breakout BME688 nello stato predefinito.

Entrambe le schede si vedono, in sequenza, nelle singole scansioni.

Il problema è che vogliamo usarli simultaneamente.

Far funzionare due bus I2C simultaneamente sull'Adafruit Feather RP2040

CircuitPython supporta entrambi controllori hardware (SDA0/SCL0 e SDA1/SCL1). Non avete bisogno di impostare alcuna configurazione (quale controller volete usare, o come fare il mux dei pin) - questo è curato da busio per te.

Dovete fare attenzione, però, a quali perni usate, perché i perni forniranno solo uno di questi bus in ogni caso, e se vi capita di scegliere pin in conflitto, otterrete ValueError: periferica I2C in uso .

Pinout Adafruit Feather RP2040

Se volete usare dei pin "in conflitto", per esempio SCL / SDA (che hanno SCL1 e SDA1) e A0 / A1 (che hanno anche SCL1 e SDA1), dovrete bitbangare una delle porte:

Ecco come scansionare questa configurazione di pin senza chiamare deinit():

importare scheda
Importazione busio
importa bitbangio
# https://circuitpython.readthedocs.io/en/latest/shared-bindings/bitbangio/index.html

print("Scansione SCL / SDA - I2C principale")
i2c = busio.I2C(board.SCL, board.SDA)
# una scansione
i2c.try_lock()
print(i2c.scan())
i2c.unlock()
# non c'è bisogno di chiamare deinit qui!
#i2c.deinit()

print("Scansione A0 / A1 - I2C secondario [bitbang!]")
si2c = bitbangio.I2C(board.A1, board.A0)
# una scansione
si2c.try_lock()
print(si2c.scan())
si2c.unlock()

# non abbiamo anche bisogno di chiamare deinit qui
#i2c.deinit()

Stiamo usando bitbangio per pilotare un I2C secondario. Nel mio caso l'I2C secondario è usato per uno scopo interno (per un espansore di porte), e molto probabilmente può fare con una velocità di interfaccia inferiore.

Nota: non siete in grado di scegliere la periferica I2C che viene indirizzata ai pin nel software - se avete bisogno di una periferica diversa, dovete usare pin diversi.

Risoluzione dei problemi degli errori I2C

ValueError: periferica I2C in uso

Se state usando busio.I2C per entrambe le porte: Controllate se state già usando la stessa periferica hardware I2C - e se è necessario riassegnare i pin.

Per esempio, sia SCL e SDA, sia A0 e A1 condividono la stessa periferica hardware I2C (SCL1 / SDA1 - vedi la foto del pinout di Adafruit Feather RP2040 in questo articolo).

Nel caso in cui vogliate usare la stessa configurazione dei pin, potete usare bitbangio per "creare" un'ulteriore porta I2C controllata dal software. Lo svantaggio di questo è una minore velocità per questa porta I2C software, e un maggiore carico della CPU.

RuntimeError: Nessun pull up trovato su SDA o SCL; controlla il tuo cablaggio

Se ottieni il seguente errore

RuntimeError: Nessun pull up trovato su SDA o SCL; controlla il tuo cablaggio

allora dovresti mettere delle resistenze di pullup tra 3V3 sulla scheda (il pin 3.3V) e rispettivamente i tuoi pin SDA e SCL. Questi sono necessari per il normale funzionamento I2C (i dispositivi tirano giù i pin I2C per comunicare, lo stato predefinito / inattivo sul bus è alto) - e non sono inclusi nella Adafruit Feather RP2040. Sono inclusi in molte periferiche Adafruit, e in periferiche di altre aziende (come, di nuovo il nostro Scheda di breakout BME688).

Se non sai cos'è un pullup: questo è essenzialmente una resistenza tra il pin in questione (per esempio SDA) e il pin di alimentazione a 3,3 V. Non è necessario che sia terribilmente preciso. Dovresti iniziare con resistenze da 10 kOhm, se questo non funziona, prova eventualmente una resistenza da 1 kOhm per un pullup più "rigido".

TimeoutError: Tratto dell'orologio troppo lungo

Controlla se il chip con cui vuoi parlare è alimentato correttamente.

Note varie

Riferimenti / Risorse / Link / Ulteriori letture

Lascia un commento