稼働中

マイクロビット(e_31)MCP3008 A/D変換

MCP3008 A/D (SPI)

Microchip社のMCP3008をmicro:bitで使ってみました。※thonny-microbitのMicroPythonを使っています。
「MCP3008」は分解能10bitの8チャンネルのA/Dコンバータです。SPI通信で制御します。
※詳細はデーターシート等を参照ください。

外観

MCP3800の外観写真とピン配置です。※ピン配置はMicrochipのデータシートより抜粋
MC3008外観   ピン配置

接続例

MCP3008の電源電圧は2.7V~5.5Vなのでmicro:bitの電源が使えます。
送信するSPIデバイスの選択を行うCS/SHDNはpin16に接続しました。pin16のモードはデジタル出力です。
A/D変換値を確認するために可変抵抗で2.0Vに調整し、抵抗Rで分圧してCH0~CH3に接続しました。
VddとVrefを接続した場合には、
A/D変換の最小値はLSB=Vref/1024なので3300mV/1024(10bit)=3.22mVになります。
接続図
※micro:bitのピン配置図は「https://tech.microbit.org/hardware/edgeconnector/」からの引用です。

実体接続した写真です。
実体図

スクリプト

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


#!/usr/bin/env python
# -*- coding: utf-8 -*-
from microbit import *

LSB=3220/1024       # Vdd(mv) /1024(10bit)
CS_pin=pin16        # CS にpin16を使う

#spi.init(baudrate=1000000, bits=8, mode=0, sclk=pin13, mosi=pin15, miso=pin14)
spi.init()

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

# num:CHの番号、conf:input configuration single(1) differential(0)
def r_CHN(num, conf=1):
    CS(1)
    buf=bytearray(3)        # write-buf 3bytes
    buf[0]=0x01             # start bit
    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)      # read-buf 3bytes 空 2bit 8bit
    #spi.write_readinto(out, in)
    CS(0)
    spi.write_readinto(buf, r_buf)
    CS(1)
    data=(r_buf[1] & 3) << 8 | r_buf[2] #2byte(2bit)+3byte(8bit)>>10bit-data
    data=data*LSB            # mv data 
    print('CH%d='% num, '%5.1f(mV)'%data )           # ADC
    return data
    
# TEST Analog IN single-ended CMD CH0‘1000’ CH1'1001'..
#CS(1)

r_CHN(0) # CH0 ADC input single-ended
r_CHN(1)
r_CHN(2)
r_CHN(3)

SPI通信

MCP3008は下図のようにSPI通信でA/D変換値を送受信します。MicroPythonの「spi.write_readinto(out, in)」を使って制御します。
コントロールビット
コントロールビット
※Microchip MCP3008のデータシートより抜粋

送信データは3byteです。
スクリプトではbuf=bytearray(3)としました。
buf[0]は|0|0|0|0|0|0|0|1| # 0x01
buf[1]は|SGL/DIFF|D2|D1|D0|X|X|X|X| # buf[1]=(conf<<3 | num) <<4
buf[2]は|X|X|X|X|X|X|X|X| # 0x00
スクリプトでは’X=0’にしています。
buf[1]の上位4bitにinputモード(single-ended、differential)とチャンネル数を与えて送信します。

受信データも3byteです。
スクリプトではr_buf=bytearray(3)としました。
r_buf[0]は|?|?|?|?|?|?|?|?|
r_buf[1]は|?|?|?|?|?|0(null)|B9|B8|
r_buf[2]は|B7|B6|B5|B4|B3|B2|B1|B0|
です。
data=(r_buf[1] & 3) << 8 | r_buf[2]で|B9|B8|B7|B6|B5|B4|B3|B2|B1|B0|の10bitデータにしています。

実行結果

可変抵抗で2.0Vに調整し、抵抗Rで分圧してCH0~CH3に接続してテストしました。※ThonnyのShellに表示されます。
やや値に誤差があるようですがA/D変換値が出力できました。


>>> %Run mcp3008_ad_02b.py
bytearray(b'\x01\x80\x00')
CH0= 2015.6(mV)
bytearray(b'\x01\x90\x00')
CH1= 1509.3(mV)
bytearray(b'\x01\xa0\x00')
CH2= 1025.1(mV)
bytearray(b'\x01\xb0\x00')
CH3= 525.1(mV)
>>> 

ちなみにdifferentialで測定すると以下のようになりました。


>>> r_CHN(0,0)                  # Diff CH0=IN+ CH1=IN-
bytearray(b'\x01\x00\x00')
CH0= 528.2(mV)                  # 差分
528.281
>>> r_CHN(1,0)                  # Diff CH0=IN- CH1=IN+
bytearray(b'\x01\x10\x00')
CH1=   0.0(mV)                  # 負になるので
0.0
>>>

まとめ

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