SSブログ

macOSからPi Picoを使う - その11 [Pi Pico]

前回の続きでPi PicoのPWMとADCとで自産自消というか自給自足というかウロボロスというか、そういうお試しの結論....

次の図はADCの読みとPWMのlevelの差(ADC Error)と、エラーフラグの立った変換の回数の割合。
0615a100errors.png
もしPWMが正確でそれをちゃんとDCにできてさらにADCが変換できれば0が続くはず。ジャンプが4箇所あって2進で桁が変わるところ(たとえば0x3FF→0x400とか)かと思ったら違っていた。細かくみるとジャンプしているのではなく、16レベルぐらいかかって8ほど変わっている。入力が増えているのに読みは下がる、ということころまではいかないけど、そのギリギリぐらいのところにあって、この付近ではミッシングコードは頻発するはずである。

逐次比較のADCってこういうもんだっけ?A/Dコンバータのデータシートを見るとINL(Integral nonlinearity)のグラフとかはこれとよく似たノコギリ型を見ることがあるけど、その縦軸は一桁小さい。その昔MCP3208で似たようなデータを取った時は、自作の電圧源回路の品質のほうがA/Dに負けてるという結果だったけど。

全体のオフセットはOPアンプのバッファの問題も考えられる(しかしTL082のオフセットは案外優秀でユニティゲインだとTypicalでここでの1ビット分ぐらいしかない)のと、PWMがアナログ的にどこまで正確か(たとえば、LowとHighのどちらかが振り切っていなくてノイズの乗り方が違ったり、立ち上がりと立ち下がりでディレイや傾きが違えば平滑化したアナログ値がデューティに比例しない)というのもわからない。しかしアナログを測る方がずっと難しいので、とりあえず今回は不問にするしかない。

それよりももっと不思議なのはもう一方の線で、ADCのFIFOから読み出した時に最上位ビットが立っていると変換エラーを表すことになっていた。256回のうちに何回あったか、の比率を示しているけど、平均的に約半分でエラーになっている。これはちょっと多すぎるよなあ。

ブレッドボードなのでノイズが多くて、S/Hをすっぽ抜けたとか、そういうのかなあ。もし本当にこれが実力ならシングルショットは役に立たないよなあ。よくわからん。

10.1.2  4096回の場合

平均化するデータを16倍にしてみた。
0615a1000errors.png
当然傾向は同じで、ノイズはずっと減った。大量にA/D変換してるけど速いので1回分10msecもかからない。測定時間そのものはPWMを変化させた直後のデータは捨てているので0.01 ×4096秒の倍以上かかってるけど。

10.1.3  65536回の場合

さらに16倍してみた。こうすると一つのデータをとるのに0.1秒以上、4096点振ると10分近くかかる。
0615a10000errors.png
当然のことながら傾向は同じで、オーバーサンプリングの成果でノイズはさらに減った。こうなるとADCの非線形性があらわになる。オフセットは不問にして0〜4095のフルスパンで最大±8ぐらいのエラーになっている。つまりこのデータからはINLは±3LSB、ということになる。安価なMCP3208でも±1LSBを保証しているのに、かなり残念な特性である。

これで12ビットデータにするのは厳しい。FIFOに詰め込むために上位8ビットをとる機能が実装されているけど、これが標準だと思った方がいいかもしれない。

それに確率1/2で変換に失敗するようじゃなあ。

今回Pi Picoを550円で買った。1個買いだと送料と変わらなくなるので2個一緒に買った。ということでもう一方の方もデータを取ってみると
0615a10000othererrors.png
こっちのほうがずっと悪い。ノイズが減ったように見えるのは縦軸のレンジが広くなったせい。しかしこれはひどいな。実質7ビットしか信用できないということで、これで「12ビットADCでござい」というのはあまりだな。

こんど基板にちゃんと半田付けしてアナログ環境の比較的良い状態でもう一度みなおさないといけない。

10.1.4  ブルートフォース解決

このエラーはADC固有の特性なのでPi Pico基板を特定すれば決まる(普通のADCだと電源電圧、基準電圧、チップ温度なんかにも依存する)。ということはこの特性を測定してその逆を下駄履きすればマシになるはずである。

やってみると
0615a1000errorscorr.png
となって、±2LSBぐらいにはなった。超ブルートフォースだけど。この場合PWMの値とADCの読みの差を引き算したけど、比をかける、というのもある。このエラーの原因が何によってるかによって違ってくる。しかしどっちみち±1/2LSBとかにはならなさそうなので、どちらにしても大差ないかもしれない。

もうひとつの悪い方は
0615a1000othererrorscorr.png
こっちのほうがマシなのはなんでだろう。

とりあえずこの誤差が電圧や温度で大きく変わらなければ、超ダサいけどPi PicoのADCにはそこそこ有効と考えていいようである。

僕みたいにレーザの光を扱ってるとスペックルノイズが避けられなくて、どっちみちひと工夫しないと強度分布測定なんかの精度を上げるのは難しいことがよくある。ちゃんとした測定にはそれなりの対策を打つけど、とりあえず有効数字で一桁がわかればいい、ということもあって、そういう場合、温度はしょうがないとして、V refにはちゃんとした電流の取れる基準電圧を与えてやれば、こういうブルートフォースでもそこそこいけるかもしれない。

また、僕はPi Picoを単独で使うことはほとんどなくて、ホスト(僕の場合macOS)とUSB接続して、ホストのローレベルのハードウェア接続性を増やすためにしか使わない。その場合、Pi Pico側の基板にいつもPWM→ADCの回路を繋いで切り替えられるようにしておいて、ADCのエラーをこの方式で測定してからADCを補正する、というのもありだろう。補正は計算能力の有り余ってるホスト側でやればいいし、もしPi Pico側に余力があるなら、flashをノンボラメモリとして使って補正用のlookup tableを書いておいて自分で補正する、という手もある。

さて、これでだいたいわかった、ということにしよう。次は?
nice!(0)  コメント(2) 

nice! 0

コメント 2

居酒屋ガレージ店主(JH3DBO)

Raspberry Pi PicoのADC、こちらのテストでも
数値512,1536,2560,3584の4カ所で「段」が
出現しました。
http://igarage.cocolog-nifty.com/blog/2022/04/post-75c555.html

ADC入力に入れた抵抗+コンデンサ、この値によっても
奇妙な挙動が出ます。

by 居酒屋ガレージ店主(JH3DBO) (2022-04-18 11:16) 

decafish

コメントありがとうございます。

単体のADCでもINLがノコギリの形になっているのをみたことがあります。しかしそれはたいてい±1/2LSBの範囲でした。

あまりADCの構造に詳しくないのでこう言うエラーが起こる原因はよくわからないのですが、ミッシングコードのようなビットの切り替わりでジャンプするのではなくて、変換の傾きが一定ではなくなるエラーというのが僕には不思議です。

この回にやったように、このエラーがチップ固有で変化しないのなら8kBのルックアップテーブルで補正できると思ったのですが、このあと確認はしていません。

どちらにしてもPi PicoのADCはオマケ程度のものだと考えた方がよさそうですね。7ビット128レベルのADCと割り切ればそれでも使い道はあります。


by decafish (2022-04-19 15:54) 

コメントを書く

お名前:
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。