raqwel’s diary

Web系で働いている駆け出しエンジニアの備忘録です。

Raspberry PiでAD変換するのにMCP3002を使おうとする話(データシート読み取り編)後編

先日に続いて、次はデータ受信編です。
ちなみに、先日の「データ送信編」は以下から

raqwel.hatenablog.com

データ受信に関しても基本的にデータシートを元に読み取っていきます。 f:id:raqwel:20171126180016p:plain

この図の「Dout」と「MCU Recieved Data」に着目すると、データがどのように返ってくるのかがわかります。

Doutを見るとB0〜B9までの10bit帰ってきてその後にNullBitが返ってくることがわかります。これはMCP3002の分解能が10bitであることから起因していると考えられます。また、データの並び方はビッグエンディアンである事もわかります。

しかしMCU Received Dataを見ると8bitずつに分けられて2回送られてきていることがわかります。ということは受信されたデータをそのまま素直に受け止めるわけにはいかなさそうです。ちなみに受信される順番はNullBitがある方から始まり、B0で終わる、というようになっています。
ではどのようにしたらデータを上手く受信して来れるのでしょうか。

先日の記事で示しました、xfer2()で送信したら返り値に受信した値を格納するようです。そしてそれは配列で受け取ることが出来る模様です。 ということは、response = xfer2()とするとresponse[0]に[X, X, X, X, X, null, B9, B8]、response[1]には残りのbitが入る事が考えられます。

値は取得できましたが、配列で2つに分かれてしまっています。
1つのセンサから得た値が2つに分かれてしまって扱うのが面倒そうなので、 出来ることなら1つの変数にまとめてしまいたいです。

そこでビット演算の出番です。 response[0]の値を左に8bitシフトしてからresponse[1]を足すと
[X, X, X, X, X, null, B9, B8, B7, B6, B5, B4, B3, B2, B1, B0]となります。これで値を全部取れそうなんですが、Xとなっている部分がちょっと邪魔です。ここの値に何か入っていると上手く値を取ることが出来ません。
欲しいのはX以外の値です。ということなのでXの部分は0にしてしまいましょう。
ここでAND演算の出番です。2進数で0b1111111111、16進数で0x3ffをAND演算すると、Xの部分はどんな値でも0になるので欲しいところだけ取得することが出来ます。

最終的な形としては

response = spi.xfer2([0x68, 0x00])
value = ((response[0] << 8) + response[1]) & 0x3ff

となります。 ここまで結構長かったですがしっかり読み取ったことで確信を持って実装に移ることが出来ます。

ということで方針が経ったので次は実際に実装していこうと思います。