「カラー図解 最新 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 はチャンネルごとに以下のようになります。
CH1:11001
CH2:11010
CH3:11011
CH4:11100
CH5:11101
CH6:11110
CH7:11111
ビット演算のことがよくわかっていないのですが、「|= 」は「足す」という意味なのでしょう。
commandout <<= 3で、右側に0が3つつきます。
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になります。
ということで、
CLK、CS/SHDNは、コマンド入力、
DINに入力することでチャンネルを指定し、
DOUTでデジタルに変換されたアナログデータを受信する
という仕組みになっていることがわかりました。