センサ・シリーズ 温度①確度±0.1℃ TMP117 その3 アラートでLED点灯
使用環境
|
前回、温度センサTMP117のもつアラートの設定をしました。上限設定温度31℃を超えるとアラートをコンソールに表示しました。ここでは、GPIOピンにLEDをつないで、アラートの表示をします。
●LEDの電流制限抵抗
白色LEDの中身は青色LEDです。順方向電圧Vfは約3Vです。したがって、GPIOのHighの電圧が3.3Vとの電位差がほとんどありません。下記のように電流制限抵抗Rの値を計算します。
R = (3.3 - 3.0) / 5[mA] = 60[Ω] R = (3.3 - 3.0) / 1[mA] = 300[Ω] |
白色LEDが出始めた昔は、10~20mAの電流を流して光らせていましたが、最近の製品は1mA程度で明るく光ります。多くの小信号用LEDは、1mA以下で光り始め、電流を増やすと明るさが増し、10~20mA付近で明るさが増えなくなり、30~70mAを超えると破壊する製品が多いようです。
赤色や緑色のLEDのVfは当初1.7V付近でしたが、最近の製品では2.0V前後です。
R = (3.3 - 1.7) / 1[mA] = 1.6[kΩ] R = (3.3 - 1.7) / 3[mA] = 530[Ω] R = (3.3 - 2.0) / 1[mA] = 1.3[kΩ] R = (3.3 - 2.0) / 3[mA] = 430[Ω] |
アマゾンで購入したLEDには規格は不明です。これらの計算から、白色と青色は300Ω、赤色、緑色、黄色、オレンジ色は1kΩにしましょう。
ラズパイのGPIOが流せる電流は最大5mAぐらいといわれています。なので、少ない分にはマイコンにダメージを与えません。
●LEDの接続には2通りある
マイコンのI/Oピン=ディジタル入出力ポートは、電流を吐き出す(source)と電流を吸い込む(sink)の両方の機能があります。マイコンによっては、扱える電流が異なります。2~5mAのデバイスが多いようです。
どちらも、マイコン内部に電流が流れるので、少ないほうが発熱は少ないです。
●GPIOピンにLEDをつなぐ
上の図(b)ではGPIOのポートをHighにしたときに電流が流れ、LEDが点灯します。電流が流れだす接続が、次の図(c)です。GPIO17(11番)に抵抗1kと赤色LEDをつなぎます。
(c) GPIO17にLEDをつなぐ
図(b)のソース電流を流す回路を採用した上記の回路では、LEDを点灯するためのプログラムを書かなくてはなりません。
しかし、図(a)のシンク電流を流す回路採用し、図(d)のようにLEDをALRT信号につなげれば、プログラムは変更せずに済みます。ALRTは、アクティブLowでしたから。
LEDには1~2mAが流れます。ALRTのsink電流をデータシートで見ると、0.8Vまで電圧が上昇してもよいなら約25mAの電流を吸い込めます。こんなに電流を流すとデバイスが発熱するので、2mA程度ならよいかもしれません。
(d) GPIO4にLEDをつなぐ
最初に、図(d)の接続図通り実際にLEDを接続して、前回のプログラムを動かします。LEDの抵抗は、1番ではなく17番の3.3Vへつなぎました。
●LEDの用意
左のLEDは抵抗入りです。右は普通のLEDです。抵抗は1kΩ1/2Wです。もちろん電流は流れないので1/4WでもOKです。
リード線をはんだ付けします。足の短いほうのカソードは黒色のリード線です。この後、シュリンク・チューブ(スミチューブ)でむき出しの部分を覆い、ヒート・ガンで熱して密着させます。
●GPIO4にLEDをつないだ回路
前回の最後のプログラムでは、上限温度を超えると、ALRT信号がHigh->Lowになります。割り込みがかかり、コンソールに「at High temp」を表示します。図(d)の回路では、その時にLEDが点灯するはずです。
実際に動かすと、瞬間にぴかっと光ります。短すぎます。しかし、割り込み関数内は、基本はすぐに抜けるようにプログラムを作るのがセオリです。それは、割り込みはいつかかるかわからないし、複数の割り込み源が存在することもあるからです。
したがって、「at High temp」を表示した後、同じ割り込み処理関数内で、少しの時間待ってからアラート・フラグをクリアするわけにはいきません。
●GPIO17にLEDをつないだ回路
次に、図(c)を試します。上限温度を超えるとGPIO17を制御するプログラムを追加します。LEDはGPIO17がHighになると点灯します。
プログラムです。上限温度を超えていたらLEDはONになり、1秒間キープします。
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 High_Limit_temp_dec = 31 High_Limit_temp_list = [0x0f, 0x80] ALRT_pin = 4 # 7pin ALRT_LED_pin = 17 # 11pin def sign16(x): # 16ビットの2の補数形式。符号処理 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) # GPIOxxという名称のxxという数字を使う gpio.setup(ALRT_pin, gpio.IN, pull_up_down=gpio.PUD_UP) # 割り込みピンは入力に設定し、プルアップする gpio.add_event_detect(ALRT_pin, gpio.FALLING, callback=callback_alert, bouncetime=20) # 20msは割り込み禁止 gpio.setup(ALRT_LED_pin, gpio.OUT) # LED用ピンは出力に設定 gpio.output(ALRT_LED_pin, False) # set Low 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]) # 64回平均 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, High_Limit_temp_list) # 上限温度を設定 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: |
●割り込みとポーリング
アラート信号を受けて割り込みでコンソールに「at High temp」を表示しました。
forループの中で温度を測定して、31℃を超えていたら、LEDを点灯しました。これをポーリングと呼びます。
どちらも上限温度31度を超えたら動作します。今回の割り込みは、実測で100us(※1)ぐらいで動作しました。ポーリングはsleep(0.01)とすれば、20ms程度(※2)の間隔で温度を測定できます。
(※1)割り込み処理関数の先頭にGPIO21をONする処理を追加し、ALRTのGPIO4の両方をオシロスコープで観測し、差の時間を測定した。
(※2)実測。print文が入っているので10msより長めになった。
割り込みのメリットは、forループでいろいろなことをやっていても、リアルタイムで反応できるところです。ポーリングは、forループ内で時間がかかる処理があれば、31℃の上限を超えたことに気づくのにタイムラグが生じます。
今回の制御の対象が温度と、比較的変化の度合いが緩やかなので、割り込みを使う必要はないかもしれません。
なお、どちらの処理もprint文が入っていますが、処理時間がかかるので、デバッグが終わったらコメントアウトします。