I2Cセンサー取扱いのコツ
これまでにも触れてきましたが、Raspberry PiのGPIOにはI2Cと呼ばれるシリアル通信用端子が準備されており、I2C対応センサーの実装に利用可能です(I2CはArduino等でも対応しています)。
I2C温度センサーは、「TMP102(データシート)」や「ADT7410(データシート)」あたりが有名どころかと思います。今回は、以前からよく使っているADT7410を例にI2Cセンサーの取扱いについてご説明します。
データシートで「データを格納しているレジスタのバイト(ビット)長」と「換算式や分解能」を確認しましょう。
(ADT7410のデータシート P12)
読んでみると、ADT7410は標準13bit(2バイト)で、その際の分解能は1/16(0.0625)とあり、換算式も記載されています。さらに13bitの際には出力対応表(代表値)まで掲載されています。これらを書き下すと、次のようになります。
ここで、前回のPythonでのI2Cセンサーの値を読み出している部分の記述を見直しながら計算過程を追っていきましょう。
# 以下、センサーの値読み出し部分の抜粋
data = smbus.SMBus(self.channel).read_i2c_block_data(0x48, 0x00, 2)
temp = (data[0] << 8 | data[1]) >> 3
if(temp >= 4096):
temp -= 8192
value = temp * 0.0625
はじめにread_i2c_block_data(0x48, 0x00, 2)
関数の第3引数の2は読み出すデータバイト長を表しています。今回は13bitですので、2バイト必要です(3ビット余計ですが)。
次に、data[0] << 8
とdata[0] << 8 | data[1]
、さらに(data[0] << 8 | data[1]) >> 3
の部分を見て行きましょう。
日本語で書くと、「①data[0]
をまるっと8ビット左シフトして、②data[1]
とOR演算で繋いで、13ビットを取り出すために、③3ビット右シフトして不要部分を削る」ということになります。絵で描くと次のような感じです。
最後に、最上位ビットが1すなわち4096以上の場合には、負数となるので8192との差をとり、13bit設定時の分解能である1/16(0.0625)との積をとれば、データシートにあるように摂氏温度(真値)を得ることが出来ます。
いかがだったでしょうか?センサーのデータシートには換算式が示されることが多く一見分かった気になりますが、サンプルコードにおけるビット演算と分解能の計算部分のフォローが少なく、ここででつまずくことも少なくないのではないかと思います。これを押さえておけば、他のセンサーでも怖いもの無しですので、参考にして頂ければと思います。