![](https://jhalfmoon.com/dbc/wp-content/uploads/2018/11/JH-2-150x150.png)
特価品(見切り品?)のGR-CITRUSボード(RX631搭載)で組み込みRuby(mruby)してます。前回はDAC出力だったので、今回はADC入力を使ってみます。マニュアル拝見すると基準電圧が3種類、レゾリューションが2種類で合計4種もの動作モードがあるように見えます。でも回路図みるとそんな筈がないです。どゆこと?
※Rubyと一緒 投稿順indexはこちら
いつもお世話になっておりますルネサス様の以下のページを拝見すると
analogRead(pin)メソッドの項に(以下引用させていただきます)
pin: ピン番号(14, 15, 16, 17) 0~675(3.3V)
後述のanalogReferenceで入力モード指定可能
と注釈が書かれてます。そして、analogReference(mode)の項には(再度引用)
0: 5.0V基準
1: 1.1V基準(内蔵電圧)
2: 3.3V基準
3: 3.3V基準, 12ビット分解能(0~4096)
と書かれておりますのじゃ。RX631とGR-CITRUS素人の年寄は上記をみて、基準電圧が3種類、ADコンバータも12ビット分解能と10ビット分解能(多分、書いてないけど)の2種類が使えるのか?と早合点してしまいました。
でもま、RX631のデータシートとGR-CITRUSの回路図を拝見させていただき、上記の認識を修正いたしましたぞ。
RX631搭載ADのハードウエア
RX631は、いずれも逐次比較型のADC、2ユニットを搭載しています。その電源と基準電圧端子をまとめると以下のようです。
AD名 | レゾリューション | AD電源 | ADグランド | AD参照+ | AD参照- |
---|---|---|---|---|---|
S12ADa | 12bit | AVCC0 | AVSS0 | VREFH0 | VREFL0 |
ADb | 10bit | VREFH | VREFL | VREFH | VREFL |
つまり12bit精度のS12ADaというユニットは、独立の電源、GNDと参照電圧+、-を持っており、10bitのADbは、電源、GNDがそのまま参照電圧としても使われる方式になっているようです。ただし、GR-CITRUSの回路図を参照すると、結局どちらも同じだ、ということが判明。
-
- AVCC0、VREFH0、VREFL0、すべて3.3V電源
- AVSS0、VREFH、VRERL、すべてGND
つまり3.3V電源が外部リファレンス電圧兼アナログ電源であります。なお、1.1Vのリファレンス電圧を内蔵しているのですが、RX631のドキュメントを拝見するに、この電圧を読み取ることはできそうなのですが、この電圧をAD変換のリファレンス電圧に使う方法は見当たりませんでした。なんだ、結局 参照電圧は3.3V電源の1択か?ホントか?
また、RX631のチップ端子とGR-CITRUSの外部端子の関係でいうと
S12ADa のAN000~AN003がそのままA0~A3端子に出ている
という関係です。よって使用可能なADCはS12ADaの方で10bitのADbの方はとりあえず忘れておいても良さそうです(ただし、A0~A3端子は、ボード背面の半田ジャンパにより接続先を変更可能。)
なお、細マケー話ですが、手元のGR-CITRUS回路図では マイコン端子名のVREFH0とVREFL0の”0”が抜けておりVREFH、VREFLと見分けがつかないっす。まあ、上記のような接続なのでどうでもいい話ですが。
今回実験のRuby(mruby)ソース
今回実験のソースが以下に。4種の「analogReferece()モード」を変更しながらadcの値を読んで標準出力に出力するだけのもの。
#!mruby usb = Serial.new(0, 9600) usb.println("ADC, Pin.A0") adcmode = 0 duration = 2000 while true do usb.println("ADC mode: " + adcmode.to_s) analogReference(adcmode) adcin = analogRead(14) usb.println("ADC read: " + adcin.to_s) adcmode = adcmode < 3 ? adcmode + 1 : 0 delay(duration) end
ここで最初、
analogRead(A0)
みたいな書き方をしたら、実行時エラー(ビルド時ではない)で落ちました。ボード上にもA0ってしっかりシルクで描かれているじゃん。互換性を意識?しているらしいArduinoじゃ、アナログ端子はA0って書けた気がする。知らんけど。
まあ、端子番号で
analogRead(14)
と書いたらすんなり通りました。よくある「フェイント」ね。ガタガタ言うなと。
実験結果とその考察
実験のために、A0端子の外側に抵抗とボリュームを取り付けました。どちらも1kΩです。固定抵抗で3.3Vに吊り上げ、ボリュームの片側はGNDに落としてあります。ブレッドボード写真が以下に。
ボリュームは結構回転数が多いタイプなのでかなり細かく調整できます。ハンディDMMの電圧計をみながらA0に加わる電圧が 1.000 Vになるように調整いたしました。
ここで4モード(0から4)の測定値とそこから推定できる計算式を以下に列挙しました。
-
- モード0、読み値 205、計算式 (205/1024) * 5.0 = 1.001 [V]
- モード1、読み値 930、計算式 (930/1024) * 1.1 = 0.999 [V]
- モード2、読み値 310、計算式 (310/1024) * 3.3 = 0.999 [V]
- モード3、読み値 1240、計算式 (1240/4096) * 3.3 = 0.999 [V]
前述のハード調査の結果とまとめると以下のようかと
-
- 12ビットのADを使っているがモード0から2では10ビットの結果に換算している
- モード0では、存在しない5Vの参照電圧があるかのような値に換算している。結果レゾリューションは荒くなっている。推測するにArduinoの5V機に合わせたかった?(Arduinoでも3V IO電圧機ではそんな律儀な換算してないケド。)
- モード1では、内蔵の1.1V参照電圧を使っているような書きぶりだが、その実体はよくわからない。1.1Vの内蔵電圧を参照して計算で「補正」かけているのかも知れない。
- モード2では、3.3V電源をリファレンスに読み値を10ビットに換算している
- モード3では、3.3V電源をリファレンスに12ビットで読み取っている
なんだか複雑なモードを作ってくれてるのだが、内蔵の参照電圧のよみとり機能さえあれば、12ビットそのままで良いような気がします。やりすぎ感あり。