Raspberry Pi PicoでPythonのお勉強 ~3~
BME280モジュールの中身を見ていこうと思いますが、今回使ったモジュールのソースは下記のページにあります。
今回はI2C制御とそれに関連する内容だけを調べるつもりなので、Pythonのクラスに関することはここでは触れません。
最初に登場するI2Cでのアクセスは75行目になります。
dig_88_a1 = self.i2c.readfrom_mem(self.address, 0x88, 26)
クラス内なので頭に"self."が付いていますが、"i2c.readfrom_mem"がI2Cリードの部分になります。なので、これをMicroPython librariesで調べると
となっていて、self.addressがBME280のI2Cスレーブアドレス、0x88がレジスタアドレスでそこから26bytesのデータを読み出すということになります。そして読み出したものはbytes型になるので、それを変数dig_88_a1に代入するという処理になります。
BME280のデータシートを見ると0x88からTrimming parameterのデータが始まるようなので、温度や気圧の計算に必要なデータを読み出しているということになりますか。
BME280はバーストリードに対応しているらしいので、読み出すレジスタの先頭アドレスだけ送れば勝手にレジスタアドレスをインクリメントしたデータを出してくれるようです。でも全てのデバイスがバーストリードに対応しているわけではないと思うので、I2C.readfrom_memではレジスタアドレスを26回変えながらリードしているのですかね?I2Cの波形を見れば分かりますが、今回はそこまで調べるのはやめておきます。
76行目も同様にI2C.readfrom_memが出てきますが、今回興味深かったのは77行目の処理でした。
self.dig_T1, self.dig_T2, self.dig_T3, self.dig_P1, \
self.dig_P2, self.dig_P3, self.dig_P4, self.dig_P5, \
self.dig_P6, self.dig_P7, self.dig_P8, self.dig_P9, \
_, self.dig_H1 = unpack("<HhhHhhhhhhhhBB", dig_88_a1)
この"unpack"という関数が、dig_88_a1のデータを分割してイコールの左側にある変数にそれぞれ値を代入しているということはすぐに分かりましたが、"<HhhHhhhhhhhhBB"という記述が謎でした。なので調べてみると`struct` -- pack and unpack primitive data typesというページに謎の記述の意味が書いてありました。
dig_88_a1は26bytesのbytes型なので先頭から22222222222211バイトづつ分割しそれぞれをリトルエンディアンのデータとして指定した型のデータに変換するという処理をしているようです。C言語だとchar型の配列を用意して配列のどの位置のデータをどの順番で結合してどのデータ型にするかを個々の変数ごとに書かなければならないと思いますが、MicroPythonではこんな風に書けてしまうのですね。
ちなみにunpack関数はstructというライブラリに含まれているのですが、37行目ではustructというライブラリになっていますね。最新のMicroPythonではustructというライブラリは存在しないので、以前はustructという名前だったのかもしれません。structライブラリは、バイト列をパックされたバイナリデータとして解釈するという説明があるので、組み込み用途でPythonを使う時にはかなりお世話になるのかもしれない?と思いました。