uchikawa-yです 一応今回が最終回のつもりです。 今回は前回までと趣向を変えてDS2480Bを実際に使うにあたっていろいろぶつかったことや気になったことについて書いていきます。今回は最初に項目をあげておきましょう。
  • DS2480Bのシリアル入出力
  • byte単位のreadコマンド/モードが無い?
  • センサの電源を配線しないでも動いてしまった - 2線使用時の電源の謎 -

DS2480Bのシリアル入出力

なんでデータモードも含めてほとんどのコマンドで1byteの戻り値が帰ってくるのだろう

DS2480Bは1-Wireバスとシリアル(RS-232C TTLレベル)の変換器として動作しますが、シリアル入出力の仕様は以下の通りです。
  • TTLレベル 正/負論理(端子接続で切り替え可能)
  • 9600bps(デフォルト値)~115200bps
  • フロー制御なし
  • 送信バッファなし、受信バッファ1byte

DS2480Bには送信バッファはありませんがシリアル経由でPCなどのホストへ送られたデータはPC側の受信バッファにたまります。このため送られてきたデータは適切に処理するなり読み飛ばす必要があります。そうしておかないと必要なデータをバッファオーバーフローで失ったり、データのずれが起きたりする可能性があります。 ほとんど全てのコマンド、データモードの送信で1byteの戻り値があるのでDS2480Bでは基本的には「1byteの書き込みを行ったら1byte読む」という形に自然になります。最初はこの仕様を奇妙に思ったのですが実はちゃんと意味があった…というお話です。

1-Wireの最大データ転送レートはオーバードライブ(高速)モードで142kbps、標準モードでは実質的16kbps程度です。センサのDS18B20がオーバードライブに対応していないのでここでは標準モードを使用しています。この場合、9600bpsでもシリアル入出力のほうが高速なので、DS2480Bへの送信でデータオーバーフローの可能性があります。受信バッファが1byteしかないのでホスト側では1byteごとにチェックしなければならないわけです。

DS2480Bが受け取った1byte分の処理の完了は、ホスト側のDS2480Bの返す1byteの読み取り完了で検出できる 割合当然といえば当然なのですが、私は一番最初に引っかかってます。「実行例ちゃんと読めよ」ですね。CTS/RTS制御が使える環境でドライバ任せにするプログラムしか書いたことなかったですから…(ぶーぶー)。

データモードの戻り値についてはもう一つ別の大きな意味がありました。 というわけで次の項に続く

DS2480Bにはbyte単位のreadコマンド/モードが無い?

これは…何て言っていいのか、個人的には使うにあたって一番詰まったところだったりしますが… DS18B20は9バイトの読み出し可能なメモリ(Scratchpad)を持っていて、温度測定結果などが収められています。温度測定完了後にこれを読み出したいのですが、データモードでセンサに対してRead Scratchpadコマンドを送って待っていても9バイトのデータを受け取ることはできません。
  • シリアルポートに対してソフトウェア的にreadを行っても対向のポートには「read待ちの状態である」というような情報は伝わらない
  • 1-Wireではマスタ側がReadスロットを開始しないとスレーブ側はデータを送信しない
ということがあって、シリアルポートの向こう側から待っているだけではデータは出てこないのです。1bit単位のreadコマンドはコマンドモードで用意されているのですが、これを繰り返し使うのはいかにも無駄です。 ではどうすればいいのかというと……これも「データシートの実行例読めよ」が結論なのですが。 結論:byte単位でデータを読むにはデータモードでffh(全bit1の1byte)を送信して戻り値を読む。読み出した1バイトがスレーブの送ったデータである。 1-Wireの仕様をちゃんと理解した上で、DS2480Bのデータモード時の戻り値が1-Wireバス上の波形を反映したものである、という内容を考えれば想像つかないものでもないですが、この行間を読むのはちょっと厳しいです(実行例に書かれているので最終的には正解にたどり着けるようになっているとは言えるのかもしれませんが)。 本気でデータシートの本文に書いておいてほしいと思いました。

センサの電源を配線しないでも動いてしまった  - 2線使用時の電源の謎(strong pullupの意味) -

1-Wireは信号線と+電源(Vdd)を時分割して共有する配線も可能で、2線で使用できるようになっています。これはネットワークケーブルや電話線のUTPのうち1ペアが利用可能ならそれを流用した配線もできるようにと考えたものらしいです。 アプリケーションノートにはネットワークケーブルを使う例があげられています。DC等のルール的に問題があるかどうかは別としてラック間配線のためのパッチパネルなどが利用できると楽だったりしませんか? (なお以下の部分には「いくらか」アナログ回路設計の知識が必要な内容が含まれます。まあオームの法則程度なので気楽に読んで下さい) 信号線と+電源を共有するというと特別な方法を使っているような印象を持つかもしれませんが、これは回路的には大したものではなくて概念的にはダイオードとコンデンサを組み合わせた以下のような回路で接続されています。
2線接続の場合の電源


1-Wireの信号線はデータのやり取りを行っているときには短時間0となる場合がありますが、大部分の時間では1(プルアップ抵抗を介して+5Vに接続している状態となっています。
信号線QDが1
QDからダイオード経由で電源が供給される
信号線がQDが0
ダイオードによってQDは切り離され、コンデンサに蓄えられた電荷が(短時間の)電源供給に利用される
もし、1-Wireバス上のスレーブデバイス全体の消費電流が小さい(数μA程度のオーダー)ならばこれはこのまま何もしなくても動作してしまうと考えられます。実際にはそうも行かなくて、DS18B20の場合温度測定を開始したり、設定内容の書き換えを行う場合はデータシート上、最大1mA電流が流れるとあります。 1mA電流が流れるとして、仮にプルアップ抵抗を推奨回路の通り4.7kΩとするとプルアップ抵抗の両端の電圧Vrは、 Vr = I×R = 1×10^(-3)×(4.7×10^3) = 4.7(V) DS18B20のDQの電圧は5-4.7=0.3(V)となり、電源電圧として必要な電圧に達しません。正常に温度測定できないことになります(実際には規格上の電流の最大値まで流れないことも多いようですが)。この問題に対応するため、2線で使う場合はプルアップ抵抗をバイパスできるような回路が必要です。バイパス回路はDS2480Bには内蔵されていてソフトウェアから制御可能になっています。 バイパスした状態をDS2480Bではstrong pullupと呼んでいます。 以下の図はDS2480B経由で1-Wire上にセンサ4個を2線接続して温度変換コマンドを送り、DQ端子の電圧を見たものです。
strong pullupの効果


DS2480Bは単純なプルアップ抵抗を使用しているわけではなく、アクティブプルアップとなっているので多少事情は異なりますが、strong pullupを使用すると電圧の低下が少なくなることがわかります。 ところでDS18B20は電源電圧は最低3Vなのでこの測定結果によればstrong pullupなしでもぎりぎり動作するような気がします。実際に動かしてみると完全に規格外の使い方ですがstrong pullupを行わなくても動作してしまいます。 実は先に2線接続をしてstrong pullupを行わずに測定プログラムを動かしてみたら「あれ?動いちゃった」状態だったので調べてみたのですが、元々動いてもおかしくない状態だったようです。 ただ、調子に乗ってセンサをいくつもつないだりすれば誤動作しやすいでしょう。また、1-Wire上を流れる電流はセンサ全ての合算ですから、全てのセンサで同じタイミングで温度測定を行うと誤動作しやすいということもわかります。

最後に

温度測定システムの紹介ということで5回にわたって書きましたが、なにぶん書き慣れないことなのでどの程度伝わったか不安ではあります。 Perlで書いた測定プログラムは公開してありますし、メーカーのデータシートには十分な情報が含まれていますし、含めるとかなり煩雑になりそうだったので、今回は具体的なコマンド体系・シーケンスについてはあえて書きませんでした。なので具体的なコマンドの解説もあったほうがいい等の感想があったら教えていただけるとありがたいです。 温度センサDS18B20は中々よくできているセンサで使わないのはもったいないと感じています。1-Wireのデバイスは温度センサ以外は品揃えがいまいちなのが残念ですが汎用のA/Dコンバータがあるのでいろいろな場面で選択肢の一つとして考えられるものだと思います。