CircuitPython, Adafruit Feather RP2040 i I2C

RP2040 posiada dwa kontrolery I2C - dobre na przykład, gdy chcesz uruchomić dwa urządzenia I2C z tym samym adresem I2C.

W mojej konfiguracji testowej, mam płytkę z mikrokontrolerem Adafruit Feather RP2040, i podłączyłem do niej dwa z naszych BME688 breakout boards - jeden z wykorzystaniem pinów SCL + SDA oraz jeden z wykorzystaniem A1 (dla SCL) + A0 (dla SDA).

Używam CircuitPython w wersji 7.0.0, które można pobrać stąd.

Ponadto, zainstalowałem wszystkie biblioteki Adafruit do katalogu lib w folderze Feather RP2040. (Feather RP2040 ma wystarczająco dużo miejsca na swojej pamięci Flash, aby to umożliwić)

Możesz pobrać te biblioteki w Adafruit CircuitPython Bundle tutaj. (Pobrałem adafruit-circuitpython-bundle-7.x-mpy-20211123.zip)

Uwaga: aby zainstalować te biblioteki po prostu skopiuj je do folderu lib na "dysku" CIRCUITPY, który jest zamontowany na twoim komputerze. Oczywiście będziesz musiał skopiować tylko biblioteki, nie przykłady i inne rzeczy.

Dużą zaletą korzystania z rzeczy Adafruit jest to, że dostajesz tonę przykładów, które obejmują wiele popularnych układów, i możesz bardzo łatwo zacząć od tego. Są tam takie rzeczy jak obsługa karty microSD za pomocą SPI, odczyt RTC, czy odczyt z czujnika BME680.

Testowanie I2C w CircuitPython

Mam następującą konfigurację, ponieważ chcę wysterować dwa urządzenia niezależnie od siebie (które w tym przypadku mają te same adresy):

Feather RP2040 i dwa BME688 breakout boards

Zauważ, że nasze płytki breakout BME688 zawierają już pullupy dla SDA i SCL. (Ty potrzebujesz pullupów na SDA i SCL).

Uwaga 2: Nasza płytka breakout BME688 ma możliwość zmiany adresu, więc ten scenariusz jest przeznaczony do celów demonstracyjnych.

Aby sekwencyjnie przejechać przez oba zestawy pinów (w celu wykrycia urządzeń), używam następującego kodu:

print("Skanowanie SCL / SDA")
i2c = busio.I2C(board.SCL, board.SDA)
# skanowanie
i2c.try_lock()
print(i2c.scan())
i2c.unlock()
i2c.deinit()

print("Skanowanie A0 / A1")
si2c = busio.I2C(board.A1, board.A0)
# a skanowanie
si2c.try_lock()
print(si2c.scan())
si2c.unlock()

Uwaga i2c.deinit() jest kluczem do działania tego konkretnego przykładu! (ponieważ SCL / SDA i A0 / A1 mają zarówno ten sam sprzętowy peryferyjny I2C - patrz poniżej).

Powinno to dać następujące wyniki:

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

Tutaj, 119 jest dziesiętne dla heksadecymalnego 0x77 - który jest adresem naszej płytki BME688 w stanie domyślnym.

Obie tablice są widoczne, kolejno w poszczególnych skanach.

Problem w tym, że chcemy ich używać jednocześnie.

Uruchamianie dwóch magistral I2C jednocześnie na Adafruit Feather RP2040

CircuitPython obsługuje zarówno kontrolerów sprzętowych (SDA0/SCL0 i SDA1/SCL1). Nie musisz ustawiać żadnej konfiguracji (z którego kontrolera chcesz korzystać, czy jak muxować piny) - tym zajmuje się busio dla ciebie.

Należy jednak zwrócić uwagę, których pinów używamy, ponieważ będą one dostarczać tylko jeden z tych magistral w każdym przypadku, a jeśli zdarzy się, że wybierzesz sprzeczne piny, otrzymasz ValueError: Peryferia I2C w użyciu .

Adafruit Feather RP2040 Pinout

Jeśli chcesz użyć "konfliktowych" pinów, fo rexample SCL / SDA (które mają SCL1 i SDA1) i A0 / A1 (które również mają SCL1 i SDA1), będziesz musiał bitbangować jeden z portów:

Oto jak przeskanować tę konfigurację pinów bez wywoływania deinit():

importować deskę
importować busio
importować bitbangio
# https://circuitpython.readthedocs.io/en/latest/shared-bindings/bitbangio/index.html

print("Skanowanie SCL / SDA - główne I2C")
i2c = busio.I2C(board.SCL, board.SDA)
# a skanowanie
i2c.try_lock()
print(i2c.scan())
i2c.unlock()
# nie ma potrzeby wywoływania deinit tutaj!
#i2c.deinit()

print("Skanowanie A0 / A1 - wtórne I2C [bitbang!]")
si2c = bitbangio.I2C(board.A1, board.A0)
# a scan
si2c.try_lock()
print(si2c.scan())
si2c.unlock()

# tutaj również nie musimy wywoływać deinit
#i2c.deinit()

Używamy bitbangio aby wysterować drugorzędny I2C. W moim przypadku drugorzędny I2C jest używany do celów wewnętrznych (do ekspandera portów), i całkiem prawdopodobne, że może sobie poradzić z niższą prędkością interfejsu.

Uwaga: nie masz możliwości programowego wyboru peryferiów I2C, które są kierowane do pinów - jeśli potrzebujesz innych peryferiów, musisz użyć innych pinów.

Rozwiązywanie problemów z błędami I2C

ValueError: Peryferia I2C w użyciu

Jeśli używasz busio.I2C dla obu portów: Sprawdź, czy używasz już tego samego sprzętowego peryferium I2C - i czy musisz ponownie przypisać swoje piny.

Na przykład, zarówno SCL i SDA , jak i A0 i A1 współdzielą ten sam sprzętowy peryferyjny I2C (SCL1 / SDA1 - patrz rysunek wyprowadzeń Adafruit Feather RP2040 w tym artykule).

W przypadku, gdy chcesz użyć tej samej konfiguracji pinów, możesz użyć bitbangio do "stworzenia" dodatkowego portu I2C sterowanego programowo. Wadą tego jest mniejsza prędkość dla tego portu I2C sterowanego programowo i większe obciążenie procesora.

RuntimeError: Nie znaleziono podciągania na SDA lub SCL; sprawdź okablowanie

Jeśli wystąpi następujący błąd

RuntimeError: Nie znaleziono podciągania na SDA lub SCL; sprawdź okablowanie

to powinieneś umieścić rezystory podciągające pomiędzy 3V3 na płytce (pin 3.3V) a odpowiednio twoimi pinami SDA i SCL. Są one wymagane do normalnej pracy I2C (urządzenia ściągają piny I2C aby się komunikować, domyślnym stanem bezczynności na magistrali jest stan wysoki) - i nie są dołączone do Adafruit Feather RP2040. Są one zawarte w wielu urządzeniach peryferyjnych Adafruit, oraz w urządzeniach peryferyjnych innych firm (jak, ponownie, nasze własne BME688 breakout board).

Jeśli nie wiesz co to jest pullup: jest to w zasadzie rezystor pomiędzy danym pinem (np. SDA) a pinem zasilania 3.3 V. Nie musi być on strasznie dokładny. Powinieneś zacząć od rezystorów 10 kOhm, jeśli to nie zadziała, ewentualnie spróbuj rezystora 1 kOhm dla "sztywniejszego" podciągania.

TimeoutError: Zbyt długi odcinek zegara

Sprawdź, czy układ, z którym chcesz rozmawiać, jest prawidłowo zasilany.

Różne notatki

Referencje / Zasoby / Linki / Dalsza lektura

Pozostaw komentarz