Raspberry Pi Pico(d_07)MCP3008 A/D変換
MCP3008 A/D (SPI)
Microchip社のMCP3008は分解能10bitの8チャンネルのA/Dコンバータです。SPI通信で制御します。
Raspberry Pi PicoでMCP3008を使ってみました。
※micro:bitの記事(e_31)からRaspberry Pi Picoで使えるように追記、修正しました。
外観
MCP3008の外観写真とピン配置です。※ピン配置はMicrochipのデータシートより抜粋
接続図
MCP3008の動作電圧が2.7~5.5VなのでRaspberry Pi Picoの3.3Vから供給できます。
SPI通信はGP0(SPI0 RX)、GP1(SPI0 CSn)、GP2(SPI0 SCK)、GP3(SPI0 TX)を使いました。MCP3008のDOUTとRX、CS/SDNとCsn、CLKとSCL、DINとTXを接続しました。※RX(MISO),TX(MOSI)
デバイスデータシートの説明
MCP3008の送受信
MCP3008のADCデータを得るタイミングチャートは下図になります。データシートから抜粋しています。
送受信は大雑把には以下のような感じです。送受信②③は図のように並行して進んでいます。
SPI.write_readinto(buf, read_buf)を使って送受信します。
①デバイスを選択します。
CSを’0’にしてMCP3008を選択します。
②送信信号を送ります。
送信データは3bytesです。スクリプトではbuf=bytearray(3)としました。
StartBitと測定モード、チャンネル情報を送ります。
buf[0] StartBit’0b00000001(0x01)’
buf[1] 測定モードと測定チャンネルを示す|SGL/DIFF|D2|D1|D0|X|X|X|X|を送ります。
buf[2] |X|X|X|X|X|X|X|X| を送ります。
スクリプトでは’X=0’にしています。
③受信信号が戻ります。
受信データも3byteです。スクリプトではr_buf=bytearray(3)としました。
Nullと10bit(B9~B0)データが返ります。
r_buf[0] | ?| ?| ?| ?| ?| ?| ?| ?|
r_buf[1] | ?| ?| ?| ?| ?| 0|B9|B8|
r_buf[2] |B7|B6|B5|B4|B3|B2|B1|B0|
使用するのはr_buf[1]とr_buf[2]です。
スクリプトでは(r_buf[1] & 3) << 8 | r_buf[2]で|B9|B8|B7|B6|B5|B4|B3|B2|B1|B0|の10bitデータにしています。
測定モードと測定チャンネルを示すControlBit(|SGL/DIFF|D2|D1|D0|)は以下のようになっています。
スクリプトでは|SGL/DIFF|の値をconf、チャンネル番号をnumとして、先のbuf[1]を
buf[1]=(conf<<3 | num) <<4 で得ています。
スクリプト
スクリプトは以下のようにしました。
※開発環境はThonnyです。ThonnyでMicroPythonをRaspberry Pi Pico with RP2040にインストールして使っています。
pico_mcp3008_b2.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from machine import SPI, Pin
# MCP3008 2.7V 8-Channel 10-Bit A/D Converters with SPI Serial Interface
LSB=3300/1024 #3300mV/10bit
#Chip Select Pin
CS_pin=Pin(1, mode=Pin.OUT, value=1) #CS GP1
#spi.init
spi = SPI(0, baudrate=1000_000,sck=Pin(2), mosi=Pin(3), miso=Pin(0))
# Chip Select CS(0)
def CS(dat):
CS_pin.value(dat)
#CS_pin(dat)
# SGL/DIFF D2 D1 D0 XXXX conf=single(1)/diff(0)
def r_CHN(num, conf=1):
CS(1)
buf=bytearray(3)
buf[0]=0x01
buf[1]=(conf<<3 | num) <<4 # control bit single/diff|D2|D1|D0|X|X|X|X|
buf[2]=0x00
#print(buf)
r_buf=bytearray(3)
CS(0)
spi.write_readinto(buf, r_buf)
CS(1)
data=(r_buf[1] & 3) << 8 | r_buf[2]
data=data*LSB
print('CH%d='% num, '%5.1f(mV)'%data )
return data
# TEST ADC
CS(1) # CS='1' SHDN
# Single
r_CHN(0) # CH0
r_CHN(1) # CH1
r_CHN(2) # CH2
r_CHN(3) # CH3
# Diff
r_CHN(0,0) # CH0=IN+ CH1=IN-
r_CHN(2,0) # CH2=IN+ CH3=IN-
r_CHN(3,0) # CH2=IN- CH3=IN+
CS(1) # CS='1' SHDN
実行結果
結果は以下のようになりました。※ThonnyのShellに表示されます。
2Vを4分圧しているので500mVづつ変わるハズです。測定できているようです。
pico_mcp3008_b2.py
>>> %Run -c $EDITOR_CONTENT
CH0= 2065.7(mV)
CH1= 1534.0(mV)
CH2= 1031.3(mV)
CH3= 528.5(mV)
CH0= 551.1(mV) # CH0=IN+ CH1=IN-
CH2= 512.4(mV) # CH2=IN+ CH3=IN-
CH3= 0.0(mV) # CH2=IN- CH3=IN+ 負になるので
>>>
まとめ
Raspberry Pi PicoでMCP3008を使ってA/D変換の測定ができました。