Raspberry Pi 3を使って、アナログ信号をデジタル信号に変換するプログラムを作成します。A/D変換には、メカトラックス社のラズベリーパイ用高精度A/D変換モジュール「ADPi Pro」を使用します。ADPi Proは、24bit分解能のAnalog Devices社「AD7794」を使用し、温度特性に配慮した外部基準電圧発生ICの搭載し、出荷時校正データを格納した「EEPROM」により、A/D変換したデータを補正します。
ADPi Proは、SPIインタフェースとIIOサブシステムにより接続可能で、SPIインタフェースを使用するときはSPIを用いたラズベリーパイ用高精度A/D変換モジュール「ADPi Pro」のセットアップ、IIOサブシステムを使用するときはIIOサブシステムを用いたラズベリーパイ用高精度A/D変換モジュール「ADPi Pro」のセットアップに従って、それぞれセットアップします。
実際にADPi Proに分圧した1Vのアナログ電圧を入力して、Raspberry Pi 3でA/D変換値を取得する動作環境の様子を次に示します。なお、ADPi Pro の資料は、ADPi Pro(ラズベリーパイ用高精度 A/D 変換モジュール)に公開されています。
作成したプログラムを確認するための1Vのアナログ電圧は、ADPi Proのターミナルブロック4個の差動電圧入力「Vin+」「Vin-」のそれぞれに、5Vを5個の抵抗で分圧した「1V」を次ように接続します。
#SPIを用いたADPi Proによる計測
ADPi ProをSPIデバイスとして動作させ、ADPi Proのターミナルブロックに接続されたアナログ電圧値をA/D変換して入力するpythonスクリプトを作成します。なお、SPIを用いたADPi Proのセットアップについては、ADPi Proのセットアップ(SPI)に示します。
##SPIを用いたADPi ProのPythonスクリプトの作成
ADPi Proに接続されたアナログ電圧を、SPIインタフェースを使ってA/D変換値を入力し、変換した値に対して補正を行うPythonスクリプトを作成します。
- Python3 により SPI 通信でADPi ProのA/D変換器「AD7794」をアクセスするために、spidevパッケージを使用します。
- Python3 により I2C通信でADPi Proの出荷時校正データ「EEPROM」をアクセスするために、smbusパッケージを使用します。
- adpiパッケージは、ADPi Proを構成する24bit分解能のA/D変換器「AD7794」、出荷時校正データを格納する「EEPROM」、GPIO エキスパンダ「MCP23008」を制御するPythonスクリプトクラスで、Pythonスクリプトのコードをpython-adpiに示します。
- get_voltage関数は、adpiクラスのインスタンスとA/D変換するチャンネル番号をパラメータにし、チャンネル番号に対応するターミナルブロックに接続されたアナログ電圧値を、single_conversion関数を用いて取得し、取得したデータから対応するチャンネルの入力電圧を計算して、その計算結果を文字列変換して関数の戻り値とします。
- single_conversion関数は、入力電圧のスケール値とその生の電圧値を取得します。
#!/usr/bin/python3
import spidev
import smbus
import adpi
import sys
from time import sleep
RAW_OFFSET = (1 << 23)
RAW_SCALE = (
0.000596040,
0.000298020,
0.000149010,
0.000074500,
0.000037250,
0.000018620,
0.000009310,
0.000004650,
)
TEMP_VREF = 1.17
def v2k(rate, val):
for k, v in rate.items():
if v == val:
return k
def single_conversion(dev, ch):
c = dev.adc.channel[ch]
g, _ = dev.read_configuration()
dev.write_configuration(g, c)
_, r = dev.read_mode()
dev.write_mode(dev.adc.mode['single'], r)
rate = v2k(dev.adc.rate, r)
while True:
sleep(2 * 1.0 / float(rate))
if not dev.read_status() & 0x80:
break
raw = dev.read_data()
return raw, g
def get_voltage(dev, ch):
raw, g = single_conversion(dev, ch)
vol = RAW_SCALE[g] * (raw - RAW_OFFSET)
return "Ch {} : {:.9f}".format(ch,vol)
if __name__ == "__main__":
spibus = 0
spics = 0
eeprombus = 1
eepromaddr = 0x57
gpiobus = 1
gpioaddr = 0x27
spi = spidev.SpiDev()
i2c = smbus.SMBus(eeprombus)
try:
spi.open(spibus, spics)
spi.mode = 0b11
spi.max_speed_hz = 1000000
ad = adpi.ADPiPro(spi, i2c, eepromaddr, gpioaddr)
print(get_voltage(ad, "1"))
print(get_voltage(ad, "2"))
print(get_voltage(ad, "3"))
print(get_voltage(ad, "4"))
except (IndexError, ValueError):
sys.exit(2)
finally:
spi.close()
##作成したPythonスクリプトの実行
作成したPythonスクリプトを次のコマンドで実行すると、4チャンネル分のA/D変換値が表示されます。
$ python3 adpispisample.py
Ch 1 : 1005.942668400
Ch 2 : 1005.440802720
Ch 3 : 1006.350359760
Ch 4 : 1005.499810680
#IIOサブシステムを用いたADPi Proによる計測
ADPi ProをIIO サブシステムとして動作させ、ADPi Proのターミナルブロックに接続されたアナログ電圧値をA/D変換して入力するシェルスクリプトを作成します。なお、IIOサブシステムを用いたADPi Proのセットアップについては、ADPi Proのセットアップ(IIOサブシステム)に示します。
##IIOサブシステムを用いたADPi Proのシェルスクリプトの作成
ADPi Proに接続されたアナログ電圧を、IIOサブシステムを使ってA/D変換値を入力し、変換した値に対して補正を行うシェルスクリプトを作成します。シェルスクリプトは、IIO サブシステムに示すIIO サブシステムを用いて、ADPi Pro に搭載された ADC へアクセスします。
- 「
cat ${IIO_PATH}/in_voltage${idx}-voltage${idx}_offset
」により、チャンネルに対応したオフセット値を取得します。 - 「
cat ${IIO_PATH}/in_voltage-voltage_scale
」により、入力電圧のスケール値を取得します。 - 「
cat ${IIO_PATH}/in_voltage${idx}-voltage${idx}_raw
」により、チャンネルに対応した生の電圧値を取得します。 - get_voltage関数は、A/D変換するチャンネル番号をパラメータにし、チャンネル番号に対応するターミナルブロックに接続されたアナログ電圧をデジタル変換し、取得した入力電圧のスケール値、オフセット値、生の電圧値からチャンネルごとの入力電圧を計算して表示します。
#!/bin/bash
set -e
LIB_PATH=/usr/lib/adpi-utils-backend-iio/
IIO_PATH=/sys/bus/spi/devices/spi0.0/iio:device0
INDEX_OFFSET=-1
#
# Usage: get_voltage <N>
#
get_voltage ()
{
local idx
local ofs
local scl
local raw
idx=$(($1 + $INDEX_OFFSET))
ofs=$(cat ${IIO_PATH}/in_voltage${idx}-voltage${idx}_offset)
scl=$(cat ${IIO_PATH}/in_voltage-voltage_scale)
raw=$(cat ${IIO_PATH}/in_voltage${idx}-voltage${idx}_raw)
printf "Ch %d : " $(echo $1)
printf "%.9f\n" $(echo "($raw + $ofs) * $scl" | bc -l)
}
#
# execute command
#
status=2
get_voltage 1
get_voltage 2
get_voltage 3
get_voltage 4
status=$?
exit $status
##作成したシェルスクリプトの実行
作成したシェルスクリプトを次のコマンドで実行すると、4チャンネル分のA/D変換値が表示されます。
$ ./adpiiiosample.sh
Ch 1 : 1005.272123400
Ch 2 : 1005.208347120
Ch 3 : 1006.048167480
Ch 4 : 1005.173776800
#ADPi Proに関連する記事
1. SPIを用いたラズベリーパイ用高精度A/D変換モジュール「ADPi Pro」のセットアップ
ADPi ProをSPIデバイスとして動作させ、Python言語で作成されたサンプルスクリプトを実行して、ADPi Proに接続したアナログ電圧のA/D変換値を確認します。
2. IIOサブシステムを用いたラズベリーパイ用高精度A/D変換モジュール「ADPi Pro」のセットアップ
ADPi ProをIIOサブシステムとして動作させ、作成されたサンプルシェルスクリプトを実行して、ADPi Proに接続したアナログ電圧のA/D変換値を確認します。