Raspberry Pi(Linux、Python)で温度測定(1) MCP9808
■Adaflut MCP9808(購入はスイッチサイエンス)
MCP9808はマイクロチップの温度センサです。I2Cインターフェースでデータを読み取ります。
電源電圧は2.7~5.5Vなので、ラズパイにそのままつなげられます。測定温度範囲は-20~100℃です。データは最小0.0625℃で読み出せますが、確度は ±0.25℃です。
●MCP9808ボードのピン配置
ラズパイとの接続は下記の4本です。
ピン名称 | 備考 |
---|---|
Vdd | +3.3Vへ |
Gnd | グラウンド |
SCL | I2C。10kΩでプルアップ済み |
SDA | I2C。10kΩでプルアップ済み |
Alert | 温度の読み出しでは使わない |
アドレス A0 | 下記のアドレス選択を参照 |
アドレス A1 | 下記のアドレス選択を参照 |
アドレス A2 | 下記のアドレス選択を参照 |
●スレーブのアドレス
アドレスを変更するために、A2、A1、A0の3ピンがボード上にあります。
アドレス | 値 |
---|---|
A6 | 0 固定 |
A5 | 0 固定 |
A4 | 1 固定 |
A3 | 1 固定 |
A2 | 外部ピンで設定。解放で0 |
A1 | 外部ピンで設定。解放で0 |
A0 | 外部ピンで設定。解放で0 |
A2、A1、A0に何もつながないとスレーブ・アドレスは0x18です。変更したいときは、Vddにつなぎます。
ピン名 | |||||||
---|---|---|---|---|---|---|---|
A2 | Vdd | Vdd | Vdd | - | - | - | Vdd |
A1 | - | Vdd | Vdd | Vdd | Vdd | - | - |
A0 | - | - | Vdd | - | Vdd | Vdd | Vdd |
アドレス | 0x1c | 0x1e | 0x1f | 0x1a | 0x1b | 0x19 | 0x1d |
●温度レジスタは0x05
最上位にある符号は、負のとき1、0℃以上では0です。0、1、13、14、15のビットは読み出すと0です。
(※)最小の1と0ビットにはデータが入っていますが利用していません。
●ラズパイとの接続
MCP9808とLCDモジュールAQM1602AをI2Cバスにつなぎます。AQM1602Aはこの記事のように、そのままつないでは認識されないので、バス・リピータPCA9515ADを挟みます。
●プログラミング
i2cdetectで接続を確認します。0x18にいます。
(1) 温度レジスタをワード(16ビット)単位で読み出すと、2バイトが逆転しているので、入れ替える
t=i2c.read_word_data(addr03,0x05) #temp reg tswap= swap16(int(hex(t),16)) |
<バイト・スワップ>
def swap16(x): return (((x << 8) & 0xFF00) | ((x >> 8) & 0x00FF)) |
(2) 正の温度であれば、符号は0なのでそのまま扱えばよいが、ビット12が’1’つまり10進で4096以上ならば、0x0fffでマスクをして符号を取り去ってから換算。下2桁にデータがないので2ビット右シフトをするために16で割る
temp = (int(hex(tswap),16) & 0x0fff) / 16.0 |
(3) 四捨五入する
temp = round(temp,1) |
(4) 文字列tempをLCDに表示する
mojilist=[] for moji in str(temp): mojilist.append(ord(moji)) i2c.write_i2c_block_data(addr02, _data, mojilist) time.sleep(0.2) |
(5) 温度に続けて℃を表示
i2c.write_byte_data(addr02, _data, 0xdf) time.sleep(0.2) i2c.write_byte_data(addr02, _data, 0x43) |
プログラム全体です。
#!usr/bin/env python i2c = smbus.SMBus(1) # 1 is bus number # LCD AQM1602 def swap16(x): #main t=i2c.read_word_data(addr03,0x05) #temp reg mojilist=[] |
実行したようすです。