IIOサブシステムを用いたラズベリーパイ用高精度A/D変換モジュール「ADPi Pro」のセットアップ

Raspberry Pi 3を使って、アナログ信号をデジタル変換して入力してみます。Raspberry Pi 3ではアナログ信号を処理するためにA/D変換モジュールが別途必要で、このために、研究開発・ビジネス用途向けに開発されたメカトラックス社の[ラズベリーパイ用高精度A/D変換モジュール「ADPi Pro」](https://mechatrax.com/products/adpi/)を今回使用します。
ADPi Proは、SPI デバイスとIIO サブシステムの二つのインタフェースを使って、アナログ電圧を入力してA/D変換できます。前回「[SPIを用いたラズベリーパイ用高精度A/D変換モジュール「ADPi Pro」のセットアップ](https://qiita.com/TomoSoft/items/8aee48e685db8ffab3ca)」はADPi ProをSPIデバイスとして動作させたので、今回はADPi ProをIIO サブシステムとして動作させます。ADPi ProのIIO サブシステムは、Industrial I/O Subsystemに準拠したドライバをサポートしており、カーネルの標準機能として組み込まれ，Pythonが不要なこともあり使い方が簡単で応用もききます。
SPIデバイスとして動作させた時と同様に、5Vを5つの抵抗で分圧してADPi Proのターミナルブロックに接続し、メカトラックス社から提供されているシェルスクリプトで作成したサンプルスクリプトを実行して、ADPi Proに接続したアナログ電圧のA/D変換値を確認します。なお、ADPi Pro の資料は、[ADPi Pro（ラズベリーパイ用高精度 A/D 変換モジュール）](https://github.com/mechatrax/adpipro?_ga=2.190419565.739881186.1531101539-1744061270.1449811405)で公開されています。

#_ADPi Proについて_
ADPi Proは、24bit分解能のAnalog Devices社「AD7794」をA/D変換器を使用し、温度特性に配慮した外部基準電圧発生ICの搭載し、出荷時校正データを格納した「EEPROM」により、A/D変換したデータを補正します。

- 入力電圧：0 ～ 5Vの差動入力。リファレンス電圧は基準電圧発生回路を通じて5Vを生成します。
- 分解能	：24ビットの∑∆（シグマ・デルタ）A/Dコンバータ
- 更新レート：4 ～ 470Hz
- 出力電圧：12V、各チャンネルの最大電流50mA。ラズベリーパイ電源用5Vから12Vに昇圧し、センサ用電源としてチャンネル1-4の各ターミナルブロックに割り当てます。

>出力電圧「12V」は、ターミナルブロック「Vout」と「GND」間に出力されます。GPIO エキスパンダにより、チャンネル１からチャンネル4までの出力電圧のON/OFFを制御します。

なお搭載されているAnalog Devices社の「AD7794」の詳細については、[AD7794のデータシート](http://www.analog.com/media/jp/technical-documentation/data-sheets/AD7794_JP.pdf)を参照してください。また、ADPi Proのハードウェアに関しては、[ADPi Proのハードウェア](https://github.com/mechatrax/adpipro/wiki/%E3%83%8F%E3%83%BC%E3%83%89%E3%82%A6%E3%82%A7%E3%82%A2)を参照してください。

実際にADPi Proに分圧した1Vのアナログ電圧を入力して、Raspberry Pi 3でA/D変換値を取得する動作環境の様子を次に示します。

![adpi02.jpg](https://qiita-image-store.s3.amazonaws.com/0/124811/a6259ce6-021d-00c6-021f-e58762770de0.jpeg)


##_ADPi Proの動作環境の構築_
ADPi Proの40ピンコネクタCN3と、Raspberry Pi 3の40ピンコネクタJ8を重ね合わせるように接合します。これにより、Raspberry Pi 3から5Vを給電し、SPIとI<Sup>2</Sup>Cの各インタフェースを使用します。ADPi Pro基板上のジャンパおよびディップスイッチJ1、J2、J3、DIPSW1は初期状態のままです。また、ADPi Proのターミナルブロック4個の差動電圧入力「Vin+」「Vin-」のそれぞれに、5Vを5個の抵抗で分圧した「1V」を次の図のように接続します。なお、抵抗は金属皮膜抵抗器、162Ω、誤差±0.1%を使用しました。

<div align="center" "><img src="https://qiita-image-store.s3.amazonaws.com/0/124811/90f309ed-1b45-fe3f-4359-2f742d7b4883.jpeg"></div>


#_ADPi Proのセットアップ_
今回使用するraspbian「2018-04-18-raspbian-stretch」は、[ラズベリーパイ公式サイト](https://www.raspberrypi.org/downloads/)からダウンロードしました。ADPi ProをシェルスクリプトでアクセスできるIIO サブシステムとするために、このraspbianに、次の手順に従いADPi Proをセットアップします。なお、IIO サブシステムとしてアクセスするADPi Proのセットアップは、[ADPi Proのセットアップ](https://github.com/mechatrax/adpipro/wiki/%E3%83%91%E3%83%83%E3%82%B1%E3%83%BC%E3%82%B8#2-iio-%E3%82%92%E5%88%A9%E7%94%A8%E3%81%99%E3%82%8B%E5%A0%B4%E5%90%88)を参照してください。

1.　次のコマンドでraspbianにリポジトリを追加します。
 
```
$ sudo bash -c 'echo "deb http://mechatrax.github.io/raspbian/ stretch main contrib non-free" > /etc/apt/sources.list.d/mechatrax.list'
$ wget http://mechatrax.github.io/raspbian/pool/main/m/mechatrax-archive-keyring/mechatrax-archive-keyring_2016.12.19.1_all.deb
$ sudo dpkg -i mechatrax-archive-keyring_2016.12.19.1_all.deb
```

2.　次のコマンドでADPi Pro用のIIO サブシステムのパッケージをインストールします。

```
$ sudo apt update
$ sudo apt install raspberrypi-kernel-mtx adpi-firmware adpi-utils-backend-iio adpi-utils
```

3.　パッケージのインストール後はデバイスの初期化を行うため、次のコマンドでRaspberry Pi 3を再起動します。

```
$ sudo shutdown -r now
```

#_ADPi Proのセットアップ確認_
次の手順に従って、ADPi Proのセットアップが正常に完了したことを確認します。

1.　ADPi Proがカーネルに認識されているか次のコマンドで確認します。

```
$ cat /sys/bus/iio/devices/iio\:device0/name
ad7794
```

2.　IIO サブシステムとして使用するために、システムから「/dev/iio 」下のデバイスとして認識さているか次のコマンドで確認します。

```
$ ls -la /dev/iio*
crw------- 1 root root 252, 0  8月  1 03:36 /dev/iio:device0
```


3.　ADPi ProのEEPROMとGPIOエキスパンダの I<Sup>2</Sup>Cアドレスを、次のコマンドで確認します。EEPROMのI<Sup>2</Sup>Cアドレスが「57」、GPIOエキスパンダのI<Sup>2</Sup>Cアドレスが「27」になっていることを確認します（初期設定の場合）。なお、各I<Sup>2</Sup>Cアドレスは、ADPi Proの基板上のDIPSW1により変更可能です。

```
$ i2cdetect -y 1
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- UU -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- UU -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --               
```

4.　IIOサブシステムを利用してADPi の操作を行うシェルスクリプトファイル「adpi-utils-backend-iio.sh」が、正しくセットアップされているかを次のコマンドで確認します。

```
$ ls -la /usr/lib/adpi-utils-backend-iio/adpi-utils-backend-iio.sh
-rwxr-xr-x 1 root root 5999  7月  5 11:01 /usr/lib/adpi-utils-backend-iio/adpi-utils-backend-iio.sh
```

#_ADPi Pro の IIOサブシステムを用いたアナログ電圧の入力_
IIOサブシステムから ノードとしてADPi Proに搭載されたADCへアクセスできます。スケール値、オフセット値、生の電圧値の各ノードを使って、CH1の入力電圧を求める方法を次に示します。なお、ADPi Proで実行できる代表的なノードの説明を[ADPi ProのIIOサブシステム](https://github.com/mechatrax/adpipro/wiki/IIO-%E3%82%B5%E3%83%96%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0)に示します。

現在の入力電圧のスケール値を確認します。

```
$ cat /sys/bus/iio/devices/iio:device0/in_voltage-voltage_scale
0.000596040
```
CH1のオフセット値を確認します。

```
$ cat /sys/bus/iio/devices/iio:device0/in_voltage0-voltage0_offset
-8388608
```

CH1の生の電圧値を取得します。

```
$ cat /sys/bus/iio/devices/iio:device0/in_voltage0-voltage0_raw
10075441
```

入力電圧のスケール値、オフセット値、生の電圧値から、次の式によりCH1の入力電圧Uを求めることができます。

```
U = (in_voltage0_voltage0_raw + in_voltage0_voltage0_offset) * in_voltage-voltage_scale  
  = (10075441 - 8388608) * 0.000596040
  = 1005.41994132 mV
```


ADPi Proをセットアップすると、シェルスクリプト「adpi-utils-backend-iio.sh」がインストールされます。動作確認のために、シェルスクリプト「adpi-utils-backend-iio.sh」を用いて、チャンネル1からチャンネル4までに接続されたアナログ電圧をデジタル変換してみます。表示される電圧の単位は「mv」で、各チャンネルには「1V」のアナログ電圧を接続しており、それぞれ次のように表示されます。なお、シェルスクリプト「adpi-utils-backend-iio.sh」については、[adpi-utils-backend-iio](https://github.com/mechatrax/adpi-utils-backend-iio)を参照してください。

```
$ /usr/lib/adpi-utils-backend-iio/adpi-utils-backend-iio.sh  device=adpipro spi0.0 1-0x57 1-0x27  get voltage 1
1005.319806600
$ /usr/lib/adpi-utils-backend-iio/adpi-utils-backend-iio.sh  device=adpipro spi0.0 1-0x57 1-0x27  get voltage 2
1006.182276480
$ /usr/lib/adpi-utils-backend-iio/adpi-utils-backend-iio.sh  device=adpipro spi0.0 1-0x57 1-0x27  get voltage 3
1006.584603480
$ /usr/lib/adpi-utils-backend-iio/adpi-utils-backend-iio.sh  device=adpipro spi0.0 1-0x57 1-0x27  get voltage 4
1005.883660440
```

次に「adpi-utils-backend-iio.sh」の実行時に与えるパラメータについて説明します。

- 「device=adpipro」：デバイスの名称を与えており、固定になります。
- 「spi0.0」：「.0」はCS番号を示します。「spi0」はSPIのBus番号で、固定となります。
- 「1-0x57」：「0x57」はEEPROMのI<Sup>2</Sup>Cアドレスを示します。「1」はEEPROMのBus番号で、固定となります。
- 「1-0x27」：「0x27」はGPIOエキスパンダのI<Sup>2</Sup>Cアドレスを示します。「1」はGPIOエキスパンダのBus番号で、固定となります。
- 「get voltage 1」：アナログ電圧を入力してデジタル値に変換します。最後の数値はチャンネル番号で「1」－「4」を指定します。なお「adpi-utils-backend-iio.sh」は、パラメータ「get」以外にも「set」「reset」が指定でき、設定されている電圧レンジに対応した分解能の表示／設定や、設定されている電圧レンジに対応したゲイン倍率の表示／設定などが可能です。

この他、ADPi Proのパッケージでは、SPI デバイスとIIO サブシステムの二つのインタフェースを同じパラメータで操作できる「adpictlコマンド」が提供されています。adpictl コマンドは 「/etc/adpi.conf 」の設定を元に、「/usr/lib/adpi-utils/adpi-utils-backend」に引数を付けて実行します。「adpi-utils-backend 」は、「adpi-utils-backend-iio」をインストールした場合、「/usr/lib/adpi-utils-backend-iio/adpi-utils-backend-iio.sh」が使用されます。接続先チャンネルで測定した電圧を表示するには「get voltage ｘ」を使用します。「ｘ」はチャンネル番号「1」－「4」です。この「adpictlコマンド」を使用して、チャンネル1からチャンネル4までに接続されたアナログ電圧をデジタル変換してみます。なお、「adpictlコマンド」のほうが、与えるパラメータが少なく使いやすいのでお勧めです。

```
$ adpictl get voltage 1
1006.413540000
$ adpictl get voltage 2
1006.175720040
$ adpictl get voltage 3
1006.520231160
$ adpictl get voltage 4
1005.971278320
```

「adpictlコマンド」の詳細なパラメータの説明については、[ADPi を操作するためのツール類](https://github.com/mechatrax/adpi-utils)を参照してください。

#_ADPi Proに関連する記事_
1.　[SPIを用いたラズベリーパイ用高精度A/D変換モジュール「ADPi Pro」のセットアップ](https://qiita.com/TomoSoft/items/8aee48e685db8ffab3ca)
ADPi ProをSPIデバイスとして動作させ、Python言語で作成したサンプルスクリプトを実行して、ADPi Proに接続したアナログ電圧のA/D変換値を確認します。
2.　 [SPI /IIOサブシステムを用いたラズベリーパイ用高精度A/D変換モジュール「ADPi Pro」による計測方法](https://qiita.com/TomoSoft/items/3d9fa6f8db3daa0e5b8d)
ADPi ProをSPIインタフェースやIIOサブシステムでアクセスして、接続されたアナログ電圧をA/D変換するサンプルスクリプトを作成します。