特価品(見切り品?)のGR-CITRUSボードで組み込みRuby(mruby)してます。前回はデジタル出力とはいえ、LPFなど通せばアナログ出力的に使えるPWMでした。今回はそのものズバリのアナログ、DAC出力を実験してみます。でもね、ちょいと文書の辻褄が合わないんです。どゆこと?
※Rubyと一緒 投稿順indexはこちら
いつもお世話になっておりますルネサス様の以下のページを拝見すると
analogDac(value)メソッドの項に
DACピンからアナログ値を出力 0 ~ 4096(3.3V)
と書いてあります。ここにちょいと引っかかりましたです。同じくルネサス様の以下のマニュアルを拝見いたしますと
RX63Nグループ、RX631グループ ユーザーズマニュアル ハードウェア編
GR-CITRUSボードに搭載のRX631のDAコンバータは10bitとかかれてます。多分まあ、マニュアルどおりハードウエアは 10bit のDAなんだけれども何か「大人の事情」でRubyから見える出力値指定は12ビットになっているのであろう、と想像いたしました。今回はそれを実際に動かして確認してみた、の回です。
なおマニュアル上はDAC2チャンネル搭載ですが、GR-CITRUS上では9番ピンのみがDAC出力対応であるようなので、そこを使ってます。
Rubyとmrubyの違い1点
Ruby素人な上、GR-CITRUSに搭載されているmruby処理系についてもほとんど調べもせぬまま実行しとります。まあ mruby は Ruby のサブセットなんだろうから、Rubyとの違いはあるだろな~。あったらその時(に泥縄対応)くらいの勢いです。すみません。
今回そんな差を1つ発見。範囲を表す範囲オブジェクトについてです。Ruby処理系の場合、範囲オブジェクトの.step()というメソッドを使えば、以下の例のように「一つ飛ばし」などでループを回すことができます。
for i in (0..10).step(2) do puts i end
ところが、mrubyの場合、以下のようなコードを書いたらエラーになりました。
for dacout in (0 .. dacmax).step(dacstep) do
エラーメッセージをそのまま解釈すると、step()メソッドは無い、と言われているみたい。なお上記のように転送成功しているので、ビルドは成功、実行したらエラーというランタイム・エラーです。前回、ビルドでエラーの場合、エラーが発生したことだけ教えてくれて、場所や理由にまったく言及なかったことに比べれば、上記のランタイム・エラーの方がよっぽど親切。しかしメソッドが無いとかいうのはビルド時に分からんのか?不思議ね。
まあ、step()は避けてコードを書き直しました。
今回実験に使用した mruby のコード
実際にGR-CITRUS上で実行したコードは以下のようです。
#!mruby usb = Serial.new(0, 9600) usb.println("DAC, Pin.9") tpin = 9 dacmax = 4096 dacstep = 1 initDac() while true do dacout = 0 while dacout < dacmax do analogDac(dacout) dacout += dacstep end end
上記コードであると、ソフトウエアループの成り行きの速度で、0から4095まで1ずつプラスしながら舐めてます。これにて想定できるDAC出力波形は0から3.3Vまでのノコギリ波であります。
実験結果
データシートを拝見するにDAC出力の測定時には負荷抵抗に2MΩとりつけているみたいでした。そこで9番には2MΩとりつけてます。特にキャパシタンスはとりつけてません。まずは上記の dacstep=1 の場合の時間波形が以下に。
期待通りのノコギリ波が生成できた?感じがします。Minimum値がマイナスになっているのは、測定精度も多少ありますが、最大出力から最小出力へ一気に遷移したためにアンダーシュートしてるのが大きい感じです。知らんけど。
繰り返しの周期の測定結果からすると1ビット出力あたりの経過時間は以下のように推定できます。
周期23.562ms / 4096 = 約5.8 μsec/bit
あれれ、以前にデジタル出力したときのビットバンギングよりも速いんでないかい。
ノコギリ波の下限付近を拡大してカーソルを置いてみました。ちょっと見ずらいですが、時間軸、電圧軸とも「階段状に見える段の4段分」とってます。
まず時間軸方向から。
4段分のΔT = 91.825us、つまり = 1段 ΔT = 23.0 μsec
「遠くからみたときに」1ビット分の時間=約5.8 μsecでした。
5.8*4=23.2
であるので、上記の1段ΔTは4ビット相当の時間です。つまりソフトウエア上は4回DACに書き込んでいる筈なのだけれど、連続する4回分が同じ値の出力になってる、ということね。なんだ10ビットじゃん。予想通り。
次は電圧軸方向。
4段分の ΔV = 13.361mV、つまり1段ΔV = 3.34 mV
ざっくりしたところ、
3.34 * 1024 = 3.42V
で3.34mVステップで10ビットであればほぼほぼ辻褄があうので、やっぱり10ビットですな。
現在は無駄に4回も「同じ出力になる」値を連続して書き込んでいるので、dacstep=4にすれば、今と同じ電圧レゾリューションでもっと速い波形が可能では?やってみました。こんな感じ。
ソフトウエアループだけれども非常に安定しています。1周期16点とかで電圧出力したら、そこそこの速さで波形出力できるんでは?
16 * 5.75 = 92usec 約10870Hz
振幅控えめにしてローパス通せば数kHzくらいの結構綺麗な正弦波を発生できるんでないの?やってみる?