CircuitPython, Adafruit Feather RP2040 en I2C

De RP2040 heeft twee I2C controllers - goed wanneer u bijvoorbeeld twee I2C apparaten met hetzelfde I2C adres wilt laten werken.

In mijn testopstelling heb ik een Adafruit Feather RP2040 microcontroller bord, en heb ik twee van onze BME688 breakout borden - één met de pennen SCL + SDA en één met A1 (voor SCL) + A0 (voor SDA).

Ik gebruik CircuitPython in versie 7.0.0, die u hier kunt downloaden.

Verder heb ik alle bibliotheken van Adafruit geïnstalleerd in de lib map op de Feather RP2040. (De Feather RP2040 heeft voldoende ruimte op zijn Flash om dit mogelijk te maken)

U kunt deze bibliotheken downloaden in de Adafruit CircuitPython Bundel hier. (Ik heb gedownload adafruit-circuitpython-bundel-7.x-mpy-20211123.zip)

Noot: om deze bibliotheken te installeren kopieert u ze eenvoudigweg naar de map lib op de CIRCUITPY "drive" die op uw computer is aangekoppeld. U moet natuurlijk alleen de bibliotheken kopiëren, niet de voorbeelden en andere dingen.

Het grote voordeel van het gebruik van Adafruit's spullen is dat je een heleboel voorbeelden krijgt die veel populaire chips dekken, en je kunt er heel gemakkelijk mee beginnen. Er zijn dingen zoals het aansturen van een microSD kaart met SPI, het uitlezen van een RTC, en het uitlezen van de BME680 sensor.

I2C testen in CircuitPython

Ik heb de volgende opstelling, omdat ik twee apparaten onafhankelijk van elkaar wil aansturen (die in dit geval toevallig dezelfde adressen hebben):

Feather RP2040 en twee BME688 breakout borden

Merk op dat onze BME688 breakout boards al pullups bevatten voor SDA en SCL. (U heeft pullups nodig op SDA en SCL).

Noot 2: Ons BME688 breakout bord heeft de mogelijkheid om het adres te veranderen, dus dit scenario is bedoeld voor demonstratie doeleinden.

Om beide pinnenreeksen sequentieel te doorlopen (om de apparaten te ontdekken), gebruik ik de volgende code:

print("SCL / SDA scannen")
i2c = busio.I2C(board.SCL, board.SDA)
# een scan
i2c.try_lock()
print(i2c.scan())
i2c.ontgrendelen()
i2c.deinit()

print("A0 / A1 scannen")
si2c = busio.I2C(board.A1, board.A0)
# een scan
si2c.try_lock()
print(si2c.scan())
si2c.ontgrendelen()

Opmerking: de i2c.deinit() is de sleutel tot de werking van dit specifieke voorbeeld! (omdat SCL / SDA en A0 / A1 beide dezelfde hardware I2C periferie hebben - zie hieronder).

Dit zou het volgende moeten opleveren:

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

Hier, 119 is decimaal voor hex 0x77 - dat is het adres van onze BME688 breakout bord in de standaard toestand.

Beide borden zijn te zien, achtereenvolgens in de afzonderlijke scans.

Het probleem is dat we ze gelijktijdig willen gebruiken.

Twee I2C bussen gelijktijdig op de Adafruit Feather RP2040

CircuitPython ondersteunt beide hardware controllers (SDA0/SCL0 en SDA1/SCL1). U hoeft geen configuratie in te stellen (welke controller u wilt gebruiken, of hoe de pinnen gemuxed moeten worden) - dit wordt verzorgd door busio voor jou.

U moet wel opletten welke pinnen u gebruikt, want de pinnen leveren alleen een van deze bussen in elk geval, en als je toevallig conflicterende pinnen kiest, krijg je ValueError: I2C randapparaat in gebruik .

Adafruit Feather RP2040 Pinout

Als u "conflicterende" pinnen wilt gebruiken, bijvoorbeeld SCL / SDA (die SCL1 en SDA1 hebben) en A0 / A1 (die ook SCL1 en SDA1 hebben), dan moet u een van de poorten bitbangen:

Hier is hoe je deze pin-configuratie kan scannen zonder deinit() op te roepen:

import bord
importeren busio
importeren bitbangio
# https://circuitpython.readthedocs.io/en/latest/shared-bindings/bitbangio/index.html

print("SCL / SDA scannen - hoofd I2C")
i2c = busio.I2C(board.SCL, board.SDA)
# een scan
i2c.try_lock()
print(i2c.scan())
i2c.ontgrendelen()
# het is niet nodig om hier deinit aan te roepen!
#i2c.deinit()

print("A0 / A1 scannen - secundaire I2C [bitbang!]")
si2c = bitbangio.I2C(board.A1, board.A0)
# een scan
si2c.try_lock()
print(si2c.scan())
si2c.ontgrendelen()

# ook hier hoeven we deinit niet aan te roepen
#i2c.deinit()

We gebruiken bitbangio om een secundaire I2C aan te sturen. In mijn geval wordt de secundaire I2C gebruikt voor een intern doel (voor een poortuitbreider), en kan deze waarschijnlijk met een lagere interfacesnelheid toe.

Opmerking: u kunt het I2C-periferie dat naar de pennen wordt geleid niet softwarematig kiezen - als u een ander periferie nodig hebt, moet u andere pennen gebruiken.

Oplossen van I2C fouten

ValueError: I2C randapparaat in gebruik

Als je busio.I2C gebruikt voor beide poorten: Controleer of u al dezelfde hardware I2C periferie gebruikt - en of u uw pinnen opnieuw moet toewijzen.

Bijvoorbeeld, zowel SCL en SDA , en A0 en A1 delen dezelfde hardware I2C periferie (SCL1 / SDA1 - zie de Adafruit Feather RP2040 pinout foto in dit artikel).

In het geval dat je toch dezelfde pin setup wilt gebruiken, kun je bitbangio gebruiken om een extra software-gestuurde I2C poort te "maken". Het nadeel hiervan is een lagere snelheid voor deze software-I2C poort, en een hogere CPU belasting.

RuntimeError: Geen pull up gevonden op SDA of SCL; controleer uw bedrading

Als u de volgende foutmelding krijgt

RuntimeError: Geen pull up gevonden op SDA of SCL; controleer uw bedrading

dan moet je pullup weerstanden plaatsen tussen 3V3 op het bord (de 3.3V pin) en respectievelijk je SDA en SCL pinnen. Deze zijn nodig voor een normale I2C werking (de apparaten trekken de I2C pinnen naar beneden om te communiceren, de standaard / idle toestand op de bus is hoog) - en zijn niet inbegrepen op de Adafruit Feather RP2040. Ze zijn wel aanwezig op veel randapparatuur van Adafruit, en op randapparatuur van andere bedrijven (zoals, alweer onze eigen BME688 breakout bord).

Als u niet weet wat een pullup is: dit is in wezen een weerstand tussen de pin in kwestie (b.v. SDA) en de 3,3 V voedingspin. Hij hoeft niet erg precies te zijn. U kunt het beste beginnen met weerstanden van 10 kOhm, als dat niet werkt, probeer dan eventueel een weerstand van 1 kOhm voor een "stijvere" pullup.

TimeoutError: Klok rek te lang

Controleer of de chip waarmee u wilt praten de juiste spanning heeft.

Diverse notities

Referenties / Hulpbronnen / Links / Verdere lectuur

Laat een reactie achter