Raspberry Pi Zero WでPython 〜ADコンバータでアナログ電圧を読む〜

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]

は、ぱっと見わかりづらいですが、以下の処理を行なっています。

  1. adcd[0]と0b00000011の論理積をして上位の6ビットを0として下位2bitのデータB9、B8(AD変換データの上位2ビット)を取得
  2. 取得したデータを8ビット左にシフトして10ビットのデータとしてシフトした右のビットを0にする
  3. この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コンバータを使うことでセンサーのアナログ出力を利用できるようになりました。

スポンサーリンク
スポンサーリンク
スポンサーリンク

シェアする

  • このエントリーをはてなブックマークに追加

フォローする

スポンサーリンク
スポンサーリンク