Raspberry Piで正統派のアナログ入力

Raspberry Piでのアナログ入力方法として、OpenStickを用いる例を先日書いたが、今回はA/D変換ICを用いる正統派の方法を試してみた。

使用したのは秋月電子で¥200のMCP3002。アナログ入力が2CHあり、SPIでRaspberry Piと接続する。

回路図

RaspiAN_SPI

回路図

Raspberry Pi側の準備
こちらを参考に設定した。

  1. sudo apt get install python-dev  でpython-devをインストール
  2. /etc/modprobe.d/raspi-blacklist.confファイルをエディタで開き、
    blacklist spi-bcm2708 行の先頭に#を追加してコメントアウト。
  3. リブート後、lsmodコマンドを実行して「spi_bcm2708    ・・・」の表示がある事を確認。
  4. 下記を実行してPython-spiをインストール
    mkdir python-spi
    cd python-spi
    wget https://raw.github.com/doceme/py-spidev/master/setup.py
    wget https://raw.github.com/doceme/py-spidev/master/spidev_module.c
    sudo python setup.py install

お試し
次のスクリプトをspiread.pyという名前で作成。

#!/usr/bin/env python
# _*_ coding: utf-8 _*_

import spidev
import time

CE=0

spi = spidev.SpiDev()
spi.open(0,CE)

while True:
retspi = spi.xfer2([0x68,0x00])
value = (retspi[0]*256+retspi[1]) & 0x3ff
print value
time.sleep(1)

実行結果(可変抵抗でアナログ値を変化させながら実行した例)

$ ./spiread.py
0
0
128
292
489
1023
1023
1023

Raspberry PiのSPIはCE0とCE1端子を用いて2個のSPIデバイスを個別に使用できる。これをスクリプト中では変数CEで指定している。
spi.xfer2()に渡している0x68はMCP3002に対し、「シングルエンド動作」、「アナログ入力CH0を使用」、「MSPから出力」 を設定している。 変換結果は配列retspiに2バイトで入るので、連結して下位10ビットを取出した後、print文に渡している。
なおspi.xfe2()に渡す値0x68を0x78に変更するとCH1入力を使用する事になる。

OpenStick方式と比べると・・・

  1. ICが安い
    OpenStickで使うPIC18F2550は350円。更に発振子やUSBコネクタが必要だが、MCP3002だと200円で殆ど外付け部品が不要。
  2. チャンネルが2つだけ
    OpenStickだとアナログ10CHで更にデジタル入力も使えるがMCP3002は2CHのみ。
  3. プログラムが簡単
    慣れや使用言語にもよると思うが・・・ジョイスティックの値を取るよりSPIの方が簡単な気がする。
  4. PIC18F2550のアナログソースは最大2.5KΩのインピーダンスにせよと取説に記載がある。 一方MCP3002の取説によるとアナログ入力リークが0.001μA(TYP)なので、こちらの方が扱いやすそうである。
  5. OpenStickはUSB電源駆動なので0~5Vの範囲でA/D変換する。 MCP3002はRaspberry Piと直結する場合、SPI信号が3.3VなのでA/D変換も0~3.3Vの範囲となる。

Raspberry Piで正統派のアナログ入力” への7件のコメント

  1. ピンバック: Raspberry Pi + MCP3002で照度センシング | ほいほい堂blog

  2. こんにちは
    少し気になりましたのでコメントさせていただきます。
    0x68はMCP3002に対し、「シングルエンド動作」、「アナログ入力CH0を使用」、「MSBデータの後ろにLSBデータを付加して出力」
    ですね。

  3. nopnop2002さん、こんにちは。
    もうすっかり忘れていたのでMCP3002のマニュアルを読み直しました。「5.0 SERIAL COMMUNICATIONS」の章を見るとMSBFビットがHのときはMSB側から10bit分のデータを出して終わり。MSBFビットがLのときはMSB側から10bit分のデータを出した後に反転させた順序でLSB側からデータを出すという事だと思います。
    なので本文の内容で合っている様に思うのですが、いかがでしょう?(MSPと書いちゃったのはMSBの間違いですが)

  4. 返信ありがとうございます
    私も、

    MSBFビットがHのときはMSB側から10bit分のデータを出して終わり。MSBFビットがLのときはMSB側から10bit分のデータを出した後に反転させた順序でLSB側からデータを出す

    という理解をしていましたが、どうも動きが違うので、実際に試してみると

    MSBFビットがLのときはMSB側から10bit分のデータを出して終わり。MSBFビットがHのときはMSB側から10bit分のデータを出した後に反転させた順序でLSB側からデータを出す

    という動作をしました

    こちらをご覧ください
    http://nopnop2002.webcrow.jp/Analog-Input/MCP3002-4.html

  5. nopnop2002さん、こんにちは。
    そうなんですね!貴重な実験結果ありがとうございます。

    私の乏しい英語力ではマニュアルにはLの時にLSB側のデータを出すと書いてある様に読み取れましたが、確かに一か所だけ気になったのが次の文で、ここだけはMSBFがHの時にLSB側データを出す様に見えます・・・
    “If all 10 data bits have been transmitted and the device continues to
    receive clocks while the CS is held low (and the MSBF
    bit is high), the device will output the conversion result
    LSB first as shown in Figure 5-2. ”
    なんとなくマニュアルがミスってそうな気がしますね(自分の英語力の問題かもしれませんが)。

  6. こんにちは。
    はい、私もマニュアル(以下の部分)には、MSBFがLの時にLSB側のデータを出すと書いてある様に読み取れましたが、どうもマニュアルがミスってそうな気がします。

    If the MSBF bit is “high”, then the data will come from the device in MSB first format and any further clocks with CS low, will cause the device to output zeros.
    If the MSBF bit is “low”, then the device will output the converted word LSB first after the word has been transmitted in the MSB first format.

    お騒がせいたしました。

  7. nopnop2002さん
    貴重な情報ありがとうございました。
    またホームページ拝見いたしました。かなりいろんな事されてますね。
    今後ともよろしくお願いいたします。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です


*