【Arduino】ワンチップセンサとシリアルI/O

前回の記事でArduinoのセットアップをしました。
今回は具体的な使用方法として手軽なワンチップセンサをArduinoにつなげることを想定し, 簡単なワンチップセンサリストを作りました。

先にシリアルI/Oのおさらいをします。この辺はArduinoを触っていたら意識しないところですが知っておいても損はないです。

シリアルI/O方式

まずは, I2C (inter-Integrated Circuit)です。
I2Cはフィリップス社が開発したクロック信号(SCL)とデータ信号(SDA)だけの汎用性の高いシリアルバスです。
マイコンがI2C対応なら比較的楽にハードを設計できます。
こちらは, SPIと比較してサウンドチップやカメラモジュールなどの通信に向いています。

I2C

マスタとスレーブ
役割 デバイス
マスタ マイコン
スレーブ EEPROM ADC DAC
マスタスレーブ マイコン / I/O機能を持つデバイス
I2Cのプロトコル
プロトコル 役割
スタートコンディション ネゴシエーションを開始する。SCLがhigh,SDLをlowでバス使用権獲得
アービトレーション 7bitのデバイスアドレスと1bitの送受信方向をバスに送信。小さなアドレスが優先される
アクノレッジ アービトレーション後に転送準備のためSCLをrowに維持する
ストップコンディション SCLがlowでSDAをlowにした後に,SCLをhighにする。最後にSDAをhighにして完了。この後にレジスタやメモリにデータを書き込む。

続いて SPI (Serial Peripheral Interface) です。
モトローラが開発したインターフェイスで当初は周辺機器のチップとデータのやり取りする信号線を減らすことを目的で作られました。
現在はマスタスレーブ方式であることや標準規格でないことから異なる仕様のチップ間で使えないことから, 主にFlashメモリとの接続で使われているみたいです。

spi_if

また, データサイズの制限やパリティ処理やチェックサムもないのが特徴です。

ワンチップセンサ

シリアルI/Oをさらっと見たところで本題のリストです。世の中にあるワンチップセンサのほんの一部です。
ワンチップセンサはモジュール化されているのでフィルタ, アンプ, ADCを自分で作る必要がないので楽です。
マイコンのGPIOなどに直接つないで使用できます。

計測対象とワンチップセンサ
計測対象 センサ 接続 製造元
温度湿度 SHT1x/2x I2C センシリオン
気圧 MPL115A1/A2 SPI Freescale
近接/色 TCS3771 I2C AMS
近接/照度 BH1772GLC I2C Rohm
照度 TEMT6000 アナログ Vishay
加速度 KXTI9 I2C Kionix
電流 FHS 40-P/SP600 アナログ LEM

* 参考 : トラ技2012-12月号

データの一時退避先としてのリングバッファ

センシングしたデータはクラウドにリアルタイムに送信するか, 一時的にメモリに保存して一括で送るなど色々な方法があります。
以下は, リングバッファを使用して一時的にホスト側に貯めておく方法です。バッファメモリが一杯になったら一括送信といった形で使います。
直近のデータからマイコン側で何かアクションさせて, さらにバックアップ等としてクラウドを利用するというケースでは使えると思います。

バッファメモリを先頭から使っていき使い切ると先頭に戻る構造です。
つまりキューを有限なメモリ領域内でループさせるというプログラミングテクニックです。
組み込み機器などの制約的な環境ではよく用いられます。

配列のインデックスを見つけるのを工夫している実装が多いようです。

int next(int index) {
  return (index + 1) % MAX_QUEUE_SIZE;
}

一般的にキューではデータの追加 (enqueue), データの取出し (dequeue), 空チェック (isEmpty)を実装するために、読み込み位置と書き出し位置をポインタで制御する必要があります。

実装例はここここが詳しいです。

RaspberryPiのブート

Raspberry PiはSDカードブートです。まずは, OSイメージをSDに書き込みます。

OSXではimgを書き込むツールRPi-sd card builder v1.2が推奨されているにもかかわらず, 私の環境では使えなかったのでCUIでOSのimgを書き込みます。

$ df -h
$ diskutil list
$ sudo diskutil umountDisk /dev/disk1
$ sudo dd bs=1m if=/***/2013-02-09-wheezy-raspbian.img of=/dev/rdisk1
1850+0 records in
1850+0 records out
1939865600 bytes transferred in 208.028218 secs (9325012 bytes/sec)

[注意]
ここでも指摘されているように、キングストンのSD Card (16Gb Kingston Class 10) では[mmc0 timeout waiting for hardware interrupt]というエラーが出る場合があります。
mmcデバイス(マルチメディアカード)のマウントエラーのようです。

Raspberry Piのマルチブートという使い方もあります。