Raspberry Pi Zero WにはArduinoのようなアナログ入力ピンを持っていません。そのため、センサー出力などのアナログ値を知る(測る)には外付けでADコンバータを使う必要があります。
ここでは8ピンパッケージでSPIシリアルインターフェースを持つMCP3002を使ってアナログ電圧を読み取るPythonプログラムの例を示します。
MC3002の概要
MCP3002は2チャネルのアナログ入力、分解能は10ビット、電源電圧は2.7V-5.5V(基準電圧VREFと共用)、そしてマイコンとはSPIシリアルインターフェースで通信可能なデバイスです。データシートは秋月電子通商の商品ページのリンクを参照。
MCP3002のRaspberry Pi Zero W(以下Pi Zero)とのデータの送受信のタイムチャートです。なお、このタイムチャートはSPIのモード0になります。
動きとしては、Pi Zeroからはじめの8ビットデータの上位5ビットで通信の開始とMCP3002の動きを設定するConfigurationを送出し、次の8ビットで ダミーデータを送出すると、MC3002からAD変換後の10ビットのデータが送出されます(正確には最初のクロックの7番目と8番目に同期してAD変換のデータのB9とB8を、次の8個のクロックに同期してB7-B0が送出される)。
データのフォーマットは以下になります。
回路図
MCP3002の動作の確認を可変抵抗(10kΩ)を使って、AD変換した結果をコンソールに表示して行います。
以下はその回路図でアナログ入力はシングルエンド、入力チャネルはCH0、そして電源電圧はPi Zeroの3.3Vとします。
ソース・コードと解説
ソース・コードは以下になります。ファイル名はtest13.pyとしています。
#!/usr/bin/python import spidev # spidevライブラリの読み込み import time # timeライブラリの読み込み cfg = 0x68 # |START|SGL|SIGN|MSBF| # | 1 | 1 | 0 | 1 | spi = spidev.SpiDev() # spidevのインスタンス化 spi.open(0,0) # CE0を指定 spi.max_speed_hz = 1200000 # 転送速度を1.2MHzに設定 spi.mode = 0b00 # SPIモード0 try: while True: adcd = spi.xfer2([cfg, 0x00]) # Configuration Bitsの送出と変換データの受信 data = ((adcd[0] & 3) << 8) + adcd[1] # データを10bitにまとめる print("Data:",data) time.sleep(1) except KeyboardInterrupt: spi.close() # SPI通信を終了
ちょっと解説します。
アナログ入力がシングルエンド、入力チャネルがCH0そしてデータの出力フォーマットをMSBファーストに設定するのをスタートビットを含め
cfg = 0x68
とし変数cfgに代入しています。
spi.max_speed_hz = 1200000
で、クロック周波数を1.2MHzにしています。MCP3002のクロック周波数は電源電圧が5Vの時は最大3.2MHzで2.7Vの時は最大1.2MHzとなっているので、今回3.3Vで使っていますが余裕をみて1.2MHzとしました。
adcd = spi.xfer2([cfg, 0x00])
は、MCP3002に0x68とダミーデータ0x00を送信して、リスト変数adcdにAD変換データを取得しています。リスト変数adcdの要素adcd[0]にはAD変換データの最初の8ビットが、要素adcd[1]には2番目の8ビットが格納されます。これは、そういうものだと理解すれば良いと思います。
data = ((adcd[0] & 3) << 8) + adcd[1]
は、ぱっと見わかりづらいですが、以下の処理を行なっています。
- adcd[0]と0b00000011の論理積をして上位の6ビットを0として下位2bitのデータB9、B8(AD変換データの上位2ビット)を取得
- 取得したデータを8ビット左にシフトして10ビットのデータとしてシフトした右のビットを0にする
- この10ビットのデータとadcd[1]に格納されたAD変換データの下位8ビットを加算してMCP3002のAD変換データを得る
これらの処理を図で示しています。
Raspberry Pi Zero Wとの接続
Pi Zeroとの接続です。
Raspberry Pi Zero W | MCP3002 | |||
/CE0 | GPIO8 | 24 | /CS | 1 |
MOSI | GPIO10 | 19 | DIN | 5 |
MISO | GPIO9 | 21 | DOUT | 6 |
SPICLK | GPIO11 | 23 | CLK | 7 |
3.3V | 17 | VDD/VREF | 8 | |
GND | 20 | VSS | 4 |
ブレッドボードに実装した状態。可変抵抗はBカーブ10kΩでその1番ピンをVDDに、3番ピンをGNDにそして2番ピンをMCP3002のCH0に接続しています。
動作確認結果
動作確認をします。プログラムは以下のコマンドを入力します。
$ python test13.py
アナログ入力電圧をAD変換したデータをコンソールに表示した結果です。例えば617の時の電圧値は617×(3.3÷1023)で計算されその値は1.9903となり、また423の時の計算値は1.3645となるので、ほぼテスターで測定した値と等しくなっています。ただしく変換されているのがわかります。
このようにMCP3002等のADコンバータを使うことでセンサーのアナログ出力を利用できるようになりました。