■前々から作りたかったものに、室内の温度記録を取るのに複数の測定点を持たせたロガーがあった。部屋の四隅で、床面、床上2m、天井高の3点、都合12点で経時的に測定できたら面白そうだなと。サーキュレーションの効果判定とかに使えるし。
もちろん問題になるのはセンサの数で、今まで使ってきたアナログセンサやI2Cセンサだと、センサの数だけチャンネルを持たないとならない。I2Cはセンサごとにアドレスが違えば同じバスライン上に載せられるけど、実際には同じ種類のI2Cセンサはアドレスも同じなので一つのバス上に複数載せられない。アドレスの異なる複数種のセンサを集める手もあるけれど、精度やデータフォーマットが微妙に異なることになって、それはそれで手間になる。
同じバスで複数のセンサを載せられるとなると、MAXIMのDS18B20などの1-Wire系のセンサが解になる。
DS18B20は1つ1つのセンサにユニークなアドレスが振られていて、個々のアドレスを指定して個別にセンサの値を読み出すことができる。ただ、1-wireという方式がMAXIM独自で、AVRのペリフェラルでは対応しておらず、自前で実装しなければならない。
DS18の1-Wireは昔電子工作の入門書をみながら見様見真似で使ったことがあって、それで初めてDigi-Key使ったような記憶がある。その時はセンサにコードをはんだ付けするのが精いっぱいで、データバスにマルチポイントなんて夢のまた夢みたいな世界だったのだけど、今となってはやる気だけかなと。
ただ、1-Wireのフォーマットを使うのは久しぶりなのでデータシートをひっくり返す。
1-Wireの通信は要するに半二重で、同期クロックを使わず、タイミングだけで信号を読む。信号線は4.7Kプルアップが基本で、GNDへの立下りを物理的なビット信号開始のトリガとして、トリガから一定時間経過後の信号線の状態で0と1を決定する。そのために信号の各ビットには最小限のウィンドウが与えられていて、それを「タイムスロット」と呼んでいる。タイムスロットは最短で60us必要。データシートの書き方だと0と1でタイムスロットの持ち方が違うように読めなくもないのですが、スロットの物理フォーマットは共通です。

各センサを個別に呼び出すにはそれぞれのIDを指定(MATCH ROMコマンド)を発行した後に機能命令(FUNCTION)を発行する。データバス上に複数のセンサがある場合、IDを検索することもできる(SEARCH ROMコマンド)のだけど、肝心なのはどのIDを持つセンサがどこにあるか、なので、事前にIDを調べておかなければならなず、事前にIDをすべて洗い出しておく必要がある。
ID呼び出しでも「シリアルナンバ」という表現が曲者で、データシートでは「シリアルナンバ」は6バイトなのですが、必要なのはファミリーコード1バイトにシリアルナンバ6バイト、CRC1バイトを加えた68ビットです。この値は要するにREAD ROMで読み出される64ビットのユニークコードそのまま使えば通ります。