(ツール)
 
 
 DS18S20 デジタル温度センサー (2004.02.28)

 
 
ほんとにデジタル?
 + と GND と、もう1本の線の3端子でデジタル温度センサーを実現しているというもの。
デジタルという言葉のためか、常温域の温度計として信頼して使用している。

 
    このページでは、1つのデジタル温度センサーDS18S20をLCDに表示させるために、僕が行った必要最小限の1-Wireタイミングのテスト内容と結果を掲載する。
(PICの1つのピンにDS18S20を何個も並列接続したりもできるようだが、そーいう難しそうなことはしていない。)

 
   
JPEG 300x150 12.7KB

 僕が以前使用した実績のある温度センサーは
 「LM35DZ」と「S8100B」だったが、今回は「DS18S20」
 という、デジタル温度センサーを使うことに成功した
 ので、ここにポイントを掲載する。

 大げさ表現と思うかもしないが、僕にとっては
 1-Wire(ワンワイヤー)という1本の線でデーター通信
 する方式のタイミングが超難解だったのだ。
 
   
センサーは上写真のTO-92パッケージ。これにデジタル回路が入っているのだから、十分21世紀を感じられる。

[ きっかけなど ]

ペルチェの冷蔵式乾燥装置などを作ってみたいなぁと思ったところで、トラ技2003年1月号にPIC16F84を使った温度コントローラの製作<前編>DS18S20を使いこなそう!軸丸 哲也 氏(272P〜280P) を思い出した。
その記事をよく読むと、精度の公称は±0.5゚C(ただし、-10〜+85゚Cの範囲内)で、デジタルなので当然校正は不要。もうこれを使うっきゃないという気持ちになってきた。
 しかし、PICとDS18S20の通信するタイミングについては、何回読んでも理解できなかった。

ここはやはりインターネット検索だ。
しかし、旧タイプの「DS1820」でも検索してみたが、思ったほどヒットしない。その中でも参考にさせていただいたのは、次の2つのページ。

 ・ライフ・カーネルの http://www.lifekernel.ne.jp/radio/ds1820.html
 ・雑多な工作室

しかし、やっぱよく分からない。(T_T)
データーシートも見つけたのだが、英語で益々分からなく、他の方達はよく分かったものだと感心してしまったほど。
幸いだったのは、PICのプログラムをダウンロードできるようになっているものがあったこと。それを解析できれば なんとかなりそう。
最も参考にしたプログラムは、トラ技のホームページからダウンロードしたもの。しかし、アセンブルの記述が、いつも使い慣れているものとちょっと違う。なんとか16進にアセンブルし、あとは「帝」のお世話になった。

 
   
JPEG 300x150 11.8KB

 今まで使用したことのあるアナログ温度センサー
 の僕的問題点など。

 ブツは秋月電子通商から の入手で、100〜200円/個
 くらいと安価。

 LM35は1゚Cで10mVと分かりやすいのだが、マイナス
 温度の計測ができないよだ。

 S8100Bは1゚Cで-8mVという、マイナスとハンパで
 分かり難いが、マイナス温度の計測ができる。

 しかし、どちらを使うにしても、電圧が微量であり、
 A/D変換に都合良く合わせるために、オペアンプに
 よる増電圧をしていたので、ハードが厄介だった。

 
    また、オペアンプは使いようという感じで、下手に組むと温度変化により精度が悪くなってしまったりするようだ。
元の温度センサーの精度、増電圧の精度、さらにはA/D基準電圧の精度にも多少の不安があり、表示温度が今ひとつ信用できないことは拒めない。(実は校正もテキトーでイーカゲンだった。)

 
 
DS18S20の入手

 
    「RSコンポーネンツ」 から通販購入した。
トラ技の記事には500円前後と書いてあったので、ちょっと高いのかもしれないが、他で見つけられなかった。

780円/個だったが3個注文し、代引き送料税込みで3,507円。(注文してから届くまで敏速。)

なお、RSコンポーネンツを利用するには、まず登録しなければならないが、会社名入力必須になっていたので、個人では登録できないのか問い合わせてみたところ、個人登録はOKであり、会社名入力には「個人」と入れればよいという返事をすぐにもらえた。(なお、個人の場合は代引きのみとのこと。)

 
 
リセット信号の送受信

 
    それではいよいよ通信タイミングに入る。
まずはリセット。これを確立させなければ先に進めない。
下図はデータシートのコピーに、矢印と番号を書き込んだもの。

GIF 600x200 10.5KB

@…最初の状態がどうあるべきか疑問だったが、どーでもよいようだ。
   たとえばPIC側は直前まで電気を吸い込むLo状態だったとしても、一瞬だけHi(PICの出力)にして、
   すぐにLoにしてもOKのようだ。
A…PIC側は電気を吸い込むLo状態から480μs以上経過後、PIC側を入力状態にする。
B…この緩いカーブの意味がよく分からないが、点線のように、いきなりHiが立つと考えても特に問題な
   いようだ。
C…PIC側を入力に切り替えた直後から、15〜60μsの範囲内で、DS18S20からHiが出る。
D…その後すぐにLoになる。(60〜240μsの範囲内で、DS18S20から出力が無くなる。)
E…DS18S20から二度目のHiが出っぱなしになる。
F…PIC側を入力に切り替えた時から480μs以上経過すると、DS18S20は命令待ちになる。

以上でリセット完了。

 
 
信号確認プログラム1

 
    リセットのやり方解釈が合っているかどうかの確認をしてみる。
PICを利用して、CとDの大体の時間を計ってみる。

GIF 600x300 8.32KB

*リセット信号確認テストプログラム DS819T1.src 10.6 KB …ダウンロード

[概要]

LCDは20文字x4行を使用。
PICは内蔵RCの4MHzを選定し、タイマー2をプリスケール1:1に設定して、1カウント1μsということで分かりやす くしたつもり。(ただし、内蔵RCは正確ではないし、1命令中にもタイマーは1μs進んでいるので、正確な測定ではない。)

[プログラム]

約1秒ごとにリセット動作を繰り返して、測定時間を表示するだけ。
μsの後ろの(F0)は、タイマー2のオーバーフロー旗。タイマーが255μsを超えてしまっていないかの確認用で、もし超えた場合は「F1」になる。
それから、同じ測定数値が続く場合は、フリーズしているようにも見えるので、T1の後ろに「.」を点滅するようにしてある。

[結果]

CのWaitsは30μsくらい、DのPresence Pulseは100μs前後だった。

やったー!(^^)!データーシートの範囲内である。っていうか、たぶんリセット成功!解釈は合っていたようだ。

今後のプログラムでは、これをエラーチェックとして利用することにする。
CとDの時間を計測して、データーシートの範囲に収まっていなければリセット失敗と判断して、リセットプログラムをやり直すように組むことにする。

 
 
 スキップROMコードの「送信」

 
    リセットの次はスキップROMコードを送信する。
DS18S20を並列に複数個接続している場合は、他のコードを送ったり、いろいろしなければいけないようだが、PICの1つのピンに1個だけの場合は、無条件にスキップROMコードの送信ということになるだ。
コードはCCh(16進数)表記だが、2進数だと11001100。下位のビットから送り出す。

それでは、送信パターンはどうやればよいのか。データーシートでは、「0」の場合と「1」の場合をくっつけて書いてあり、分かり難いので(実はそれをすぐには気付かなく、しばらく悩んでしまった。)引き離して見やすくしてみた。

● PICからDS18S20に「0」を送信する。
  (実際には「0」を送信できないから、「0」であるということを教える。)
 
GIF 450x225 9.89KB

@…リセットの時と同様で、PIC側は出力ピン設定でHi(出力)の状態から、電気を吸い込むLo状態にする。
   しかし、ここで(?_?)。
   リセット信号のFはPIC側が入力ピンの設定だから、どこでどのようにして、ここにくればよいか。
   結果論だが、リセット信号Fのすぐ後、PIC側を出力ピン設定でHi(出力)の状態に切り替えておく。
   それで問題なかった。

A…PIC側をLo状態にしてから60μs後(ただし120μs未満)、PIC側はHi(出力)の状態にする。
   (DS18S20は、ある時間内でHiが入らなかったので、「0」と判定するようだ。)

● PICからDS18S20に「1」を送信する。

GIF 450x225 9.23KB

@…上の「0」パターンと同じ。
A…PIC側をLo状態にしてからすぐに、Hi(出力)の状態にする。
   実は斜線部と「>1μs」の意味が分からないのだが、タイミングが早すぎるとダメなのかもしれない。
   PICを4MHzクロックで動作させた場合、1命令はちょうど1μsになるが、15μs以内にHiにしておけばよい
   のだと思う。
   なお、上の「0」パターンとは異なり、送信終了の合図は無い。PIC側をLo状態にしてから60μs以上経て
   ば、次の送信OKのようだ。

※「0」、「1」パターン共、最初と最後はPIC側がHi(出力)の状態ということに気が付いた。
 ビットデーターは連続でどんどん送るのだが、PIC側Hiを基本とすると分かりやすい。

 
 
コンバートTコードの「送信」

 
    次にPICからDS18S20へ「温度変換開始指令」のコードを送信する。
コード配列が違うだけで、上のスキップROMコードの送信と同じ。 コードは44h(16進数)だが、2進数だと01000100。下位のビットから送り出す。

 
 
変換時間(待ち)

 
    データーシートでは最長で0.75秒になっている。しかし、変換終了の合図は来ないようなので、少し余裕を付けて、約1秒間待つことにした。
 
 
DS18S20のリセット
スキップROMコードの「送信」

 
    ここで再び、リセットとスキップROMコードの送信をする。僕のリセットイメージとは違い、すべて初期化される訳ではなく、データーは残っているようだ。

 
 
リード・スクラッチ・パッド・コードの「送信」

 
    今度はPICからDS18S20へ「温度変換 したデーターなどを送ってきなさい指令」のコードを送信する。
これもコード配列が違うだけで、他の送信パターンと同じ。 コードはBEh(16進数)だが、2進数だと10111110。下位のビットから送り出す。

 
 
DS18S20からのデーター「受信」

 
    やっと受信する行程にきた。ここでちょっと今までの流れを整理しておく。

1.リセット
 ↓
2.スキップROMコードを送信(CCh(11001100))
 ↓
3.コンバートTコードを送信(44h(01000100))
 ↓
4.変換時間(約1秒待ち)
 ↓
5.リセット
 ↓
6.スキップROMコードを送信(CCh(11001100))
 ↓
7.リード・スクラッチ・パッド・コードを送信(BEh(10111110))
 ↓
8.データーの受信   (→↑ 1.から繰り返すようにすると、約1秒毎に温度測定更新になる。)


それではいよいよDS18S20からデーターを受信するが、受信はどうやればよいのだろうか。
この場合のデーターシートも、「0と「1」の場合をくっつけて書いてあり、分かり難いので引き離して見やすくしてみた。

● DS18S20からPICへのデーターが「0」の場合。

GIF 450x225 11.6KB

@…送信が終わった後は、PIC側はHi(出力)の状態にしておくが、ここでPIC側をLo(電気を吸い込む)にする。
A…すぐにPIC側を入力に切替え、Hi(1)かLo(0)か判定する。
B…ここではLo(0)だったのパターンだから、@のPIC側をLoにしたところから60μs以上待つ。
C…PIC側を出力のHi(出力)状態に戻しておく。


● DS18S20からPICへのデーターが「1」の場合。

GIF 450x225 7.23KB

@…上の「0」パターンと同じ。
A…上の「0」パターンと同じ。
B…上の「0」パターンでは60μs以上待ったが、すぐにPIC側を出力のHi(出力)状態に戻してOK。


さて、送・受信のやり方は間違っていないのか。送信パターンは一方通行であり、きちんと送信されているのか分からないので、 正常受信できなかったとしても、何が悪いのか分からなくなりそうなのが心配だった。


メモリーマップ
(この表はトラ技の転載で、4と5は何の予約なのか分からない。)

 
   
0 温度データー下位バイト
1 温度データー上位バイト
2 THレジスタまたはユーザー・バイト1
3 TLレジスタまたはユーザー・バイト2
4 予約済み
5 予約済み
6 温度変換カウンター(COUNT REMAIN)
7 温度変換カウンター(COUNT PER゚C)
8 CRC
9バイトのデーター(8ビットx9)

データーは左表の上から順に、下位ビットから読み出すことができる。
っていうか、途中から読み出すことはできないようだ。

最後のCRCは、読み出したデーターが間違っていなかったかの確認用。
 
   
全部読み出すと、8ビットx9で72ビットになるが、ここまでの送・受信のやり方が間違っていないかどうかを確認するために、とりあえず1バイト(8ビット)だけ読んで表示してみる。

*受信(1バイトのみ)確認テストプログラム DS819T2.src 10.6 KB …ダウンロード

[概要]

・回路はリセット信号確認テストプログラムと同じ。
・温度データー下位バイトを約1秒間隔で10進数(BCD)表示する。DS18S20を指で摘むと、数値が上がってい
  くのを確認でる。プラス側の温度であれば、表示を÷2すると実際の温度になる。
・DS18S20関係部のプログラムは、サブルーチン(call命令)を使用していないので、単調な繰り返し記述が長い。
・リセットエラーチェックを入れてみた。もしエラーがあった場合は、LCDの3行目にエラー表示をして停止する。
 (DS18S20の配線を1本外してみたりすると、エラー動作させてみることができる。)

 
 
確認テストプログラム3

 
   
JPEG 300x120 12.0KB


 上の受信(1バイトのみ)確認テストプログラムは
 無事に表示されたので、送・受信のやり方は間違って
 いなかったとして、今度は9バイト連続受信して表示し
 てみる。
 なお、メモリーマップ表にないが、10バイト目も受信し
 てみまる。
 (最初のデーターが表示されると予想していた。)
 
    ・回路はリセット信号確認テストプログラムと同じ。
・今回はサブルーチン(call命令)を使用して、プロクラム数を少なく、すっきりとしたつもり。

*10バイトデーター表示テストプログラム DS819T3.src 10.6 KB …ダウンロード

 
 
確認テストプログラム4

 
    今度は、゚C温度表示とCRC計算表示をやってみる。

 
   
温度
゚C
DIGITAL OUTPUT
2進数 16進数 10進数
+85.0 00000000 10101010 00AAh 170
+25.0 00000000 00110010 0032h 50
+0.5 00000000 00000001 0001h 1
0 00000000 00000000 0000h 0
-0.5 11111111 11111111 FFFFh 255
-25.0 11111111 11001110 FFCEh 206
-55.0 11111111 10010010 FF92h 146
左表はデーターシートのものに10進数を追加してみたもの。(上位バイトは無視)

プラス側の温度であれば、単純に÷2すると実際の温度になることが分かる。

マイナス側の場合は、上位バイトは無視して、8ビットでゼロから引いてから÷2にすると、実際の温度になる。
たとえば-25.0゚Cの場合は、
0-11001110=00110010
+25.0゚Cのときと同じ値になる。
 
   
CRC計算

 実はよく分からなく、解析したりするのが面倒になったので、トラ技プログラムのその部分を、ほぼそのまま転用することにた。移植が簡単にできなければ、とりあえずCRCは諦めようかなと思っていたのだが、すんなりとうまくいった。メモリーマップのCRCデーターと、計算のCRCを並べて表示してみたところ、常に同じ値になる。

・回路はリセット信号確認テストプログラムと同じ。

*温度とCRC表示の確認テストプログラム DS819T4.src 10.6 KB  …ダウンロード

マイナス側の表示確認は冷凍庫を使用してみたが、ぐんぐんと下がっていくので面白い。

 
 
パラサイト・パワー接続とエラーカウント

 
    パラサイト・パワー接続

DS18S20の配線が2本接続でOKというもの。
2本接続でOKなんて僕にはとても不思議なことで、あまり考えたくなかったのだが、実際に温度計を作ることを考えると、配線材は2本線が簡単で、シールド線なども入手性がよいから、最後にやってみることにした。

トラ技の記事によると、温度変換他中は電力が不足するので、1.5mAほどの供給が必要と書いてあり、その間はソフトで切り替えるようになっているようだ。
(なお、100゚C以上では内部の漏れ電流の問題で、パラサイトパワー機能を使わないほうがよいと書いてあった。)

僕のプログラムを見直してみると、通常でPICのピン側は出力のHi(出力)状態にしている。すなわちほとんどが電力供給状態なので、そのままでもよいのでは?
早速2本線接続に配線し直してみると…、何の問題もなく表示された。


エラーカウント

リセットエラーとCRCエラーがあるが、エラー頻度が気になる。どれくらいの頻度で発生するのか心配になってきた。今までのテスト表示では、突然とんでもない値が表示されたことはないのだが、 せっかくなので長時間エラー回数をカウントするプログラムを作ってみた。
約1秒間隔で温度測定表示するときに1カウントし、256カウントでCsを+1する。Csが255のときは約18時間経過したことになる計算。E1にはリセットのエラー回数を入れ、E2にはメモリーマップのCRCデーターと、計算のCRC値が違っていた場合 にエラーとし、その回数を加算していく。

[結果]

朝から晩まで動作させて、エラーゼロだった。PICとDS18S20間の配線を100mくらい長くすると、エラーが出たりする ことがあるのかもしれないが、1mくらいのシールド線では問題にならなかった。

GIF 600x300 8.39KB


*DS18S20テスト最終プログラム DS819T5.src 10.6 KB …ダウンロード


スリープによる省エネ

DS18S20の温度変換中は、PICに無駄な処理をさせて約1秒間の待ちを作ってたが、上のプログラムではその時間、PICをスリープにして、PIC自身の省エネを図ってみた。(ほんの少しの電力だが、電池による携帯温度計などを作る場合は、電池長持ちが望ましい。)
目覚めさせる方法は、ウォッチドックタイマーを有効にして、プリスケールを設定するだけという簡単なもの。
ただし、時間設定は正確にはできない。(腕時計内蔵のストップウォッチで計測して1.1〜1.2秒くらいだった。)

 
 
 
    2005.10.26
軸丸 哲也さんからEメール!
なんと!トラ技2003年1月号 PIC16F84を使った温度コントローラの製作 DS18S20を使いこなそう!執筆者の「軸丸 哲也」さんからEメールをいただいた。記事の反響があってうれしいという内容だった。
その後アドバイスもいただいた。とてもうれしい。


2005.11.01
表示ステップを0.1゚C間隔に!

データー受信の(0)を10進数で見て、それを半分にすると0.5゚Cステップの温度表示となる。ソフは簡単で分かりやすく組むことができるので、ディープな温度計は、0.5゚Cステップで製作した。

今度は、0.1゚Cステップ表示に挑戦してみる。
トラ技及びデーターシートには、データー受信の(6)と(7)を使って計算できるようなことが書いてありる。





そこで前記の「確認テストプログラム3」へ戻ってテスト確認してみた。
その結果、データー受信(7)は「016」一定で、データー受信(6)は「001」から「016」の範囲で変わることが分かった。
S18S20温度センサーを指でチョイチョイと触って、少しずつ温度を上げていくと、010、009、008…というように減少し、001の次は016になる。「008」と「016」のときはデーター受信(0)が+1される。

1゚Cの16等分が、データー受信(6)値に置き換わっているようだ。
確認した値と計算値を下表にまとめてみた。なお、TEMP_READには、データー受信(0)の0.5゚C(最下位bit)
なし値を入れる。

それでは、X.0゚CまたはX.5゚Cちょうどのポイント値はいくつか。 この表より、X.0゚Cの場合は「012」、X.5゚Cの場合は「004」と分かる。

0.5゚Cステップ表示のときは、たとえば、データー受信の(0)が20.5゚Cだったとすると、20.3〜20.7゚Cくらいの範囲 ということが分かる。

データー受信(0)
10進数
データー受信(0)
゚C表示
データー受信(0)
0.5゚C(最下位bit)
なし表示
データー受信(6)
10進数
計算結果 表示させる値
041 20.5 20 001 20.6875 20.7
041 20.5 20 002 20.6250 20.6
041 20.5 20 003 20.5625 20.6
041 20.5 20 004 20.5000 20.5
041 20.5 20 005 20.4375 20.4
041 20.5 20 006 20.3750 20.4
041 20.5 20 007 20.3125 20.3
041 20.5 20 008 20.2500 20.3
040 20.0 20 009 20.1875 20.2
040 20.0 20 010 20.1250 20.1
040 20.0 20 011 20.0625 20.1
040 20.0 20 012 20.0000 20.0
040 20.0 20 013 19.9375 19.9
040 20.0 20 014 19.8750 19.9
040 20.0 20 015 19.8125 19.8
040 20.0 20 016 19.7500 19.8

1ステップは1/16の0.0625だから、ハンパな値になるが、四捨五入してまるめると、等間隔ではないが、0.1゚Cステップを表現出来る。

それではソフトの対応方法だが、計算はせず、この表の16パターンを判定させるようにする。
データー受信(6)をチェックして、たとえば「002」と「003」なら、小数点第一位は「6」にするという、単純なもの。
ただし、「013」、「014」、「015」、「016」の場合は、1桁目の値を、1゚C下げる必要がある。

次に0゚C近辺ではどうなるのか、表にしてみる。
データー受信(0)の0.5゚C(最下位bit)は、くりあげ表示しなければ、正しい表にならなかった。
また、マイナスの場合、プラスの16パターンとは異なりることが分かった。たとえば「002」と「003」なら、小数点第一位は「4」になる。マイナスのパターンも判定させるようにする。

データー受信(0)
10進数
データー受信(0)
゚C表示
データー受信(0)
0.5゚C(最下位bit)
なし表示
データー受信(6)
10進数
計算結果 表示させる値
0 0.0 0.0 011 0.0625 00.1
0 0.0 0.0 012 00000 00.0
0 0.0 0.0 013 -0.0625 -0.1
0 0.0 0.0 014 -0.1250 -0.1
0 0.0 0.0 015 -0.1875 -0.2
0 0.0 0.0 016 -0.2500 -0.3
1 -0.5 -1.0 001 -0.3125 -0.3
1 -0.5 -1.0 002 -0.3930 -0.4
1 -0.5 -1.0 003 -0.4375 -0.4
1 -0.5 -1.0 004 -0.5000 -0.5

データー受信(0)の値がゼロでも、マイナス表示させる必要があるものがある。その場合でも、データー受信(1)はゼロのままなので、ソフトで判定する工夫が必要と思われる。

それから、表示の上限と下限を設定した場合について、確認のため表を作成してみた。
たとえばデーター受信(0)の169までとした場合は、84.7゚Cが表示上限になる。

データー受信(0)
10進数
データー受信(0)
゚C表示
データー受信(0)
0.5゚C(最下位bit)
なし表示
データー受信(6)
10進数
計算結果 表示させる値
170 85.0 85 009 85.1875 85.2
170 85.0 85 010 85.1250 85.1
170 85.0 85 011 85.0625 85.1
170 85.0 85 012 85.0000 85.0
170 85.0 85 013 84.9375 84.9
170 85.0 85 014 84.8750 84.9
170 85.0 85 015 84.8125 84.8
170 85.0 85 016 84.7500 84.8
169 84.5 84 001 84.6875 84.7
169 84.5 84 002 84.6070 84.6
169 84.5 84 003 84.5625 84.6
169 84.5 84 004 84.5000 84.5
169 84.5 84 005 84.4375 84.4
169 84.5 84 006 84.3750 84.4
169 84.5 84 007 84.3125 84.3
169 84.5 84 008 84.2500 84.3

たとえばデーター受信(0)の19までとした場合は、-9.8゚Cが表示下限になる。

データー受信(0)
10進数
データー受信(0)
゚C表示
データー受信(0)
0.5゚C(最下位bit)
なし表示
データー受信(6)
10進数
計算結果 表示させる値
19 -9.5 -10 001 -9.3125 -9.3
19 -9.5 -10 002 -9.3930 -9.4
19 -9.5 -10 003 -9.4375 -9.4
19 -9.5 -10 004 -9.5000 -9.5
19 -9.5 -10 005 -9.5625 -9.6
19 -9.5 -10 006 -9.6250 -9.6
19 -9.5 -10 007 -9.6875 -9.7
19 -9.5 -10 008 -9.7500 -9.8
20 -10.0 -10 009 -9.8125 -9.8
20 -10.0 -10 010 -9.8750 -9.9
20 -10.0 -10 011 -9.9375 -9.9
20 -10.0 -10 012 -10.0000 -10.0
20 -10.0 -10 013 -10.0625 -10.1
20 -10.0 -10 014 -10.1250 -10.1
20 -10.0 -10 015 -10.1875 -10.2
20 -10.0 -10 016 -10.2500 -10.3

※これらの、0.1゚Cステップ表現は、「7セグメントLED温度計」のプログラムに組み込んでみる。

 
                             
 
 
  バイクでフローターフィッシングとキャンプ > ツール > PIC(ワンチップマイコン) > デジタル温度計

 
  << トップヘージへ

   
inserted by FC2 system