(Last update:09/10/05)
製作の経緯:
PIC16F88 にもだいぶ慣れてきたので、実用品シリーズとして以前から構想を暖めていた温度計を製作することに。
回路説明、設計時の考慮点等:
PIC を使った温度計の製作例は巷に山ほどあるので(汗)、ここはオリジナリティを出したいところ。光モノ好きな管理人は、以前製作した2色時計が気に入っているので、このアイデアを発展(?)させ、温度を快適度に応じて
3色で表示することにした。
具体的には、次のように表示する。
5℃未満 | L表示 |
5-18℃ | 温度表示 |
19-24℃ | 温度表示 |
25-47℃ | 温度表示 |
48℃以上 | H表示 |
50℃以上? | Er表示 |
桁数は PIC16F88 のポート数から 2桁表示とする。この場合精度はさほど必要ないので
A/D 変換は扱いやすい 8 bit 変換で十分。ただし 10bit 変換よりも分解能が悪くなるので、センサー出力を
A/D 変換基準電圧付近まで増幅してなるべく誤差を抑える方向で。
温度センサーはリニア出力で扱いやすい LM35DZ で決まり。温度は 50 ℃まで測れれば室内用としては十分であるから、オペアンプのゲインを
9.8倍(詳細理由は後述)とする。LM35DZ の出力は 10mV/℃なので、オペアンプの入力オフセット電圧はそれほど神経質になる必要はなく、安価な
LM358(入力オフセット 3mV)でも十分なのだが、LM358 は H側がフルスイングしないため、8bit
A/D 変換ではそれなりの誤差が予想される。そこで今回は H側フルスイング可能な
LMV358 を採用。LMV358 の方が入力オフセットも 1.7mVと低く、その点でも好都合。
さて肝心の温度測定だが、オペアンプのゲインを 9.8倍とする 50℃時の LM35DZ
の出力は 4.9V まで増幅される。A/D 変換の基準電圧を 5V とすると、4.9V は
A/D 変換値 250カウントとなるから、1℃ = 5 カウントとなり、A/D 変換値を
5で割れば温度が求まる。即ち、オペアンプのゲインを 9.8倍に調整すれば、整数演算だけで温度変換が済むのでアセンブラで実装するには好都合となる。
ちなみに当初はオペアンプ内蔵の PIC16F785 で設計していたのだが、入力オフセットが
5mV とやや大きいのはまだいいとしても、H側がフルスイングせず、かつポートの制約も案外多いことが発覚。精度面、およびソフトウエアが面倒になることから今回は見送りとした。せめてフルスイングしてくれれば安上がりかつ小型に仕上がるのだが・・・
また単色表示の場合は 7セグ LED を PIC のポートに直結するところだが、今回は橙色表示する際に赤と緑の両方の
LED が光る点に注意が必要。PIC のポートあたりの最大許容電流は 25mA であるから、赤と緑に各
12mA 程度までしか流せない。この程度の電流量だとスタティック点灯には十分だが、ダイナミック点灯では輝度が足りない可能性が高い。
いずれにしても現物で光り具合を確認しながら電流量を決められるようトランジスタで電流増幅し、PIC
が壊れないようにしておく。この部分は 2SC1815 を使ってディスクリートで作ってもいいのだが、配線の手間を考えてお手軽なトランジスタアレイを使うことにした。
製作のポイント:
今回もっとも難物だったのが2色の7セグLED。ネット通販でも扱っているところは極めて少なく、また@\800前後と非常に高価。さりとて秋葉原でも置いてあるパーツショップがなかなか見つからず、鈴商でようやくスタンレー
NARG161 を発見して購入することができた(@\250)。ところが、喜び勇んで購入し、帰宅してからピンのピッチが
2mm であることに気づく(爆)。しかも横方向は 2mm ピッチだが縦方向は 2mm
ピッチではないという変態ぶり(泣)。そこでブレッドボードでの動作確認には別の単色7セグ
LED で代用して開発を行うハメに。また変換基板は高価なので、最終的には写真のように基板に
LED をエポキシ系接着剤で貼り付けて空中配線した。
LED のダイナミック点灯について:
ネットや文献で調べみると、LED のダイナミック点灯は「桁単位の表示制御」(各
7セグ LED 内はスタティック表示)とし、一定時間毎に割り込み処理内で表示制御をしている例が多いようだ。もちろん
LED が単色の場合はこの方法が便利なのだが、2 色 LED の場合は何かと問題が多い。
例えば「8」を表示させると全セグメントが同時点灯するわけだが、仮に各セグメントに
20mA 流したとすると、単色の場合は 140mA で済むところ、2 色LEDの場合は、赤と緑の両方が発光する橙色時にはその倍の
280mA となり、かなりの電気食いとなる。
また電流制限抵抗を赤と緑とで共有するため、8を表示した場合(点灯セグメントが多い)場合と、1を表示した場合(点灯セグメントが少ない)場合で輝度に差が出てしまう、というかなり致命的な問題も発生する。
実際、今回の温度計も当初は桁単位でのダイナミック制御を行なっていたのだが、「1」の場合にはかなり明るくなってしまうため、簡易 PWM で見かけの輝度を下げる、といった対処を試みたのだが、結局は表示方式を根本的に改め、セグメント単位でダイナミック点灯を行なう「完全ダイナミック点灯」式に変更した。この場合、発光するのは常に 1 セグメントだけなので、原理的に輝度差は生じないし、橙色時でも消費電流は 20 x 2 = 40mA と圧倒的に省エネ。3端子レギュレーターは放熱不要の小型のものが使えるし、電流制限抵抗もセグメント毎に設ける必要はなく、アノードコモン側に 1本用意すれば済む。また桁制御のトランジスタも不要となるため、かなり部品点数も減らせる。(今回はある程度作ってから仕様変更したため、抵抗も桁制御トランジスタも残ったままだが・・・爆)
ただしこの「完全ダイナミック表示」では点灯するセグメント数によって表示に必要な時間が変化する点に注意。2桁表示の場合、表示セグメント数が最も少ない「11」表示では
4セグメント、最も表示セグメントが多い「88」表示では 14 セグメントとなり、表示に必要な時間は3倍以上も異なる。これを一定時間毎の割り込み処理で制御するとセグメント数が少ない場合に表示がちらついてしまうため、基本的に割り込みは使えない。そのためメインルーチン側で常に表示を繰り返し、非表示時間が極力出ないようにしている。
今回の失敗:
TRISA レジスタをちゃんと設定したにもかかわらず RA1 が出力ポートにならず、1日悩む。季節柄、静電気で
PIC を壊したかとも疑ったが(汗)、MPLAB の標準デバッガで動作をシミュレートしても
RA1 が出力にならないことからソフト的な問題であることを確認。結局ステップ実行しつつレジスタをトレースしてようやく
ANSEL レジスタで RA1 をデジタルポートに設定し忘れていたことに気づく(爆)。ってか
TRISA レジスタでポートを出力に設定しちゃえば普通 ANSEL レジスタの値は動作に無関係になると思うでしょ?(負け惜しみ)
また試作当初は、上桁スタティック表示→切り替え→下桁スタティック表示という「桁単位」のダイナミック点灯にしていたため、
(1) 「1」を橙色で表示した場合のみ緑 LED と赤 LED の輝度比が変わってしまい、表示が赤っぽくなってしまう
(2) 最大80mA 程度流れるため、3端子レギュレータや集合抵抗からの発熱が温度センサーに影響を与える
という問題が発生した。(1) に関しては、橙色で「1」表示の時のみ PWM 制御で赤の見かけの輝度を下げることで一時的に対処したのだが、結局最後は全セグメントをダイナミック表示することで根本解決した。またこれにより消費電流が下がったため
(2) の不具合も解消した。
注意点、改良案など:
何℃から色が変わるか、各自の快適度に合わせてソースの定数部分を適宜変更していただけると宜しいかと
^^; あるいは RA3 ポートを使って、マニュアル操作で夏用と冬用の色設定を変更できるようにするとか、測定温度の平均値に基づいて色設定を自動変更させる等、アイデアはいくらでも膨らむ。
今回は LED の実際の輝度を現物合わせで行ったため、輝度調整をし易いよう集合抵抗とトランジスタアレイを使用したのだが、これらに案外実装面積を取られてしまった。また最終的な消費電力が不明だったため余裕を持った部品選定をしたわけだが、最終的な消費電流は最大
40mA 程度となった。上記のとおり、PIC の 1 ポートあたりの最大電流量の制約上、残念ながらトランジスタ・アレイは省略不可となったが、3端子レギュレーターは
78L05 に、2SA854 も 2SA1015 で十分代用できるようになった。またオペアンプ
LMV358 が入手できない場合は LMC662 のような単電源フルスイング・オペアンプで代用可能である(ピッチ変換が不要なぶん
LMC662 の方が作りやすいかも)。
なお RA3 ポートを空けてあるので、湿度センサーを繋ぐなんてのも実用的だし、RA3
を出力ポートにして、設定温度以上になったらアラームを鳴らすとか、トライアックで
AC 機器を制御するのも一興。
なお、温度測定は TMR1 で 240ms 毎に割り込みを発生させ、割り込み10回毎に測定(=2.4秒毎測定)している。温度の変わり目での値のフラつきが気になる場合はサンプリング周期を長めにしたり、あるいは数回の測定値の平均値を取って値を安定化させるといった工夫が考えられる。
また TMR1 を TMR0 使用に変更してポートを3つ空け、3桁化するのも実用的。ただし
8 bit A/D 変換のままでは解像度が 0.2℃程度になるため、10bit A/D 変換〜
16bit 演算する必要がある。まぁ、勉強の題材としてはもってこいですな ^^;
プログラム Ver 2.4 (2009/08/17) | |
ソース(.asm) | HEX ファイル(.HEX) |
今回学んだこと:
・2色 7セグ LED のダイナミック点灯法(全セグメントでダイナミック点灯)
・8bit 割り算
2009/8/25 追記:
CQ出版社・エレキジャック誌 No.14 (2009/8/25
号) に掲載 (^^)v
部品表
部品 | 部品番号 | 規格番号 | 数量 | 入手先、備考等 |
2色7セグメント LED (アノードコモン) |
LED1, LED2 | スタンレー NARG161 | 2 | 秋葉原・鈴商 |
PIC マイコン | U1 | PIC16F88 | 1 | 秋月電子 |
単電源・フルスイング・オペアンプ | U2 | LMV358 または LMC662 | 1 | 秋月電子 |
トランジスタ・アレイ | U3 | 東芝 TD62003APG | 1 | 秋月電子 |
温度センサー | U4 | ナショナル・セミコンダクター LM35DZ | 1 | 秋月電子 |
5V 出力 3端子レギュレーター | U5 | 78L05 | 1 | 秋月電子 |
トランジスタ | Tr1〜Tr4 | 2SA1015 | 4 | 秋月電子 |
積層セラミックコンデンサ | C1〜C3 | 0.1μF 25V | 3 | 秋月電子 |
積層セラミック又は電解コンデンサ | C4 | 100μF 6.3V以上 | 1 | 秋月電子、100〜470μF 6.3V 以上ならよい |
積層セラミック又は電解コンデンサ | C5, C6 | 1.5μF 25V | 2 | 秋月電子、1〜10μF 16V 以上ならよい |
抵抗 | R1〜R7 | 100Ω | 1 | 秋月電子、集合抵抗にすると便利 |
抵抗 | R8 | 47KΩ | 1 | 秋月電子、10K〜47KΩならよい |
抵抗 | R9,R10 | 1KΩ | 2 | 秋月電子 |
抵抗 | R11 | 6.8KΩ | 1 | 秋月電子、4.7K〜8.2KΩならよい |
抵抗 | R12, R13 | 51Ω | 2 | 秋月電子 |
抵抗 | R14〜R17 | 2.2KΩ | 4 | 秋月電子、1K〜10KΩならよい |
可変抵抗 | VR1 | 10KΩ | 1 | 秋月電子 |
ICソケット(オペアンプ用) | 8ピン用 | 1 | 秋月電子 | |
ICソケット(トランジスタアレイ用) | 16ピン用 | 1 | 秋月電子 | |
ICソケット(PIC用) | 18ピン用 | 1 | 秋月電子 | |
電源ジャック | AC アダプタのプラグに合うもの | 1 | ||
AC アダプタ | 8V 以上 100mA 程度 | 1 |