5ドル!ラズパイ・ゼロ(Raspberry pi Zero)でIoT (7) A-Dコンバータの利用4 MCP3425

16ビットA-DコンバータMCP3425

 連載の4回目、アナログ・データをディジタルに変換するために、I2CインターフェースのMCP3424を用いました。ここでは、12ビットA-DコンバータMCP3425を利用します。DIP化ボードが秋月電子通商から出ています(MCP3425(16Bit ADC I2C 基準電圧内蔵)搭載モジュール)。

 購入時にはDIP化された6ピンのボードとリード線が入っているので、はんだ付けします。

MCP3425の主なスペック

  •  ビット数;16
  •  基準電圧;2.048V内蔵
  •  電源電圧; 2.7~5.5V
  •  入力;差動
  •  増幅器;プラグラマブル前置アンプ内蔵(PGA)。1倍、2倍、4倍、8倍から選択
  •  変換方式;ΔΣ(デルタ・シグマ)方式
  •  変換速度;15 SPS (16ビット)、60 SPS (14ビット)、240 SPS (12ビット)から選択

  •  インターフェース;I2C
  •  I2Cデータ転送速度;standard (100 kHz)、fast (400kHz)、high-speed (3.4 MHz)モードのいずれか
  •  I2Cのスレーブ・アドレス;1101000 0x68固定です。

コンフィギュレーション・レジスタ

 プログラムの最初で、コンフィギュレーション・レジスタを設定します。

  • bit7 /RDY。'1'で変換開始
  • bit6、bi5 チャネル・セレクト。使われない
  • bit4 変換モード。1;ワンショット、0;連続
  • bit3、bit2 サンプルレート。10;15 SPS (16ビット)、01;60 SPS (14ビット)、00;240 SPS (12ビット)
  • bit1、bit0 PGA。00 = 1倍(デフォルト)、01 = 2倍、10 = 4倍、11 = 8倍
例;チャネル1、16ビット、アンプの増幅度1;10011000

 

●読みだしたコードの順番

 最上位ビットが符号です。

  • 16ビット;2バイト、 D14 ~ D8 (1st data byte) - D7 ~ D0 (2nd data byte) 
  • 14ビット;MMD12D ~ D8 (1st data byte) - D7 ~ D0 (2nd data byte) Mは最上位ビットがコピーされる
  • 12ビット;MMMMD10 ~ D8 (1st data byte) - D7 ~ D0 (2nd data byte)

プログラム例 16ビット

 2017年8月現在、RASPBIAN JESSIE WITH DESKTOPのカーネルを確認します。

uname -a
4.9.40

 インストールされているPythonのバージョンを調べます。

python -V
2.7.9

 インストールされているPython用I2Cライブラリを調べます。smbusはintelの呼び名で、Philipsの呼び名はI2Cです。

dpkg -l
python-smbus 3.1.1+svn-2

 i2c-toolsも入っています。最初は、このツールを使います。

 ラズパイとMCP3425をI2Cで接続します。Vin-とVin+は差動の入力なので、測定したいところにつなぎます。VDDは1番の3.3Vへ、Vssは6番のGNDにつなぎます。

 Raspberry Piは、最初に、I2Cを利用する設定が必要です。メニューのPreferencesから、Raspberry Pi Configurationを開きます。

 I2CのEnabledにチェックを入れ、再起動します。

 swap16関数は、read_word_data()で読んだデータの上位と下位バイトが逆に収納されているので、入れ替えます。sign16関数は、読み出したデータが2の補数形式のため、符号付き16ビットを10進数に変換します。差動入力の状態で入力信号を入れると、負の電圧も正常に計算します。

#!/usr/bin/env python
import smbus
import time
i2c = smbus.SMBus(1)
addr=0x68
Vref=2.048
config = 0b10011000

i2c.write_byte(addr, config) #16bit
time.sleep(0.2)
def swap16(x):
        return (((x << 8) & 0xFF00) |
                ((x >> 8) & 0x00FF))
def sign16(x):
        return ( -(x & 0b1000000000000000) |
                (x & 0b0111111111111111) )
#main
while 1:
        data = i2c.read_word_data(addr,config)
        raw = swap16(int(hex(data),16))
        raw_s = sign16(int(hex(raw),16))
        volts = round((Vref * raw_s / 32767),4)
        print (volts)
        time.sleep(1)

実行例

 プログラムをmcp3425.pyとして保存します。File Managerでこのファイルをマウスで選択し、右クリックでサブメニューを出し、一番下にあるProperitesを選びます。Permissionsのタブの中から、ExecuteをOnly ownerに変更します。これで、実行権が付きました。

 ターミナルから、python mcp3425.py で実行します。

 電圧発生器(Takedariken TR6142)の出力に、A-Dコンバータの入力につなぎ、電圧を変化させます。

  実行結果です。

 ここに掲載したプログラムは動作検証用です。エラー処理や、精度は考慮していません。