ラズパイでADコンバーターMCP3008の使い方・SPI通信

ラズパイでADコンバーターMCP3008の使い方・SPI通信
ラズパイでADコンバーターMCP3008の使い方・SPI通信

この記事では、8chで10bitの分解能を持つADコンバーターMCP3008をラズパイで使う方法を解説する。

MCP3008は8chで10bitの分解能を持つADコンバーターだ。MCP3008とはSPI通信でデータをやりとりしていく。

ラズパイとMCP3008の配線


画像の拡大

ラズパイは、Raspberry Pi zero WHを使用した。

ラズパイでSPIを使えるようにする設定が済んでない方は、こちらの記事を参考に設定しておこう。

MCP3008のピン役割

MCP3008の各ピンの役割は次のようになる。

MCP3008名称役割
1CH0アナログ電圧入力
2CH1アナログ電圧入力
3CH2アナログ電圧入力
4CH3アナログ電圧入力
5CH4アナログ電圧入力
6CH5アナログ電圧入力
7CH6アナログ電圧入力
8CH7アナログ電圧入力
9DGNDデジタルGND
10CS/SHDNチップセレクト/シャットダウン
11DinシリアルデータIN
12DoutシリアルデータOUT
13CLKシリアルクロック
14AGNDアナログGND
15Vrefリファレンス電圧
16Vdd電源電圧 (+2.7〜5.5V)

MCP3008データシート

Raspberry PiとMCP3008の配線


画像の拡大

Raspberry PiとMCP3008を次のように配線した。

MCP3008名称ラズパイ物理番号ラズパイ名称
9DGND6GND
10CS/SHDN24CS0 (GPIO 8)
11Din19MOSI (GPIO 10)
12Dout21MISO (GPIO 9)
13CLK23SCLK (GPIO 11)
15Vref173.3V
16Vdd13.3V

ラズパイではSPIで使われるCS・MOSI・MISO、SCLK、それぞれGPIO8・GPIO10・GPIO9・GPIO11に割り当てられているので注意しよう。

ラズパイGPIO役割図
ラズパイGPIO役割図

MOSIとMISO

MOSIMISO はマスターから信号を送るか、スレーブから信号を受け取るかの違いで、MOSIはマスターアウトスレーブイン、MISOはマスターインスレーブアウトの略である。今回の場合、マスターはラズパイであり、スレーブはADコンバーターのMCP3008となる。ラズパイではSPIで使う端子が決まっているので、それに合わせて配線する。

チャネルをどうやって切り替えるのか?

MCP3008 ではコンフィギュレーションビットに送るデータによって、チャネルを選択できるようになっている。下の表はコンフィギュレーションビットの仕様の一部だ。

Single/DiffD2D1D0CH
1000CH0
1001CH1
1010CH2
1011CH3
1100CH4
1101CH5
1110CH6
1111CH7


画像の拡大

今回の用途ではSingle/Diffを1に固定しているが、0に設定すると differential となり、チャネル間での差分信号を読み取れるようである。

詳しくはMCP3008データシートを参照

MCP3008で温度センサーTMP36の電圧を読み取る

温度センサーTMP36のアナログ電圧を、MCP3008で読み取って温度を取得できるプログラムを書いてみた。ただしサンプリングレートを明示してあげないと、うまく動かず正しいデータが取り出せないので注意が必要。MCP3008のサンプリングレートはVddが5Vのとき最大で200ksps、2.7Vの時では75kspsまでとなっている。今回Vddは3.3Vなので、サンプリングレートを100kspsに設定した。

# -*- coding:utf-8 -*-
import time
import spidev

Vref = 3.334  # 電圧をテスターで実測する

spi = spidev.SpiDev()

spi.open(0, 0)  # bus0,cs0
spi.max_speed_hz = 100000  # 100kHz 必ず指定する


def readAdc(channel):
    adc = spi.xfer2([1, (8 + channel) << 4, 200])
    data = ((adc[1] & 3) << 8) + adc[2]
    return data


def convertVolts(data, vref):
    volts = (data * vref) / float(1023)
    return volts


def convertTemp(volts):
    temp = (volts - 0.75) / 0.01 + 25.0
    return temp


if __name__ == '__main__':
    try:
        while True:
            data = readAdc(channel=0)
            volts = convertVolts(data, Vref)
            temp = convertTemp(volts)
            print("CH0 volts: {:.2f}".format(volts))
            print("temp : {:.2f}".format(temp))

            # data = readAdc(channel=1)
            # volts = convertVolts(data, Vref)
            # print("CH1 volts: {:.2f}".format(volts))

            time.sleep(2)

    except KeyboardInterrupt:
        spi.close()

プログラムの解説は次の記事を参考に。

TMP36の使い方はこちらを参考に。

記事に関するご質問などがあればTwitterへお返事ください。
この記事で紹介した商品
人気のラズパイ
人気のラズパイ周辺機器
Raspberry Piのオススメ入門書
関連記事