Raspberry Pi から高精度AD/DA変換ボードを用いてAD/DA入出力
Raspberry PiでAD/DA変換をする方法
Raspberry PiにはHigh/Lowのディジタル入出力が可能なGPIOがついていますが,アナログセンサデータを読んだりアナログ電圧を出力することはできません。 従ってこの記事で紹介されているようなAD/DAコンバータが必要になります。
回路を組むのはだるいのでAmazonで以下のAD/DA変換ボードを購入してみました。
Fosa 高精度AD/DA拡張ボード ラズベリーパイA + / B + / 2Bに対応 アナログデジタルモジュール
- 出版社/メーカー: fosa
- メディア: エレクトロニクス
- この商品を含むブログを見る
高精度AD/DA変換ボード
高精度とうたっていますがカタログスペックは以下の通りです。
- ADポート6チャンネル(16bit)
- DAポート2チャンネル(12bit)
Vccは5VなのでDA出力が 0~5Vとすると,12bitで分割して大体8mVくらいの分解能があります。すごい。嘘やけど。
ボードのセットアップ
今回の環境は前回 SetupしたUbuntu MATEとします。ROSは使ってないのでROSの項は飛ばしてもOK。
bcm2835 のインストール
ここからtarファイルを落として7zで解凍します。
解凍した中にINSTALL
という名前のファイルがあるのでその指示に従います。
一応実行するコマンドは以下の通りです。途中sudoが必要な点に注意。
./configure make sudo make check sudo make install
make installcheck
でインストール状況をチェックできます。
提供されているサンプル
ここで配ってますが正直読むのは結構だるいので誰か解説してやってください。
コマンドラインからDA出力を制御する自分用ライブラリ
てなわけで自分でプログラムつくりました。 下記からCloneしてmakeすれば完了です。
makeした後に出てくる実行ファイルは2つです。
- calib:Vccのキャリブレーション
- dac8532_output:出力用
Vcc補正用プログラム:calib
このAD/DAコンバータでは正確な5Vが必要っぽいのですが,ラズパイから電力供給するとVccが微妙に5Vにならないという問題を抱えているため,その補正用です。
以下に実行結果を示します。
$ sudo ./calib Supposed DA output[V] DA0:3.000000 DA1:3.000000 Measured DA output V0 = 3.070409, V1 = 3.066153 Supposed Vref = 5.058334 magnitude offset: 1.011667, 1.010965
この実行結果から,3Vを出しているのに3.07Vが出ている(とADで読める)ズレが有ることがわかります。これでは12bitの分解能が台無しです。 この関係から実際のVcc=Vrefを5.058Vと推定しています。テスタで測ると5.053なので5.0Vとして考えるよりはマシになりそうです。
このときの5Vに対するVccの倍率を一番下の行で計算しています。僕の環境では1.01倍と出ていますね。
注意:原理は多分Vrefとの比較でADやDAのしきい値を変えているのでVrefの倍率分DAやADの値が変化すると読んで計算しています。もっといい方法なんかあるなら知りたいっす…
出力プログラム:dac8532_output
こちらでは,引数にDA0とDA1の出力電圧[V],Sleep時間[ms]を与えることでコマンドラインから出力を可能にしています。
$ sudo ./dac8532_output <電圧1> <電圧2> <時間> <補正>
と打ちます。 <補正>項はデフォルトで1.01にしているので抜いてもOKです。
- データ例
試しに4Vと2Vを出力させるよう
$ sudo ./dac8532_output 4 2 10 1.01
を実行しました。
結果は3.998Vと1.999Vでした。
Vccの電圧をきちんとしない限りカタログスペックの12bit分解能は正直出ないと思われます。 でもまぁそこまで気にしないのならそこそこの精度かなと思います。 5Vや0V等の上限下限近づいた場合はこの限りではないので注意。
Pythonからの実行
結局最近プログラムの多くをPythonで書くようになったのでDA出力もPythonからしたいです。
実はsubprocessというやつを用いるとコマンドライン実行をめちゃ簡単にできます。
import subprocess da0 = 3 da1 = 4 duration = 20 subprocess.call(["./dac8532_test",str(da0),str(da1),str(duration)])
呼び出し先のプログラムにはsudo権限がいるのでこのPythonコードをsudoで実行すればいいわけです。 (/dev/memにアクセスするからのようですが,できればsudoなしでアクセスしたい…)
総括
カタログスペックは高いですが電源をちゃんとするとかしないと正直カタログのような超精度は出なさそうです。 ただ,ラズパイの上に乗って収まりが良く,はんだ付けなどなしで動作させられるのでアプリケーションによっては結構ありかも? 私は今回は車載用センサ処理に使っています。
久々にリポジトリ作りました。汚いですが指摘などあれば歓迎です。超暇なら直します。