TOPに戻る

センサ・シリーズ 温度①確度±0.1℃ TMP117 その2 アラートの設定

 使用環境
  • Raspberry Pi Raspberry Pi 4 Model B 2MB
  • OS Raspberry Pi OS(32ビット)5.4.51
  • Python3 3.7.3
  • smbusライブラリ 4.1-1
  • RPi.GPIOライブラリ 0.7.0
  • エディタ Mu

 前回、温度データを読み出しました。アラート機能を使うために、ブレークアウト・ボードから配線を増やします。
 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])))

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(temperature) kakunin3 = bus.read_i2c_block_data(tmp117_addr, TLow_LimitRegister, 2) print("TLow_LimitRegister is %s %s" % (hex(kakunin3[0]), hex(kakunin3[1]))) temp = kakunin3[0] <<8 | kakunin3[1] temperature = sign16(temp) * 0.0078125 print(temperature) 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)

 実行結果です。上限が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℃を超えた時の表示です。

連載 ラズパイ センサ・シリーズ

(1) 温度①確度±0.1℃ TMP117 その1 温度の読み出し

(2) 温度①確度±0.1℃ TMP117 その2 アラートの設定

(3) 温度①確度±0.1℃ TMP117 その3 アラートでLED点灯

(4) 温度①確度±0.1℃ TMP117 その4 アラートでリレー駆動