CircuitPythonのI2Cインターフェイスをカラーセンサーとつないでチェックしてみた
Cytron社のMaker Pi RP2040ボードのAdafruitのCircuitPythonのI2Cインターフェイスをカラーセンサーとつないでチェックしてみました。カラーセンサーはI2C インターフェースに対応したS11059-02DT(浜松ホトニクス)で,1コインで手に入ります。Groveコネクタと接続しました。今回のセンサーは3.3Vで動くので電源供給はそのまま使い,SCLとSDAのプルアップは必要なので4.7Kで行っています。ぎくしゃくとプログラミングして,何とか数値は出るようになりました。センサー側の光源がまだ無いのでNeoPixelLEDからRGBを当ててみました。[カラーセンサーS11059-02DT(浜松ホトニクス)のI2C関係のメモ]1.レジスタマップと初期設定項目 初期設定は積分の固定時間モードならコントロールレジスタ(0x00)の設定だけですみます。 またRGB(+赤外線)のデータはそれぞれ上位8bit・下位8bitの順に0x03レジスタから格納されています。2.初期設定とデータ読み出しの参考例 カラーセンサーの説明書に書かれているI2C関連のプログラム例です。慣れない言葉があるので,自分なりの覚書を追加しています。[CircuitPythonでのテストプログラムとI2C関係のメモ]1.CircuitPythonでのテストプログラム 上記のカラーセンサーのプログラム例を参考にして,そのままの流れでプログラムしてみました。2.CircuitPythonでI2Cを使うメモ1)必要なimport ・import board :ピン名などが設定されていて必須・import busio :I2Cクラスがあり必須2)busio.I2Cクラスの設定・参照:https://docs.circuitpython.org/en/latest/shared-bindings/busio/・ class busio.I2C(scl: microcontroller.Pin, sda: microcontroller.Pin, *, frequency: int = 100000, timeout: int = 255) 引数項目の途中のアスタリスク(*)から後はデフォルトで省略可能。変更するときはfrequency=400000のようにキーワードが必要。3)I2Cスタート時にはロックが必要・try_lock(self) → bool 返事がTrueになるまでロックをかける。4)書き込み後はストップコンディションが自動的に出る。 stop=false のような引数は無い・writeto(self, address: int, buffer: circuitpython_typing.ReadableBuffer, *, start: int = 0, end: int = sys.maxsize) → None 書き込み後には必ずストップコンディション(P)が出る。レジスタ指定->値の書き込みのように連続したデータの送信はbytearrayを使って一つのコマンド内に収める。(上記のプログラム例)---i2c.writeto(0x2A, bytearray([0x00,0x89]))i2c.writeto(0x2A, bytearray([0x00,0x09]))--- リピーテッド・スタートコンディション(Sr)はプログラムからは指定できないので,ストップを出す->新たにスタートを出す,で良いのでは???? CircuitPythonのプログラム例でも一部にstop=falseなどの記述がありますが,私のバージョンではエラーになります。5)読み込みはデータの先頭レジスタを指定し,連続して読み取るデータは配列に入れていく。(1)先頭レジスタの指定とデータ読み取りを別コマンドで行う方法・readfrom_into(self, address: int, buffer: circuitpython_typing.WriteableBuffer, *, start: int = 0, end: int = sys.maxsize) → None(上記のプログラムではコメントアウトしていますが,以下で動きます。)---i2c.writeto(0x2A, bytes([0x03]))result = bytearray(6)i2c.readfrom_into(0x2A, result)---- (2)先頭レジスタの指定とデータ読み取りを一つのコマンドで行う方法・writeto_then_readfrom(self, address: int, out_buffer: circuitpython_typing.ReadableBuffer, in_buffer: circuitpython_typing.WriteableBuffer, *, out_start: int = 0, out_end: int = sys.maxsize, in_start: int = 0, in_end: int = sys.maxsize) → Noneやたらと長そうですが,,アスタリスク以下は省略できるので,案外簡単です。---result = bytearray(6)i2c.writeto_then_readfrom(0x2A, bytes([0x03]), result)----6)I2C終了時はロックを解除しておく。・ unlock(self) → NoneI2Cでシンプルなデータを得るのであればライブラリの無いセンサーでもCircuitPythonでいけそうですね。ま,ライブラリがあって活用できれば,目的には早く辿り着けて,それはそれで大切な資源です。ただ,誰かがライブラリを作ってくれるのを口を開けてずっと待つわけにもいかないし,,手段をいろいろと考えてみるのも楽しいですしね。