2018年5月22日火曜日

1Wireで複数デバイス

 温度センサが欲しくなったので、1Wireで遊んでみました。
 基本的には以前のエントリで書いた方法と同じです。

 STM32F4で、通信にはUART TX/RXを使い、通信時はTXをAF_ODに設定、ストロングプルアップはTXをOUT_PPに設定、0を出す時は0x00を送信、1を出す時は0xFFを送信、受信時は0xFFを送信し、0xFFなら1、それ以外なら0、リセットは0x00を送信、という感じです。
 ボーレートはリセット時が18.75kbaud、送信時が125kbaud、受信時が180kbaudです。送受信は100kbaud固定でも大丈夫っぽいです。
 プルアップ抵抗は4.7kですが、ストロングプルアップの動作確認のために47kでプルダウンしています。電源は3.3V系で、通常は4.7kと47kの分圧抵抗で3.0V付近ですが、ストロングプルアップが有効になると3.3Vになります。
 ストロングプルアップの動作確認にはオシロスコープが必須です。ストロングプルアップは、仕様では10usec以内に有効にしろ、とのことですが、これはかなり厳しいです。無いよりは良いでしょ、くらいの気休め程度です。
 バスのデコードにはZEROPLUSのLAPが使えます。バスプロトコルでLSBファーストに設定すること、サンプリングポイントを適切に設定すること(今回は12us)、あたりに気をつければ大丈夫なはずです。

 今回、テストにDS18B20を使いましたが、デバイス側から0を送信する時のパルス幅がかなり狭いです。だいたい15usくらいしかプルしてくれません。そのため、ZEROPLUSデフォルトのサンプリングポイント30usだと適切にデコードできません。

 リセット時は、0x00を送信し、2バイトを受信できれば正常です。1バイトだけの場合はデバイスが接続されていません。1バイトも受信できない場合は回路に異常があります(TXとRXが接続されておらず、ループバックしていない)。


 最初、SEARCH ROM COMMANDの実装を自分で考えていたのですが、うまく動かないので、"マイコンの1線2線3線インターフェース活用入門"という本の28ページに有る図1-8のフローチャートを実装しました。


 とりあえず、DS18B20を7個、ブレッドボードに配置してテストしてみました。起動後にSEARCH ROM COMMANDでアドレスをスキャンし、その後温度変換コマンドを打ってメモリを読み出します。

"
search ROM:7
Device  0 OK  28 90 F2 6D 08 00 00 A2
Device  1 OK  28 68 D7 6E 08 00 00 D3
Device  2 OK  28 84 87 6E 08 00 00 12
Device  3 OK  28 62 FB 6C 08 00 00 C2
Device  4 OK  28 F2 68 6D 08 00 00 05
Device  5 OK  28 F1 63 DE 03 00 00 F4
Device  6 OK  28 09 B8 6E 08 00 00 59
---
Device  0 OK  CE 01 4B 46 7F FF 02 10 4B +28.9 degC
Device  1 OK  CE 01 4B 46 7F FF 02 10 4B +28.9 degC
Device  2 OK  CE 01 4B 46 7F FF 02 10 4B +28.9 degC
Device  3 OK  CD 01 4B 46 7F FF 03 10 4A +28.8 degC
Device  4 OK  CE 01 4B 46 7F FF 02 10 4B +28.9 degC
Device  5 OK  BC 01 4B 46 7F FF 04 10 D2 +27.8 degC
Device  6 OK  CC 01 4B 46 7F FF 04 10 67 +28.8 degC
"
 という感じの結果が得られました。DS18B20のファミリーコードは28hです。OKとあるのは、CRCチェックをパスした、という意味です。
 正常にアドレスが読み出され、メモリ読み出しも正常です。
 7個中、Device 5だけ温度が大きく異なります。他の6個はTO-92パッケージですが、Device 5はステンレス管に入れた耐候性の高いタイプです。設置場所はほぼ変わらないので、ここまで温度が変わるのは謎です。

 今回はパラサイトパワーを使っているので、温度変換中はストロングプルアップが必要になります。温度変換には1秒弱かかるので、センサ1つから温度を読み出すのにおよそ1秒かかります。7個あるので、7秒です。
 1Wireの温度センサはそれほど高速に温度が変わるような場所に使うものではありませんが、それでも1組のスキャンにデバイスの数だけ時間がかかるので、センサが何十個も有るような構成には向きません。とはいえ、I2CやSPIの温度センサを何十個も並べるのは大変ですから、そういうところこそ1Wireを使うべきなのかも知れませんが。

 1Wireの欠点の1つは、そのアドレスのデバイスがどこに有るかがわからない、という点です。このあたりは、活線挿抜で増えた/消えたデバイスを探し、そのアドレスと設置場所を紐付ける、といった事が必要になると思います。


 とりあえず、件の温度センサを使いたいというヤツは、センサ1個あれば十分なので、SEARCH ROMとかも不要だったのですが、興味本位で実装してみました。と言っても本のコピーですけども。

 さて、次は久しぶりに超音波距離計とかやりたいな。暖かくなってきたので、外に出て長距離のテストとかもやりやすい季節です。


0 件のコメント:

コメントを投稿