CircuitPython、Adafruit Feather RP2040、I2C
タイトルから想像できるように、この記事では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)
# a scan
i2c.try_lock()
print(i2c.scan())
i2c.unlock()
i2c.deinit()
print("Scanning A0 / A1")
si2c = busio.I2C(board.A1, board.A0)
# a scan
si2c.try_lock()
print(si2c.scan())
si2c.unlock()
注:その i2c.deinit() がこの例の動作の鍵となります。(SCL / SDAとA0 / A1は、同じハードウェアI2Cペリフェラルを持っているからです。)
これで以下のように出力されるはずです。
Scanning SCL / SDA
[119]
Scanning A0 / A1
[119]
ここで、119番は 10進法で16進法の0x77 - これは、デフォルト状態のBME688ブレイクアウトボードのアドレスです。
両方のボードは、個々のスキャンで順次見られます。
問題は、それらを同時に使いたいということです。
Adafruit Feather RP2040で2つのI2Cバスを同時に動かす
CircuitPythonは どちらも ハードウェアコントローラ(SDA0/SCL0およびSDA1/SCL1)を使用しています。設定(どのコントローラを使用するか、ピンをどのようにミックスするか)は必要ありません。 ブシオ を提供しています。
しかし、どのピンを使用するかに注意する必要があります。ピンが提供するのは 一つ のバスがあり、たまたま相反するピンを選択してしまうと ValueErrorです。I2C ペリフェラルが使用中 .
SCL1とSDA1を持つSCL / SDAや、SCL1とSDA1を持つA0 / A1など、「相反する」ピンを使用したい場合は、どちらかのポートをビットバンド化する必要があります。
ここでは、deinit()を呼び出さずに、このピン構成をスキャンする方法を紹介します。
import board
import busio
import bitbangio
# https://circuitpython.readthedocs.io/en/latest/shared-bindings/bitbangio/index.html
print("Scanning SCL / SDA - main I2C")
i2c = busio.I2C(board.SCL, board.SDA)
# a scan
i2c.try_lock()
print(i2c.scan())
i2c.unlock()
# no need to call deinit here!
#i2c.deinit()
print("Scanning A0 / A1 - secondary I2C [bitbang!]")
si2c = bitbangio.I2C(board.A1, board.A0)
# a scan
si2c.try_lock()
print(si2c.scan())
si2c.unlock()
# we also do not need to call deinit here
#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Ωの抵抗を使って「硬い」プルアップにするとよいでしょう。
タイムアウトエラー。クロックストレッチが長すぎる
対話したいチップの電源がきちんと入っているかどうかを確認します。
その他のメモ
- Adafruit Feather RP2040には、NeoPixel LEDが搭載されています。ネオピクセルは独自のプロトコルを使用また、I2Cは使用しません。
- のです。 Adafruit CircuitPython Community Bundle には、いくつかの追加ドライバーがあります。
- があります。 DebugI2C Helper
- のです。 サポートマトリックス をクリックすると、お使いのボードでサポートされているモジュールが表示されます(例:Adafruit Feather RP2040)。
参考文献、リソース、リンク、その他の情報
- Adafruit CircuitPython Bundle (CircuitPython用ライブラリ)
- CircuitPython Busioのドキュメント
- CircuitPythonボードのドキュメント
- RP2040のドキュメントにあるCircuitPython
- CircuitPython I2Cエッセンシャル
I2Cについてもっと知りたいですか?以下をご覧ください。 記事はこちら.
参考になる記事をありがとうございました2つ提案があります。
1) "no pull up found "エラーの原因の1つは(私がここにたどり着いた原因です)、ワイヤーが緩んでいるという間抜けなミスによって引き起こされることもあります。ステンマのコネクターは少し細いので、このようなことはよくあります。
2) サンプルコードが少し分かりにくいと思うのですが、2つのI2Cコントローラを使用する最も単純なケースから始めることができた/すべきであったと思います。
i2c = busio.I2C(board.SCL, board.SDA)
…
si2c = busio.I2C(board.A9, board.A6)
その後に使う方法も、もちろん有効で有用です
/ロブ
Robさん、丁寧なコメントありがとうございます。配線が緩んでいると、コンピュータ・サポートの世界では「電源が入っているのか?
この記事をありがとう。
Raspberry Pi Picoからの移行で、このようなものを探していました!
素晴らしい!