会社行きたくなかったんです。

自由になりたくて会社辞めました

Raspberry Pi ガジェット

書籍「Raspberry Piで学ぶ電子工作」のADコンバータのコードを理解しました。

投稿日:

カラー図解 最新 Raspberry Piで学ぶ電子工作 作って動かしてしくみがわかる (ブルーバックス)」の内容を試しています。

ADコンバータというパーツを使っているのですが、いまいち理解できなかったので、自分なりに理解した内容をまとめました。

スポンサーリンク

MCP3208というパーツですが、各ピンの構成は次の図のようになっています。

黄色がチャンネルで、センサーなどの値が入力されます。
8つあります。
赤は+、緑はマイナスにつなぎます。
そして、青の部分で出力を受け取っています。
青の接続先さえメモしておけば、使用上の問題はありません。

ということで、書籍でも値の読み出し部分のコードの解説はありません。
readadcという関数にパラメータを入れて、戻ってきた値を使うだけで事足りるからです。
readadcのソースコードを以下に引用します。

def readadc(adcnum, clockpin, mosipin, misopin, cspin):
    if adcnum > 7 or adcnum < 0:
        return -1
    GPIO.output(cspin, GPIO.HIGH)
    GPIO.output(clockpin, GPIO.LOW)
    GPIO.output(cspin, GPIO.LOW)

    commandout = adcnum
    commandout |= 0x18  # スタートビット+シングルエンドビット
    commandout <<= 3    # LSBから8ビット目を送信するようにする
    for i in range(5):
        # LSBから数えて8ビット目から4ビット目までを送信
        if commandout & 0x80:
            GPIO.output(mosipin, GPIO.HIGH)
        else:
            GPIO.output(mosipin, GPIO.LOW)
        commandout <<= 1
        GPIO.output(clockpin, GPIO.HIGH)
        GPIO.output(clockpin, GPIO.LOW)
    adcout = 0
    # 13ビット読む(ヌルビット+12ビットデータ)
    for i in range(13):
        GPIO.output(clockpin, GPIO.HIGH)
        GPIO.output(clockpin, GPIO.LOW)
        adcout <<= 1
        if i>0 and GPIO.input(misopin)==GPIO.HIGH:
            adcout |= 0x1
    GPIO.output(cspin, GPIO.HIGH)
    return adcout

正しいかどうかはわかりませんが、このコードの内容を上から順に理解してみます。

adcnumは、チャンネルです。
0~7までしか無いので、それ以外は無視します。

CSをHIGH→CLKをLOW→CSをLOW
多分、これは今から、チャンネルを教えるよというコマンドです。

0x18は、11000
commandout |= 0x18 はチャンネルごとに以下のようになります。

CH0:11000
CH1:11001
CH2:11010
CH3:11011
CH4:11100
CH5:11101
CH6:11110
CH7:11111

ビット演算のことがよくわかっていないのですが、「|= 」は「足す」という意味なのでしょう。

commandout <<= 3で、右側に0が3つつきます。

CH0:11000000
CH1:11001000
CH2:11010000
CH3:11011000
CH4:11100000
CH5:11101000
CH6:11110000
CH7:11111000

「<<=」は「左にずらす」という意味だと思います。

0x80は、10000000
commandout & 0x80で8桁目が1かどうかを判別し、
1の場合、DINをHIGH→CSをHIGH→CSをLOW
0の場合、DINをLOW→CSをHIGH→CSをLOW

「& 」は一桁ずつ見比べて、両方1なら1、それ以外は0としているのだと思います。
0x80は8桁目以外は、全部0です。
9桁より上はないのですが、なくても0という取扱になっています。
なので、
「110000000 & 0x80」は「010000000」
「1100000 & 0x80」は「00000000」
ということになり、結果的に8桁目が0か1の判別をしているということになります。

これを、一桁ずつずらしながら、DINに5桁送ります。
11000ならCH0、11111ならCH7といった判断がされているはずです。

以降は一桁ずつ読み出しします。
CLKをHIGH→CLKをLOWというのが、一桁読み出すコマンドで、最初の一桁を無視して、13回繰り返し、12桁読み出します。
DOUTがHIGHなら1、LOWなら0を並べていきます。
全部HIGHの場合、111111111111なので、4095になります。

ということで、

CH0~CH1はセンサーからの入力、
CLK、CS/SHDNは、コマンド入力、
DINに入力することでチャンネルを指定し、
DOUTでデジタルに変換されたアナログデータを受信する

という仕組みになっていることがわかりました。

-Raspberry Pi, ガジェット

Copyright© 自由になりたくて会社辞めました , 2024 AllRights Reserved Powered by AFFINGER4.