【Raspberry Pi】アナログ入力をする方法(MCP3008)

この記事はこんな人におすすめ
  • ラズパイで手っ取り早く「アナログ入力」する方法を知りたい人
  • サンプルコードが見たい人
  • MCP3008の使い方が知りたい人

こんにちは! けい(Twitter)です。

今回は、ラズパイでアナログ入力する方法、サンプルコードをまとめました。

アナログ入力とは

ラズパイはアナログ入力非対応

入力には、「アナログ入力」と「デジタル入力」があります。

ラズパイのgpioにはデジタル入力の機能はありますが、アナログ入力の機能は備わっていません。

ここで言うデジタルとは0V[0]または3.3V[1]の2値でしか扱えないということで、アナログとは、0~3.3Vの間で細かい変化を扱えるということです。

A/D変換でアナログ入力する

いきなりですが、この世界の物理現象は、すべてアナログです。
例えば、定規で物の長さを測る場合、一番細かくまで測定しようと思うと、無限に続く数字になります。

このような無限長のアナログ値を、ラズパイでは扱うことができません。
そのため電圧の値を、アナログからデジタルに近似する必要があります。

それがA/D変換と呼ばれるもので、A/Dコンバーターを使えば、ラズパイにアナログ値をデジタル値に近似した「アナログ入力」をすることができます。

ハードウェア構成

必要な物

ラズパイ本体

ここではラズパイ4としましたが、お持ちのどんなラズパイでも大丈夫です。

MCP3008

これがA/D変換コンバーターで、アナログ入力をするために必要な部品です。

可変抵抗

こちらは、アナログ入力ができているかどうかを試すために必要な物です。

回路図

mcp3008のピン配置は下の図のようになっています。

mcp3008は、最大8つのアナログ入力を同時にすることができます。

今回は、2つのチャンネルを使います。(CH0, CH1)
つまり、2つのアナログ入力をします。

mcp3008とラズパイのピンは下の表のように繋ぎました。

mcp3008のピンラズパイのピン
VDD(16)3.3V(1)
VREF(15)3.3V(1)
AGND(14)GND(6)
CLK(13)GPIO11(23)
DOUT(12)GPIO9(21)
DIN(11)GPIO10(19)
CS/SHDN(10)GPIO8(24)
DGND(9)GND(&)

回路図の全体像です。mcp3008に加え可変抵抗も繋いでいます。
可変抵抗の真ん中のピンをmcp3008のCHピンに繋ぎます。

ソフトウェア

mcp3008のライブラリ

pythonのgpiozeroというパッケージにmcp3008が入っています。

それを使えば簡単にmcp3008でアナログ入力をすることができます。

Raspberry Pi OS(旧Raspbian)を使っていればデフォルトで入っていますが、一応gpiozeroのインストール手順を説明します。

なので、ここは読み飛ばしてもらって結構です。

まずはレポジトリのリストをアップデートします。

$ sudo apt update

続いて、次のコマンドでgpiozeroをインストールします。

$ sudo apt install python3-gpiozero

python2を使っている方は、’3’を消せばオーケーです。

サンプルコード

上の回路図で動作するプログラムを作ったので、コピペして動くかどうか試してみて下さい。

from gpiozero import MCP3008
import time
import csv

def analog_read(channel):
    pot = MCP3008(channel)
    volt = pot.value * Vref
    return volt

Vref = 3.33
NCHANEL = 2

f = open('analog_read.csv' , 'w')

if __name__== "__main__":
    try:
        while True:
            v = []
            for i in range(NCHANEL):
                v.append(analog_read(i))
                print('channel:' + str(i) + '  ' + str(v[i]))
            writer = csv.writer(f)
            writer.writerow(v)
            time.sleep(0.3)
    except KeyboardInterrupt:
        pass
f.close()

プログラム 5~8行目

def analog_read(channel):
    pot = MCP3008(channel)
    volt = pot.value * Vref
    return volt

アナログ入力をする関数です。
channelのとこにチャンネル番号0~8を引数として入力すれば、そこのチャンネルでアナログ値を読み取ってくれます。

プログラム 18~20行目

v = []
for i in range(NCHANEL):
    v.append(analog_read(i))

vという空配列を作り、チャンネル0,1で読み取った値を順に格納しています。

プログラム 13,22,23,27

f = open('analog_read.csv' , 'w')
writer = csv.writer(f)
writer.writerow(v)
f.close()

読み取ったアナログ入力値をcsvファイルで出力します。

プログラムを回してCtrl+Cで終了させると、「analog_read.csv」というファイルができます。

ちなみに、下の図が私が実際にプログラムを回して得られた電圧値です。
実際に2チャンネルでアナログ入力ができていることが分かります。

つまみを回すことで、アナログ入力値が変わっていることが見て取れます。

まとめ

ラズパイの機能にはない「アナログ入力」ですが、結構使う機会があるかと思います。

Arduinoだとデフォルトでアナログ入力がついていますが、やはり何かを入力したいときに、デジタルだけでは不便な時があります。

そんな時はぜひアナログ入力を使ってみて下さい。

ではまた!