CircuitPython、Adafruit Feather RP2040とI2C

RP2040には2つのI2Cコントローラが搭載されており、同じI2Cアドレスで2つのI2Cデバイスを動作させたい場合などに適しています。

私のテスト・セットアップでは、Adafruit Feather RP2040 マイクロコントローラ・ボードを使用しています。 BME688ブレイクアウトボード - SCL+SDA端子とA1(SCL)+A0(SDA)端子で構成されています。

バージョン7.0.0のCircuitPythonを使用しています。 ここからダウンロードできます。.

さらに、Adafruitのすべてのライブラリをインストールして リブ フォルダを作成してください。(Feather RP2040のFlashには、これを可能にする十分な容量があります)。

これらのライブラリをダウンロードするには Adafruit CircuitPython Bundleはこちら.(ダウンロードしたのは adafruit-circuitpython-bundle-7.x-mpy-20211123.zip)

ノート: これらのライブラリをインストールするには、コンピュータにマウントされているCIRCUITPYの「ドライブ」にあるlibフォルダにコピーするだけです。もちろん、ライブラリだけをコピーして、サンプルやその他のものはコピーしないようにしてください。

Adafruitの製品を使う大きなメリットは、多くの人気チップを網羅した大量のサンプルが用意されていて、簡単に始められることです。SPIを使ってmicroSDカードを駆動したり、RTCを読み込んだり、BME680センサーから読み込んだりすることができます。

CircuitPythonでのI2Cのテスト

2つのデバイスを独立して駆動させたいので、以下のような設定をしています(この場合、たまたまアドレスが同じです)。

なお、当社のBME688用ブレイクアウトボードには、すでにSDAとSCLのプルアップが搭載されています。(SDAとSCLにはプルアップが必要です)。

注2:当社のBME688ブレークアウトボードには、アドレスを変更するオプションがありますので、このシナリオはデモンストレーションのためのものです。

両方のピンセットを順にドライブしてデバイスを検出するために、以下のコードを使用しています。

print("Scanning SCL / SDA")
i2c = busio.I2C(board.SCL, board.SDA)
#スキャン
i2c.try_lock()
print(i2c.scan())
i2c.unlock()
i2c.deinit()

print("A0 / A1のスキャン")
si2c = busio.I2C(board.A1, board.A0)
#スキャンを行う
si2c.try_lock()
print(si2c.scan())
si2c.unlock()

注:その i2c.deinit() がこの例の動作の鍵となります。(SCL / SDAとA0 / A1は、同じハードウェアI2Cペリフェラルを持っているからです。)

これで以下のように出力されるはずです。

スキャン SCL / SDA
[119]
スキャン A0 / A1
[119]

ここで、119番は 10進法で16進法の0x77 - これは、デフォルト状態のBME688ブレイクアウトボードのアドレスです。

両方のボードは、個々のスキャンで順次見られます。

問題は、それらを同時に使いたいということです。

Adafruit Feather RP2040で2つのI2Cバスを同時に動かす

CircuitPythonは どちらも ハードウェアコントローラ(SDA0/SCL0およびSDA1/SCL1)を使用しています。設定(どのコントローラを使用するか、ピンをどのようにミックスするか)は必要ありません。 ブシオ を提供しています。

しかし、どのピンを使用するかに注意する必要があります。ピンが提供するのは 一つ のバスがあり、たまたま相反するピンを選択してしまうと ValueErrorです。I2C ペリフェラルが使用中 .

Adafruit Feather RP2040ピンアウト

SCL1とSDA1を持つSCL / SDAや、SCL1とSDA1を持つA0 / A1など、「相反する」ピンを使用したい場合は、どちらかのポートをビットバンド化する必要があります。

ここでは、deinit()を呼び出さずに、このピン構成をスキャンする方法を紹介します。

インポートボード
インポートブジオ
インポート bitbangio
# https://circuitpython.readthedocs.io/en/latest/shared-bindings/bitbangio/index.html

print("SCL / SDAのスキャン - メインI2C")
i2c = busio.I2C(board.SCL, board.SDA)
#スキャン
i2c.try_lock()
print(i2c.scan())
i2c.unlock()
# ここでdeinitを呼ぶ必要はありません!
#i2c.deinit()

print("A0 / A1のスキャン - セカンダリI2C [bitbang!]")
si2c = bitbangio.I2C(board.A1, board.A0)
#スキャン
si2c.try_lock()
print(si2c.scan())
si2c.unlock()

# また、ここでdeinitを呼び出す必要はありません。
#i2c.deinit()

を使用しています。 ビットバンギオ を使用してセカンダリI2Cを駆動しています。私の場合、セカンダリI2Cは内部目的(ポートエクスパンダ用)に使用されており、より低いインターフェース速度でも問題ないと思われます。

注:ピンに配線されるI2Cペリフェラルをソフトウェアで選択することはできません。別のペリフェラルが必要な場合は、別のピンを使用する必要があります。

I2Cエラーのトラブルシューティング

ValueErrorです。I2C ペリフェラルが使用中

両方のポートにbusio.I2Cを使用している場合。すでに同じハードウェアI2Cペリフェラルを使用しているかどうか、また、ピンの割り当てを変更する必要があるかどうかを確認してください。

例えば、SCLとSDA、そしてA0とA1は、同じハードウェアI2Cペリフェラル(SCL1 / SDA1 - この記事のAdafruit Feather RP2040のピンアウト画像を参照)を共有しています。

同じピン設定を使いたい場合は、bitbangioを使って、ソフトウェアで制御するI2Cポートを追加で「作成」することができます。ただし、このソフトウェアI2Cポートの速度は低下し、CPU負荷も高くなります。

ランタイムエラーが発生しました。SDAまたはSCLにプルアップがありません。

以下のようなエラーが発生する場合

ランタイムエラーが発生しました。SDAまたはSCLにプルアップがありません。

の場合は、ボード上の3V3(3.3Vピン)と、SDAおよびSCLピンの間にプルアップ抵抗を置く必要があります。これらは、通常のI2C動作に必要なもので(デバイスは、通信するためにI2Cピンをプルダウンします。バスのデフォルト/アイドル状態はハイです)、Adafruit Feather RP2040には含まれていません。Adafruit Feather RP2040には搭載されていませんが、Adafruitの多くのペリフェラルや他社のペリフェラルには搭載されています(例えば、弊社のRP2040のように)。 BME688ブレイクアウトボード).

プルアップとは何かをご存知でない方のために説明しますと、これは基本的に、対象のピン(例えばSDA)と3.3Vの電源ピンの間に抵抗を設置することです。非常に正確である必要はありません。最初は10kΩの抵抗を使い、うまくいかない場合は1kΩの抵抗を使って「硬い」プルアップにするとよいでしょう。

タイムアウトエラー。クロックストレッチが長すぎる

対話したいチップの電源がきちんと入っているかどうかを確認します。

その他のメモ

参考文献、リソース、リンク、その他の情報

コメントを残す