twitter icon   twitter icon   rss icon

Linux.com Japan

Home Linux Jp チュートリアル BeagleBone Black におけるアナログ入力

BeagleBone Black におけるアナログ入力

原文は、こちらです。
Beaglebone black analog test
Linux.com での BeagleBone Black に関するシリーズの中で、「SPI を通したチップへのアクセス」や「電圧が変化したときの割り込みの受け取り方」を勉強しました。今回は、BeagleBone Black のアナログ入力の使い方を勉強しましょう。
 
GPIO、TWI や SPI が、ハイとグラウンドの 2 つの状態だけを使って通信するのに対して、アナログ入力を使うと、ハイとローの中間の値を扱えます。
 
光依存性抵抗 (訳注: いわゆる Cds などの光量に従って抵抗値が変化するもの: 日本語はこちら) などを用いて現在の明るさを調べたり、温度センサーを用いて外界の状況をセンスしたりすることが、アナログ入力の良い例です。人間とのインタフェースとして、ポテンショメーター、ジョイスティック、または抵抗型タッチ スクリーンを使うのも、アナログ入力の例です。
 
本文献の内容について、特定の用途に適するとは保証できません。私は、ここで記述したことを実験し、それは、私の BeagleBoard Black や他のものを破壊しませんでした。ハードウェアのセットアップについては、みなさん自身の責任において行ってください。
 

アナログ入力の試験

BeagleBone Black の GPIO ピンが 3.3V 入力に対して、アナログ入力ピンは、最大 1.8V となっています。P9 のピン 1,2 がグラウンドで、ピン 3 および 4 が 3.3V を供給します。アナログ入力を扱うときは、アナログのグラウンドと電源が必要です。P9 には、必要なピンが出ています。P9 は、電源用ジャックに一番近いところにあります。P32 が VDD_ADC で、P34 が GNDA_ADC です。アナログ入力は、ピン 33 と、35 から 40 です。アナログ入力の0 (基点) は、ピン 39 です。詳細については、システム参照マニュアルを見て下さい。
 
アナログ入力のテスト用に、10K のポテンショメーターを用意しました。ポテンショメーターを固定抵抗と直列に接続すると、分圧回路 (日本語) になります。私は、ポテンショメーターの前に固定抵抗を繋ぎ、ポテンショメーターの入力値を測定しました。固定抵抗には、次の 2 つの目的があります。VDD_ADC から供給される 1.8V から若干の電圧降下を行うこと、ポテンショメーターを最小値にしたときに回路に流れる電流を制限すること、の 2 つです。
 
BeagleBone Black voltage div3
分圧回路 (日本語) の原理を頭に入れて、上図を見てください。R1 は、1K オームの固定抵抗、R2 は、0K から 10K の間で変化します。ポテンショメーターのスライダーを動かし、電圧が変化するポイントに白い電線を繋ぎます。ポテンショメーターを最大値 (10K) にすると、測定値は R2/(R1+R2)*VIN=10,000/(10,000+1,000)*1.8 = 1.64V になります。ポテンショメーターを最小値にすると 0V になります。
 
Extech EX330 マルチメーター (訳注: 適当な電圧計を使ってください) を使って、BeagleBone Black のVDD_ADC ヘッダーの電圧を測定しました。1.803V ありました。1K 抵抗は、実際には若干低い値でした。ポテンショメーターは、最大値で 10.4K ありました。ポテンショメーターを最大にすると、測定ポイントの電圧は 1.645V ありました。BeagleBone Black のアナログ入力の最大値 1.8V を下回っていますので、問題ありません。
 
上図で、赤い電線でボードの電源を BeagleBoard Black の VDD_ADC (ピン 32)、緑の電線でボードのグラウンドを BeagleBoard Black の GNDA_ADC (ピン 34) に接続します。測定ポイントをアナログ入力に接続する前に、測定ポイントから供給される電圧を確認しました。ポテンショメーターの両端で、それぞれ 20mV から 1.644V となりました。20mV から スライダーを 1/6 動かすと、1V になりました。そこから 1.644V までは、リニアに変化しました。固定抵抗を 1K から 10K に変えると、電圧の範囲は 2mV から 1V になりました。そこで、今回は 10K を使うことにしました。
 

アナログ入力の読み込み

測定ポイントをアナログ入力に繋ぎます。私は、アナログ入力 0、P9 ヘッダーのピン 39 に接続しました。
 
私の BeagleBone Black は、アナログ入力用に設定済みです。下にあるように、スロット ファイルに ”cape-bone-iio” を設定します。スロット ファイルに -7 を書いて、”cape-bone-iio” を取り除こうとしましたが、/sys 中のアナログ入力ファイルが消えてしまい、BeagleBone Black をリブートする必要がありました。
root@beaglebone:~# echo cape-bone-iio > /sys/devices/bone_capemgr.*/slots
...
root@beaglebone:~# cat /sys/devices/bone_capemgr.*/slots
 0: 54:PF--- 
 1: 55:PF--- 
 2: 56:PF--- 
 3: 57:PF--- 
 4: ff:P-O-L Bone-LT-eMMC-2G,00A0,Texas Instrument,BB-BONE-EMMC-2G
 5: ff:P-O-- Bone-Black-HDMI,00A0,Texas Instrument,BB-BONELT-HDMI
 6: ff:P-O-- Bone-Black-HDMIN,00A0,Texas Instrument,BB-BONELT-HDMIN
 7: ff:P-O-L Override Board Name,00A0,Override Manuf,cape-bone-iio
 8: ff:P-O-L Override Board Name,00A0,Override Manuf,am33xx_pwm
 9: ff:P-O-L Override Board Name,00A0,Override Manuf,BB-SPIDEV0
10: ff:P-O-L Override Board Name,00A0,Override Manuf,gpio-P9.12
11: ff:P-O-L Override Board Name,00A0,Override Manuf,gpio-P9.15
12: ff:P-O-L Override Board Name,00A0,Override Manuf,gpio-P9.23
13: ff:P-O-L Override Board Name,00A0,Override Manuf,bone_pwm_P9_14
14: ff:P-O-L Override Board Name,00A0,Override Manuf,gpio-P9.26
15: ff:P-O-L Override Board Name,00A0,Override Manuf,gpio-P9.27 
アナログ入力にアクセスするためのファイルは、/sys ディレクトリのわかりにくいところにありました。大文字のファイルなので、探すのが難しいです。
root@beaglebone:/sys# cd /sys
root@beaglebone:/sys# find . -iname "ain*"
./devices/ocp.3/helper.12/AIN0
./devices/ocp.3/helper.12/AIN1
...

下記に、ポテンショメーターを最小値から最大値に変化させたときのアナログ入力値を示します。

root@beaglebone:/sys/devices/ocp.3/helper.12# cat AIN0
0
root@beaglebone:/sys/devices/ocp.3/helper.12# cat AIN0
427
root@beaglebone:/sys/devices/ocp.3/helper.12# cat AIN0
746
root@beaglebone:/sys/devices/ocp.3/helper.12# cat AIN0
921

AIN ファイルは、アナログ入力の現在値を測定し続ける機能を持っています。そのため、ハードウェアに必要jな値を保持するバッファ機能を持たせられます。これにより、特別なタイミングを意識することなく、1 回 1,2 秒で値を読み込むことができます。Web をいろいろ検索しましたが、どれも説明が異なっていました。

drivers/staging/iio/Documentation/generic_buffer.c を引用した例が多く見られます。Texas Instruments は、トリガーを除いて、アナログ入力を常時コンソールに出力するパッチ (訳注: 原文のリンク先が間違っていたので、それらしいものを検索、設定しています) を提供しています。私の Linux カーネルは、トリガー設定なしではアナログ入力のバッファ機能を有効にできませんでした。そのときの dmesg を下に出します。
[  463.846511] Buffer not started: no trigger

トリガーを有効にするために、iio-trig-sysfs カーネル モジュールを挿入します。これにより、”iio_sysfs_trigger” ディレクトリが作成されます。

root@beaglebone:/sys/bus/iio/devices# insmod /lib/modules/3.8.13/kernel/drivers/staging/iio/trigger/iio-trig-sysfs.ko
root@beaglebone:/sys/bus/iio/devices# l
total 0
lrwxrwxrwx 1 root root 0 Mar 23 02:36 iio:device0 -> ../../../devices/ocp.3/44e0d000.tscadc/tiadc/iio:device0
lrwxrwxrwx 1 root root 0 Mar 23 03:01 iio_sysfs_trigger -> ../../../devices/iio_sysfs_trigger 
adc-iio-continuous-sampling-userspace のフォークを作成し、いくつかのファイルを変更しました。Poll() の代わりに select() を使い、もっと正確にトリガーをカウントするようにしました。大きなバッファを読み込むと、poll() 関数では、デバイスがデータを用意できたかを正確に検知できません。なぜなら、ループしただけではデータを完全に出せないからです。先のフォークの generic_buffer.c は、select() を使って /dev/iio:device0 に新しい値が書き込まれるのを待ち、値を人間が読める形式で表示します。
 
下のスクリプトは、generic_buffer を起動して、アナログ入力の 0 と 5 を継続的にモニターします。トリガーは、sysfstrig1 です。スクリプトを動かすと、起動のメッセージを表示して、ポーズします。もし下のコマンドの 2 番目のブロックを他の端末で動がした場合、script_adc はアナログ入力値をプリントします。
# cat ./script_adc.sh
echo 1 > /sys/bus/iio/devices/iio_sysfs_trigger/add_trigger
echo 1 > /sys/bus/iio/devices/iio\:device0/scan_elements/in_voltage0_en
echo 1 > /sys/bus/iio/devices/iio\:device0/scan_elements/in_voltage5_en
./generic_buffer -n tiadc -t sysfstrig1 -l 128 -c 10 
# ./script_adc.sh
... [pause in time] ...
wait__ 0 10
 rs 80 ss 8
1315.000000 1508.000000 
1315.000000 1456.000000 
1315.000000 1429.000000 
1315.000000 1421.000000 
1315.000000 1414.000000 
1315.000000 1413.000000 
1315.000000 1410.000000 
1315.000000 1408.000000 
1315.000000 1411.000000 
1315.000000 1411.000000 
wait__ 1 10
 rs 80 ss 8
1315.000000 1410.000000 
1315.000000 1411.000000  
他の端末からアナログ バッファをトリガーするには、次のようにします。
root@beaglebone:/sys/bus/iio/devices/trigger0# cat name
sysfstrig1
root@beaglebone:/sys/bus/iio/devices/trigger0# echo 1 > trigger_now 

トリガーを使ったり、2 つの端末を利用するなど、ちょっと不思議なやり方ですが、これにより継続的にトリガーをかけ続けるために、アナログ入力にタイマーを停止させる必要はありません。

BeagleBone Black のアナログ変換は、12 ビットなので、0 から 4096 の範囲です。これは、Arduino の 10 ビットより、若干良い程度です。本文献では、アナログ入力の最大値を 1V としました。より多くの電圧範囲の測定はやめました。大事なことは、1.8V 以上を掛けてはならないということです。他にも電源供給や SYS_RESET に関するルールがあります。このルールを守ることにより、BeagleBoard Black を壊さずにすみます。アナログ入力を利用したインタフェースは、簡単に値を取得でき、バッファリングを利用することにより、連続的なモニター機能を手にいれることができます。
 

参考文献

 
 
 
 
 
Linux Foundationメンバーシップ

30人のカーネル開発者

人気コンテンツ

  1. Today's Linux 2018/01/10 2018年 1月 09日
  2. Today's Linux 2018/01/12 2018年 1月 11日
  3. Today's Linux 2018/01/15 2018年 1月 14日
  4. Today's Linux 2018/01/16 2018年 1月 15日
  5. Today's Linux 2018/01/17 2018年 1月 16日

Linux Foundationについて

Linux Foundation はLinux の普及,保護,標準化を進めるためにオープンソース コミュニティに資源とサービスを提供しています

 

The Linux Foundation Japan

サイトマップ

問い合わせ先

サイトに関するお問い合わせはこちらまで

Linux Foundation Japan

Linux Foundation

Linux Training

提案、要望

Linux.com JAPANでは広く皆様の提案、要望、投稿を受け付ける予定です。

乞うご期待!