部品屋根性(74) MCP3421、18bit ΔΣADCをRaspberry Piに接続

Joseph Halfmoon

今回はI2Cバスに接続可能なADコンバータです。実験はMicrochip社のMCP3421(最大18bit解像度)です。兄弟チップのMCP3425(最大16bit解像度)もあり、ピンコンパチかつソフトコンパチです。I2Cバスに接続できるのでRaspberry PiのようにADCを持たない機種にも簡単に追加できます。

※「部品屋根性」投稿順Indexはこちら

ADコンバータ、MCP3421とMCP3425

今回のADコンバータはΔΣ式のものです。変換時間はかかるけれども高精度な変換に適する形式です。実験に使用したのはMicrochip 社のMCP3421です。以下に製品ページへのリンクを貼りました。

MCP3421 18-Bit, 240SPS, Single Channel ADC

半導体の製品スペックあるある、かもしれないですが、上記に18bit、240SPS(サンプル毎秒)とあるのは、18ビット・レゾリューションのときに240SPSということではないです。最大精度の18ビットのときには3.75SPSにすぎません。240SPSを達成できるのは12ビットモードのときです。

上記のチップには以下の「兄弟チップ」もあり、今回同時に入手してます。

MCP3425 16-Bit, 240SPS, Single Channel ADC

違いとしては、MCP3421が最大18ビットに対してMCP3425が16ビットということぐらいで、ピンコンパチ、ソフトコンパチに見えます。

どちらも内部に+2.048Vの参照電源(VREF)をもっています。入力は差動電圧入力となっています。変換可能な差動電圧はプラスマイナスVREFの範囲です。また電源は単電源で2.7~5.5Vとなっています。

冒頭のアイキャッチ画像の左がMCP3421で、右がMCP3425です。左のMCP3421は、半田付け下手くそな自分でDIP化基板に半田付けしたもの。右のMCP3425は、秋月電子通商製のDIP化基板に半田付け済のモジュールです。

Raspberry Piへの接続

今回ADコンバータを接続したのは、Raspberry Pi 3 model B+機です。いつもNode-REDの練習などに使っている「サーバ機」です。この装置からはRaspberry Piの3.3VのI2Cバスを5.0Vに変換した信号が出してありその先のIO Expander MCP23017に接続してます。そのバスに接続するためにMCP3421も5V電源としています。また動作確認は、Vin- 端子をGNDに落としてVin+に可変抵抗で電圧を与えています。IO Expander接続回路図の中にMCP3421を付け加えたものが以下に。

MCP3425testCircut

実験用に入力電圧は可変抵抗1個で作っているので、可変抵抗から出力される電圧がVREF超えないように「手加減」してます。

I2Cバス接続確認

I2Cバスの接続確認は何時ものように i2cdetectで行います。こんな感じ。i2cdetect

デバイスが2個みえてますが、0x68の方が、MCP3421です。もう1個の0x20はIO Expander MCP23017です。なお、MCP3421のI2Cバスのアドレスは工場オプションで0x68~0x6Fのどこかになるみたいです。パッケージのマーキング(冒頭のアイキャッチ画像左側)を見るとCAで始まっており、CAで始まっているチップはアドレス0x68になるようです。

動作確認

いつものようにPythonで、動作確認用のコードを書いて済ませようとしてチョイと困りました。いつも Raspberry Pi からI2Cバスを制御する際には

smbus

というモジュールを使用させてもらってます。勝手な理解でホンワカしたことを書いてしまうと、smbusはI2Cバスとは違う仕様ではあるものの、サブセット的な位置にあるのでsmbusで制御できるならOKと。

しかし、今回のMCP3421(またはMCP3425)を制御する場合、smbusモジュールが用意してくれている制御用の関数は不適合に見えました。知らんけど。

そこでRaspberry Pi 3 model B+にインストール済であった pigpio を使用して動作確認いたしました。pigpioは良いものなのですが使用しなくなっていた理由は以下です。

    • pigpioデーモンを動かしておかないとならない
    • pigpioデーモンを生かしておくとpigpio以外のモジュールで制御できなくなる
    • Node-REDのRpi-gpioノードなどは他の制御モジュールを使う前提なので多分共存できない(エラーになるのを確かめてないけど)

pigpioデーモンにお願いすればいろいろ出来るのだけれども、皆がデーモンにお願いするのに賛成しているわけでないので封印していたと。

しかたないので、久しぶりにデーモンを呼び出します。

sudo pigpiod

何の断りもなくただプロンプトに戻ってきますが、これでデーモンがメモリ上に常駐しています。

さて動作テスト用のスクリプトが以下に。動作は以下です。

    1. 16ビットモード(デフォルトは12ビット)に設定
    2. ADCからは毎回3バイト読み出す。最初の2バイト(16ビット)がAD変換値。末尾1バイトがコンフィギュレーション値。
    3. 読み出しは3秒毎、20回繰り返す。

ボリュームを捻れば入力電圧が変わるのでDMMで入力電圧を確認しながら、そのときの読み出し値を記録するということで。

import pigpio
import time

device = 0x68
pi = pigpio.pi()
handle = pi.i2c_open(1, device)
pi.i2c_write_byte(handle, 0x18)

cnt = 20
while (cnt > 0):
    (count, data) = pi.i2c_read_device(handle, 3)
    print("count: {0} len: {1}".format(count, len(data)))
    if len(data) == 3:
        print("Data: {0} ".format(data[0]*256+data[1]))
        print("CONTROL: {0:02x}".format(data[2]))
    cnt -= 1
    time.sleep(3)

pi.i2c_close(handle)

さて上記のスクリプトを走らせたところが以下に。Data:とあるところが読み出し値です。count:3 len:3は、3バイト読み出し試みて3バイト返ってきたということを示しており。CONTROL: 18(16進)は、16ビットモードで連続変換動作していることを示しているので目論見どおりです。

$ python3 Pi3_i2cMCP3425.py
count: 3 len: 3
Data: 28389 
CONTROL: 18
count: 3 len: 3
Data: 28388 
CONTROL: 18
count: 3 len: 3
Data: 28388 
CONTROL: 18
count: 3 len: 3
Data: 28386 
CONTROL: 18
count: 3 len: 3
Data: 28386

上のスクリプトを走らせ、ボリュームを捻りながら電圧測定して描いたグラフが以下に。いい加減だけれども。Graph

このくらい遠くから見ると「線形」にしか見えませんな。AD変換できているんでないの。でもなあ、pigpioデーモン様にお願いしていると既に動いている他の人たちが動かなくなってしまう、多分。pigpio使わずに測定できるようにしないとダメかも。これまたメンドイ。

部品屋根性(73) ATM0130B3、カラー液晶ディスプレイ240×240バックライト付 へ戻る

部品屋根性(75) MCP3421、ADCのラズパイI2C接続、Pythonで制御の続き へ進む