稼働中

マイクロビット(e_47)MCP3208 A/Dコンバータ SPI

MCP3208 8CH 12Bit ADC

Microchip社のMCP3208をmicro:bitで使ってみました
「MCP3208」は分解能12bitの8チャンネルのA/Dコンバータです。SPI通信で制御します。
2.7~5.5Vで動作します。詳細はデーターシート等を参照ください。
分解能10bitの8チャンネルのA/DコンバータMCP3008については(e_31)の記事で記載しました。
MCP3008がADCの分解能が10bitに対して、MCP3208は12bitになっています。PIN配置は同じなので(e_31)の記事とほぼ同じです。
そのため、接続図や実体図などは省略してスクリプトとSPIの送受信の部分を記載することにしました。
MCP3208 PIN配置
※Microchip社のデータシートより引用

スクリプト

スクリプトは以下のようにしました。※thonny-microbitのMicroPythonを使っています。


#!/usr/bin/env python
# -*- coding: utf-8 -*-
from microbit import *
#spi.init(baudrate=1000000, bits=8, mode=0, sclk=pin13, mosi=pin15, miso=pin14)
spi.init()

LSB=3300/4096       # Vref(mV)/12bit
# chip select
CS_pin=pin16        # Chipselectにmicro:bitのpin16を使う

# CS=L(0) Chip Select
def CS(dat):
    CS_pin.write_digital(dat)

# num=channel conf=single(1)/diff(0)
def r_CHN(num, conf=1):
    CS(1)
    buf=bytearray(3)
    # |Start bit='1'|SGL/DIFF=1/0(conf)|D2|
    buf[0]= 4|(conf<<1)|(num>>2) # |D2|D1|D0|>>2 |0|0|D2|
    #|D1|D0|X|X|X|X|X|X| 
    buf[1]=(num<< 6) & 0xc0  #0b11000000 hex(192)= 0xc0
    buf[2]=0x00     # don't care
    #print(buf)

    r_buf=bytearray(3)
    #spi.write(buf)
    #spi.write_readinto(out, in)
    CS(0)
    spi.write_readinto(buf, r_buf)
    #print('r_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
    
# MCP3208 ADC TEST 
r_CHN(0)    # CH0 single-ended(1 default)
r_CHN(1)
r_CHN(2)
r_CHN(3)

r_CHN(0,0)  # CH0=IN+ CH1=IN- DIFF(0)
r_CHN(1,0)  # CH0=IN- CH1=IN+ DIFF
r_CHN(2,0)  # CH2=IN+ CH3=IN- DIFF
r_CHN(3,0)  # CH2=IN- CH3=IN+ DIFF

MCP3208のSPI通信

MCP3208のSPI通信の部分だけ記載します。他はMCP3008の(e_31)の記事を参照ください。
MCP3208におけるSPI通信は以下の図のようになっています。
micro:bitではspi.write_readinto(buf, r_buf)を使ってデータの送受信をします。
SPI通信
※Microchip社のデータシートに赤枠などを追加しています。

送信データは3bytesです。後に示すスクリプトでは buf=bytearray(3)になります。
図中に記入したbuf[0]、buf[1]、buf[2]に各々データを代入します。

|D2|D1|D0|は測定するチャンネルです。CH0~CH7(num)にあたります。
SGL/DIFF single-ended/differential(conf)は入力モードです。1/0にあたります。
(内)はスクリプトでの変数名です。

|D2|D1|D0|がbuf[0]、buf[1]に分かれるのでややこしいのですが、スクリプト内では以下のようにしました。
buf[0]= 4|(conf<<1)|(num>>2)
buf[1]=(num<< 6) & 0xc0
buf[2]=0x00

受信データも3bytesです。スクリプトでは r_buf=bytearray(3)に格納されます。
12bitデータはr_buf[1]の下4bitとr_buf[2]をつないだデータになります。スクリプト内では以下のようにしました。
data=(r_buf[1] & 0xf) << 8 | r_buf[2]

実行結果

ThonnyのShellに表示されます。
(e_31)の記事と同様に2Vを抵抗で4分圧してCH0~CH3に入力しました。ADC測定できているようです。


>>> %Run mcp3208_test01.py
CH0= 2043.1(mV)
CH1= 1526.7(mV)
CH2= 1010.3(mV)
CH3= 510.7(mV)
CH0= 512.4(mV)
CH1=   0.0(mV)      # diff 極性が逆
CH2= 503.5(mV)
CH3=   0.0(mV)      # diff 極性が逆
>>>

まとめ

micro:bitでMCP3208を使ったA/D変換を確認しました。