2
0

More than 5 years have passed since last update.

SPI /IIOサブシステムを用いたラズベリーパイ用高精度A/D変換モジュール「ADPi Pro」による計測方法

Last updated at Posted at 2018-08-16

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 変換モジュール)に公開されています。

adpi01.jpg

作成したプログラムを確認するための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関数は、入力電圧のスケール値とその生の電圧値を取得します。
adpispisample.py
#!/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変換するチャンネル番号をパラメータにし、チャンネル番号に対応するターミナルブロックに接続されたアナログ電圧をデジタル変換し、取得した入力電圧のスケール値、オフセット値、生の電圧値からチャンネルごとの入力電圧を計算して表示します。
adpiiiosample.sh
#!/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変換値を確認します。

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0