センサ・シリーズ 温度①確度±0.1℃ TMP117 その2 アラートの設定
使用環境
|
前回、温度データを読み出しました。アラート機能を使うために、ブレークアウト・ボードから配線を増やします。
ALRT端子にジャンパ・ケーブルをはんだ付けし、7番(GPIO4)ピンに接続しました。
TMP117 | ラズパイ |
---|---|
SDA | 3番 |
SCL | 5番 |
ALRT | 7番 GPIO4 |
GND | 9番 |
V+ | 1番 |
●アラートの機能
データシートの説明によると、ConfigurationレジスタのT/nAビットが0に設定されている場合、デバイスはアラート・モードになります。このモードでは、デバイスはすべての変換の終了時の変換結果を、下限レジスタおよび上限レジスタの値と比較します。温度結果が上限レジスタの値を超えると、構成レジスタのHIGH_Alertステータス・フラグが設定されます。一方、温度結果が下限レジスタの値よりも低い場合は、構成レジスタのLOW_Alertステータス・フラグが設定されます。
ConfigurationレジスタからI2Cの読み取りを実行すると、アラート・モードでステータス・フラグをクリアできます。
さいしょに、THigh_LimitレジスタとTHigh_Limitレジスタの初期値を確認します。データシートには、それぞれ、パワー・オン・リセット時に0x8000、0x6000が設定されていると書かれています。
import smbus bus = smbus.SMBus(1) tmp117_addr = 0x48 TemperatureRegister = 0x00 ConfigurationRegister = 0x01 THigh_LimitRegister = 0x02 TLow_LimitRegister = 0x03 def sign16(x): return (-(x & 0b1000000000000000) | (x & 0b0111111111111111)) bus.write_i2c_block_data(tmp117_addr, ConfigurationRegister, [0x04, 0x60]) kakunin1 = bus.read_i2c_block_data(tmp117_addr, ConfigurationRegister, 2) print("ConfigurationRegister is %s %s" % (hex(kakunin1[0]), hex(kakunin1[1]))) |
実行結果です。上限が192℃、下限が-256℃ですね。
●アラートを有効に
まず、上限の温度を実験でたやすく得られる31℃(0x0f80)に設定します。そして、アラート・モードにしますが、Configurationレジスタを見ると、すでに初期値がアラート・モードになっています。上限が192℃、下限が-256℃に設定されているけど、通常では、ぜったいにアラートが発生しないですね。
データシートによれば、ALRTピンはアクティブLow(通常はHighで、上限を超えるとLowになる)、ALRTピンはアラート・フラグを反映する設定です。HIGH_Alertフラグは、Configurationレジスタを読むことでクリアされるとあります。
したがって、上限31℃を超えるとALRTピンはHigh->Lowになり、Configurationレジスタを読んでクリア(リセット)すればよいことがわかります。
●上限を超えたことを把握
上限の設定値31℃を超えると、ALRTピンがLowになります。ALRTピンはラズパイのGPIO4(7番)につながっているので、このピンを監視します。アクティブLowなので、プルアップしてアラートが出るまでHigh状態にしておき、HighからLowになったところを検知します。
RPi.GPIOライブラリは、GPIOピンを個別に入力/出力に設定したり、ON/OFFしたり、PWM信号を出力するときに使われます。
gpio.setup(ALRT_pin, gpio.IN, pull_up_down=gpio.PUD_UP)
「ALRT_pin=GPIO4=7番ピン<-ALRTピンがつながっている」を「IN」 =入力に、「pull_up_down=gpio.PUD_UP」=プルアップ抵抗を有効にする設定です。マイコン内部に50kΩぐらいのプルアップ抵抗が入っているので、それを有効にします。したがって信号が入ってこないときは、High状態です。
割り込みをサポートしています。割り込みを使うには、
- 割り込みが発生したら実行する関数
- 割り込みの条件を指定した記述
の二つが必要です。
callback_alert(ALRT_pin)関数が、割り込みが発生したときに実行される内容を記述しています。画面に「at High temp」と表示し、Configurationレジスタを読みに行って、アラート・フラグをクリアします。
gpio.add_event_detect(ALRT_pin, gpio.FALLING, callback=callback_alert, bouncetime=200)
割り込みの条件を記述しています。ALRT_pinは監視するピンの指定です。FALLINGは信号の立ち下がりを意味します。callback=callback_alertは、割り込みが発生したら呼び出す関数をしてします。bouncetime=200は、スイッチのON/OFF時に発生するチャタリングの猶予時間です。ここではほとんどチャタリングは起こらないですが、記述をしています。
Configurationレジスタに[0x00, 0x02]を書き込んで、ソフト・リセットを実行しました。1秒待ってConfigurationレジスタ読み出して、設定内容を確認します。
Configurationレジスタに[0x02, 0x60]を書き込んで、64回の平均(1秒)に設定します。
bus.write_i2c_block_data(tmp117_addr, THigh_LimitRegister, [0x0f, 0x80])
0x0f80=31℃をTHigh_Limitレジスタに書き込み、その値を読み出して確認します。
5秒経過した以降、永久ループで温度を表示します。中断(終了)はCtrl-Cです。RPi.GPIOライブラリは、Ctrl-Cで中断すると次回の開始時にエラーになるので、gpio.cleanup()を実行します。
import RPi.GPIO as gpio from time import sleep import smbus bus = smbus.SMBus(1) tmp117_addr = 0x48 TemperatureRegister = 0x00 ConfigurationRegister = 0x01 THigh_LimitRegister = 0x02 ALRT_pin = 4 # 7pin def sign16(x): return (-(x & 0b1000000000000000) | (x & 0b0111111111111111)) def callback_alert(ALRT_pin): print('at High temp') bus.read_i2c_block_data(tmp117_addr, ConfigurationRegister, 2) # clear alert flag gpio.setmode(gpio.BCM) gpio.setup(ALRT_pin, gpio.IN, pull_up_down=gpio.PUD_UP) gpio.add_event_detect(ALRT_pin, gpio.FALLING, callback=callback_alert, bouncetime=200) print('reset') bus.write_i2c_block_data(tmp117_addr, ConfigurationRegister, [0x00, 0x02]) # soft reset sleep(1) kakunin0 = bus.read_i2c_block_data(tmp117_addr, ConfigurationRegister, 2) print("ConfigurationRegister is %s %s" % (bin(kakunin0[0]), bin(kakunin0[1]))) bus.write_i2c_block_data(tmp117_addr, ConfigurationRegister, [0x02, 0x60]) kakunin1 = bus.read_i2c_block_data(tmp117_addr, ConfigurationRegister, 2) print("ConfigurationRegister is %s %s" % (bin(kakunin1[0]), bin(kakunin1[1]))) sleep(0.5) bus.write_i2c_block_data(tmp117_addr, THigh_LimitRegister, [0x0f, 0x80]) kakunin2 = bus.read_i2c_block_data(tmp117_addr, THigh_LimitRegister, 2) print("THigh_LimitRegister is %s %s" % (hex(kakunin2[0]), hex(kakunin2[1]))) temp = kakunin2[0] <<8 | kakunin2[1] temperature = sign16(temp) * 0.0078125 print(' setting High temp Limit %s' % temperature) sleep(5) try: while 1: data = bus.read_i2c_block_data(tmp117_addr , TemperatureRegister, 2) # tempの読み出し temp = data[0] <<8 | data[1] temperature = sign16(temp) * 0.0078125 print("\nTemp is %.5f `C" % temperature) #kakunin1 = bus.read_i2c_block_data(tmp117_addr, ConfigurationRegister, 2) #print("ConfigurationRegister is %s %s" % (hex(kakunin1[0]), hex(kakunin1[1]))) sleep(1) except KeyboardInterrupt: print('\n end') gpio.cleanup() |
実行結果です。
31℃を超えた時の表示です。