その後3年くらい頭の片隅にあったのですが、今まで使っていた温度センサー LM35DZ が腐食で使用不可能になったことが、今回、DS1820 に温度センサーをリプレースしようと考えたきっかけです。
これが2003年11月。
RS232C では遠隔で温度センサーの情報を取得できないので、LANによる情報取得を考えたときに手っ取り早いのが、PICNICという訳です。
PICNICを何かに使ってみたかったので、丁度良い題材という訳で、今回の開発作業となった訳です。
このたぐいのノウハウは、先人達が沢山提供しているだろう、と思って(思い込んで)いたのですが、
なかなかトラブル対処に明るい情報が得られません。
結果的にまともに動作するまで、3週間を費やしました。
ここでは、弊社で現在運用している DS1820 温度センサーの開発記録を紹介します。
(温度センサーの格納方法はこちらのページへ → 温度センサーの格納実験
−55℃ 〜 +125℃の範囲が計測可能で、測定データは、1Wire-Bus という伝送方式で、ディジタル信号で出力されます。その為、アナログ出力方式の LM35DZ 等のように回路の実装が直接精度に影響する、ということはありません。
1Wire-Bus の制御さえ上手くできれば、測定誤差が蓄積されるようなことはないのです。
測定誤差は規格上、最大±0.5℃ですが、実際は±0.1℃程度のようです。
DS1820 | : | 従来のDS1820。分解能 1/80℃。現在製造中止。 |
DS18S20 | : | 従来のDS1820互換。分解能 1/16℃。TO-92 パッケージ。 |
DS18B20 | : | 9bit - 12bit 分解能可変設定可能/直読版。分解能 max 1/16℃。TO-92 パッケージ。 |
DS1820 を 2つ接続できるようにして、室内と外気の温度を別々に計測できるようにしています。
回路的には最大8個まで接続できます。
1Wire-BUS の制御は、PIC16F84A によるプログラム制御です。
1Wire-BUS は、オープンドレイン出力で且つピンの論理レベルをラッチを介さないで直接読み取れるような I/O回路が必要ですが、PIC16F84A の RA4 がその用件を満たします。また、アナログスイッチの ON 抵抗が気になるところですが、入力インピーダンスが高いためか、支障は無いようです。
PICNIC(旧PICNIC です[2014/07/10 補足]) 側で RB4-RB7 を出力、RB0-RB3 を入力としてデフォルトで設定しているので、アプリケーションプログラムの手間を省くために、その条件を前提にして PIC16F84A をプログラムします。
というよりも、PICNIC はこの構成を意図して、PICNIC から制御する回路の規模が最小になるようになっています。
PIC16F84A の機能のひとつにありますが、RB4-RB7 の変化で割り込みをかけることが出来るからです。
コネクタからDS1820までの線路長は、25mまでこちらで動作確認はしました。
・プルアップ抵抗は、DS1820に直接半田づけする
3線式(電源を外部供給する)の場合に有効です。
・DS1820と接続する線材は、カテゴリ5ツイストペアケーブルが確実
軽視しがちな部分ですが、侮れません。撚り対線であればいいのですが、日本ではカテゴリ5LANケーブル
の撚り対線を流用するのが最も入手が容易で安価で確実です。
・アプリケーションノートは情報が古いのが結構ある
このサイトで、DS1820に関係するアプリケーションノートの一覧が出てきます → ここ
しかし、記述内容が現状に合っていないものなどがあります。以下はこちらで気づいた注意点です。
APP 148 高信頼性1-Wireネットワークのガイドライン
— ハードウェア構成は、このアプリケーションノートが信頼性あります。1Wire-BUS のタイミングは参考になりません。
APP 155 1-Wireソフトウェアリソースガイド
— PIC マイコンには役に立ちません。
APP 159 iButton®アプリケーションで堅牢な1-Wire®通信を実現するためのソフトウェア手法
— 1-WireBUS の制御方法はこのアプリケーションノートに書かれている内容が一番確実なようです。ちょっと判り難いです。
— 当方でも、このアプリケーションノートに書かれている内容でやっと動作させることができました。
・高分解能温度計測結果の算出方法(DS1820/DS18S20 のみ)
DS18B20 は分解能が可変できるため、この項目は役に立ちません。
データシートには、高分解能の温度計測結果の算出方法は、下記のように定められています。
計測温度 = TEMP_READ - 0.25 + (COUNT_PER_C - COUNT_REMAIN )/ COUNT_PER_C
そして、COUNT_PER_C は、「ハードウェア的な配線によって、10H に固定されている」と記述があります。
しかし、ここが落とし穴です。DS18S20 は確かに、10H なのですが、当方で用いた DS1820 の COUNT_PER_C は、
実際に読み出すと 50H でした。DS1820 では、固定値が規定されていないようなのです。
「ハードウェア的な配線によって」という言葉に惑わされないようにしましょう。
この値は「製造ロット・計測環境によって変る場合がある」のです。
手抜きをして、固定値を使わないようにしてください。
次に具体的な算出方法です。データシートだけでは、正直なところよく理解できません。
しかし有り難いことに以下のサイトに具体的な説明が載っていました。(英語です) Thanks!!
DS1820 Temperature Sensor High-resolution Readout Demo 〔リンク切れ確認 2014/07/10〕
英語が苦手な方々のため(=自分だ)に、この部分の要点を和訳しました。例示も同じにしました。
例示では明示がありませんが、温度自体が2の補数表記なので、符号付き演算を常に考慮する必要があります。
取得値 MSB = 00h LSB = 30h Count_per_c = 10h Count_Remain = 09h 1. 16bit 長で計算します。そのために MSB と LSB を置数します。 MSB LSB 00 30 H 2. 0.5℃の桁を削除するため、全体を右1ビットシフトします。 = 00 18 H 3. 小数点以下を含む温度データを 16bit 長で以下のように置数します。 これが、TEMP_READ になります。 18 00 H = 24 ℃ 4. 0.25℃を引きます。(100H / 4 = 40H) 0.25℃ を ここで示す 16進数で表現すると 0040H になります。 - 00 40 H = 17 C0 H --> この計算結果を一時メモリに保存します。 5. Count_per_c - Count_Remain を計算します。 10 H - 09 H = 07 H 6. 5. で得られた値を Count_per_c で割り算します。Count_per_c は、1℃あたりの分解能を示し、 ここで計算して得られる値は、常に絶対値換算で1未満の値です。そのため、16bit 長で計算します。 07 00 H --> 小数点以下の値を残すため、予め 8bit(1byte)分、左シフトするとよい。 / 00 10 H = 00 70 H --> この計算結果を一時メモリに保存します。 ※除算ルーチンはこれが参考になります → AN526 PIC16C5XX/PIC16CXXX Math Utility Routines Appendix P: 16/16 Fixed Point Divide Routines - FXD1616S (符号付16bit ÷ 16bit 整数除算ルーチン) 7. 4. で一時メモリに保存した値と 6. で一時メモリに保存した値を加算します。これが求める高分解能温度です。 17 C0 H --> 4. で算出・一時保存した値 + 00 70 H --> 6. で算出・一時保存した値 = 18 30 H = 24.1875 ℃ ≒ 24.2 ℃