Raspberry Pi Pico(d_26)MCP3208 A/D変換
MCP3208 A/D (SPI)
MCP3208はMicrochip社の分解能12bit、8チャンネルA/Dコンバータです。SPI通信で制御します。
Raspberry Pi PicoでMCP3208を使ってみました。
記事(d_07)のMCP3008とほぼ同じです。
MCP3008はADCの分解能が10bitに対して、MCP3208は12bitになっています。PIN配置も同じです。
※Microchip社のデータシートより引用
接続例
MCP3208の動作電圧が2.7~5.5VなのでRaspberry Pi Picoの3.3Vから供給できます。
SPI通信はGP12(SPI1 RX)、GP13(SPI1 CSn)、GP14(SPI1 SCK)、GP15(SPI1 TX)を使いました。MCP3208のDOUTとRX、CS/SDNとCsn、CLKとSCL、DINとTXを接続しました。
可変抵抗で調整した2Vを4分割してMCP3208のCH0~CH3に入力しました。
MCP3208の説明
データシートから抜粋してMCP3208の説明します。
SPI通信は以下のようになっています。CS=’0’でアクティブです。3bytesを伝送します。
下方のスクリプトでは、送信データbuf=bytearray(3)、受信データr_buf=bytearray(3)を
spi.write_readinto(buf, r_buf)
で行っています。
送信データはStartBit’1’、ControlBit(|SGL/DIFF|D2|D1|D0|)を送ります。
SGL/DIFFは測定モードでsingle-ended’1’、differntial’0’です。
|D2|D1|D0|はADCのChannel CH0-CH7(Pin 1-8)です。
※詳細はデータシートを参照ください。
送信データbufを
buf[0]=(0b100)|(SGL/DIFF)<<1)|(|D2|D1|D0|>>2)
buf[1]=(|D2|D1|D0|<<6) & 0xc0
buf[2]=0x00
としました。
12bitのADCデータは受信データr_bufから
(r_buf[1] & 0x0f) << 8 | r_buf[2]
で得られます。
この値にVREF/4096を乗じて電圧値に換算します。※VREFとVDD(3.3V)を接続しています。
※ Microchip Technology MCP3208のデータシートから抜粋
スクリプト
MCP3208のスクリプトは以下のようにしました。
※開発環境はThonnyです。ThonnyでMicroPythonをRaspberry Pi Pico with RP2040にインストールして使っています。
※Raspberry Pi Pico単独で動作させるには’main.py’としてRaspberry Pi Picoにuploadして使います。
pico_MCP3208_test_01b.py
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from machine import SPI, Pin
# MCP3208 2.7V 8-Channel 12-Bit A/D Converters with SPI Serial Interface
LSB=3300/4096 #3300mV/12bit
#Chip Select Pin
CS_pin=Pin(13, mode=Pin.OUT, value=1) #CS GP1
#spi.init
spi = SPI(1, baudrate=100_000,sck=Pin(14), mosi=Pin(15), miso=Pin(12))
# Chip Select CS(0)
def CS(dat):
CS_pin.value(dat)
# num=Channel conf=single-ended(1)/differential(0)
def r_CHN(num, conf=1):
CS(1)
buf=bytearray(3)
# |Start bit(1)|SGL/DIFF(1/0)|D2|(|D2|D1|D0|>>2)
buf[0]= 4|(conf<<1)|(num>>2)
#|D1|D0|X|X|X|X|X|X|
buf[1]=(num<< 6) & 0xc0 #0b11000000 = 0xc0
buf[2]=0x00 # don't care
r_buf=bytearray(3)
CS(0)
spi.write_readinto(buf, r_buf)
CS(1)
data=(r_buf[1] & 0xf) << 8 | r_buf[2] #0b1111(15)0xf
data=data*LSB # mV
print('CH%d='% num, '%5.1f(mV)'%data )
return #data
## example
CS(1) # CS='1' SHDN
#r_CHN(num, conf=1) Channel_num,SGL(default=1)/DIFF(0)
# 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
関数 部分説明
r_CHN(num, conf=1)
num:測定Channelです。 0~7
conf:測定モードです。single-ended(1)、differential(0)
実行結果
結果は以下のようになりました。※Thonnyのshellに表示されます。
各CHは2.0V/4=500mVになっています。正常に測定できているようです。
>>> %Run -c $EDITOR_CONTENT
CH0= 2050.4(mV)
CH1= 1536.4(mV)
CH2= 1025.6(mV)
CH3= 507.6(mV)
CH0= 511.6(mV)
CH2= 510.0(mV)
CH3= 0.0(mV) #マイナスになるので
>>>
まとめ
Raspberry Pi PicoでMCP3208を使ってD/A変換ができました。