MCP3426 を使ってみる
熱流を双方向で測定する必要が生じたので、どうやるか考えてみた。単純に考えると、熱抵抗体を挟んで両側の温度を測定して差分を取れば熱流が計算できることになるのだが、半導体温度センサーでそんなに正確な温度が読めるとも思えないし、何かいい方法が無いかと調べたら電子冷却用のペルチェ素子は温度差発電素子でもあるということに気が付いた。これの良いところは、熱流を双方向(正負電圧)で出力できるところで、出力電圧が0Vの時に熱流0であるところが良いのです。出力電圧の正負と大きさで、熱流方向と熱流量が測定できるのだが、この出力をADコンバータで受けようとすると負電圧の入力を取り扱わねばならないという問題が出てくる。
正負電圧を取り扱えるADC、つまり差動入力のADCが必要になる。調べたら、Microchip社がMCP3426なる差動入力でI2CインターフェースのADCがあることが解った。I2CだからArduinoやRaspberry Piでも簡単に接続できるのもありがたい。早速RS-Onlineで発注して試してみた。
データシートなどを参考にして、標準的な接続でやってみるとちゃんとI2Cデバイスとして認識されたので、後はアナログインターフェースだけである。ペルチェ素子は昔秋月電子で昔買った40mm×40mmの大型の物を使ってみるた。
次はソフト。MCP3426はデフォルトアドレスが0x68で、Raspberry Piに接続後 i2cdetecto -y 1 でそのアドレスが表示されます。
pi@raspberrypi:~/mcp3426 $ i2cdetect -y 1
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- 68 -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
pi@raspberrypi:~/mcp3426 $
さて、実際にペルチェ素子からの出力電圧を読む段取りです。いくつかのサンプルコードが公開されているので、それを参考にPythonでこんなプログラムを書いてテストしてみました。
import smbus
import time
# Get I2C bus
bus = smbus.SMBus(1)
MCP3426ADDR = 0x68
def mcp3426test(ch = 0, nbit = 12, debug = False):
# Send configuration command
sleeptime = 0.01
scale = 1.0
cmd = 0x10 + ch*32
if nbit == 14:
cmd += 0x04
sleeptime *= 4
scale /= 4
elif nbit == 16:
cmd += 0x08
sleeptime *= 16
scale /= 16
# Read data back from 0x00(0), 2 bytes
# data[0]: MSB, data[1]: LSB
data = bus.read_i2c_block_data(MCP3426ADDR, 0x00, 2)
debug and print("raw data:",data)
# Convert the data to signed integer
offset = 0
if data[0] >= 128:
offset = -65536 # negative voltage
adc = data[0] * 256 + data[1] + offset
debug and print ("ch:", ch, ", nbit:", nbit, ", value:", adc)
return scale * adc
if __name__ == '__main__':
while True:
print("adc value:", mcp3426test(nbit=14, ch=0), "mv")
time.sleep(10.0)
MCP3426は変換時間が長く、12bitで毎秒240回、16bitでは毎秒16回しか変換できないのです。簡単なフリーランモードではコマンドを送出してからかなり待たないと値を読み出せないのです。ワンショットモードでRDY信号を待っても良いのだが、とりあえずはtime.sleep(sleeptime) で変換時間分待つ必要があります。12bitで5msくらい、16bitなら80ms以上になります
そんなこんなで、実際にテストすると14bit精度でも0V入力に対して1LSB以内の精度を出してきます。これは差動入力のおかげで、0V付近の高精度変換はいろんな場面で役立つでしょう。実際にやってみると、差動入力AD変換器のノウハウは色々と役立ちそうです。