google-site-verification: google3bd66dd162ef54c7.html
fc2ブログ

RP2040のADCの誤差の確認と簡単な補正プログラムのテスト

◆まえがき
Raspberry Pi pico のCPUのRP2040 のADコンバーターは12ビットですが、バグ(エラッタ RP2040-E11)があるため実力は 7-8ビットくらいしかありません。

この記事ではその状況を確認すると共に、簡単な補正プログラムを作って効果を確認してみます。なお、この問題は現時点のもので、エラッタが修正されればこの記事は意味の無いものになるはず、と言うかそうなって欲しいと思います。

◆ADコンバーターの誤差
RP2040のデーターシートの 4.9.4. INL and DNLの項で解説があります。(release 1.8)
RP2040のADCのINL
上図はRP2040データーシートから抜粋したものです。特定の値で(512,  536,  2560, 3584)で特性が不連続になっています。

◆現象の確認
状態を確認するために簡単な回路とプログラムを用意しました。
・回路図
補正回路
GP16の出力をR1とC1で積分してADコンバーター(GP26)に入力しています。適当な周期でGP16をトグルすることで問題の電圧付近のADCの挙動を探るのが狙いです。

◆外観
ブレッドボード
・プログラム
// RP2040のADCの誤差補正テスト 20220623PicoAdcTest.ino
// 
void setup() {
  pinMode(16, OUTPUT);
  pinMode(23, OUTPUT);          
  Serial.begin(115200);
  analogReadResolution(12);     // ADCのフルスケールを12ビットに設定
  digitalWrite(23, HIGH);       // ノイズ対策のため電源をPWMモードに設定
  digitalWrite(16, LOW);
  delay(500);
}

void loop() {
  int d, dc;
  digitalWrite(16, HIGH);
  for (int i = 0; i < 30; i++) {   //  30, 90, 150, 210から選ぶ
    d = analogRead(26);              // ADC0の値を読む
    dc = adcCorrection(d);
    Serial.print(d); Serial.print(", "); Serial.println(dc);
    delay(10);
  }

  digitalWrite(16, LOW);
  for (int i = 0; i < 210; i++) {   // 210, 150, 90, 30
    d = analogRead(26);
    dc = adcCorrection(d);
    Serial.print(d); Serial.print(", "); Serial.println(dc);
    delay(10);
  }
}

int adcCorrection(int x) {        // RP2040のADCの非直線性補正(RP2040-E11対策)
  int y;
  if      (x >= 3584) y = x + 32; // fsの7/8のポイントのオフセット補正
  else if (x == 3583) y = x + 29; // 遷移のステップを少し埋める
  else if (x == 3582) y = x + 27; // 同上
  
  else if (x >= 2560) y = x + 24;  // fsの5/8
  else if (x == 2559) y = x + 21;
  else if (x == 2558) y = x + 19;
 
  else if (x >= 1536) y = x + 16;  // fsの3/8
  else if (x == 1535) y = x + 13;
  else if (x == 1534) y = x + 11;

  else if (x >=  512) y = x +  8;  // fsの1/8
  else if (x ==  511) y = x +  5;
  else if (x ==  510) y = x +  3;
  else                y = x;       // 該当しなければそのままの値
  return y;
}
◆状態の確認
シリアルプロッタを使って特性を見ると便利です。
・511付近
511付近
グラフはADCの生の値のプロットです。つまり補正結果はコメントアウトして出力しないようにしています。
入力電圧(横軸)が変化しても、特定の値(このグラフでは511)でADCの値(縦軸)が引っかかって変化していません。

・511付近(電源をPFMに設定)
電源をPFMにした場合
話が脱線しますが、これは電源の制御をPWMからPFMに設定した状態です(digitalWrite(23, HIGH);をコメントアウト)。大きなノイズが乗っていてとても使い物になる感じではありません。ちなみに、デフォルトはこの状態なので怖いです。

◆単純な補正
プログラムでステップの補正を行った状態です
・511付近
単純補正
青線が補正前、赤線が補正後です。段付きの前後でシフトしていた特性が直線になっています。
もちろん、段が付いた部分の情報を再現することは出来ません。また、切り欠きになっている部分で一度に値が8増えるので大きなノイズが発生しそうです。

◆少し切り欠きを緩和
ここからが上に示したプログラムの補正を全部使った状態です。
・511付近
511付近の補正
切り欠きの前後に中間的な値を入れて大きな変化が起きないように改良したものです。具体的には一度に+8させていたのを +3, +2, +3 と3回に分けて変化させています。なお、こんなことやってるのでミッシングコードが発生します。
それでも段付きは発生しますが、誤差(仮想直性からはみ出した三角形の面積)は小さくなっているはずです。

・3548付近
3584付近
下の方の引っ掛かりで発生した誤差が累積されているので、補正の有無による値の差が大きくなっていますが、補正の内容は同じです。

◆動画

◆まとめ
RP2040のADCのエラッタは、特定の入力電圧で電圧の刻みが大きく(約8LSB)なっていることが確認出来ました。この問題についてはいろいろな方が記事で言及されていますが、改めて自分で確認することが出来て良かったです。

簡単な補正プログラム (adcCorrection) を作ってみました。これを使うとリニアリティが良く見えるようになるかも知れません。しかしAD変換のステップが飛んだことで失われた情報が再現出来る訳では無いので、やらない方が良い場合だってありそうです。

補正プログラムを通すとフルスケールが4095から、4127に増えてしまいます。これが問題になる場合は最大値が4095になるように再度マップすると良いと思います。
関連記事

コメントの投稿

管理者にだけ表示を許可する

A/D入力に入れた直列抵抗

A/Dの値。
直列に入れた抵抗の値により、なにやらおかしな挙動が出てました。
http://igarage.cocolog-nifty.com/blog/2022/04/post-4d44ad.html

RP2040の誤差の件

こんにちは。

私もこの誤動作の根本的な原因に興味が湧いてデータシートを調べておりました。以下、当たっていないかも知れませんが私の憶測を簡単にご紹介してみたいと思います。

RP2040のADCは逐次比較型です。
逐次比較型ではDACとコンパレータを使って上位ビットから順にAD変換値を決定していきます。
問題が起きるのはビット9を決めるステップです。DACのビット9を0から1とした際にこの問題が起きるようです。
加えてこの問題が起きるためには、この後の変換ステップでビット8~0がすべてゼロとなることが必要です。
データシートにADC内部キャパシタの値が不適との記述があるので、どうもビット9に接続されたホールド用コンデンサの値が不適なのだと想像してます。
この誤動作は、入力電圧が上昇中なのか下降中なのかに関わらず特定の電圧を横切るときに起き、スパイク状に誤った値を出力することになるようです。

以上です(間違っていたら済みません)。

余談ですが、英語ではErrata(「正誤表」の複数形)は「エラータ」と発音します(ご存じだと思いますが)。
英語辞書サイトで発音が聞けます。
https://www.merriam-webster.com/dictionary/erratum

どうしてこんな読み方が「発明」されたのか?「Eratta」と見誤ったのか?
ただ、ともかくこの言葉はもうチップメーカーの日本語のデータシートにも使われるなどして、技術用語として完全に定着してしまっていますのでどうにもなりません。
使われ始めた時点で修正されなかったことを残念に思います(私はこの言葉を見ると今だにギョッとしますが、感覚的に反応してしまうのでどうしようもありません)。

re:A/D入力に入れた直列抵抗

そういう挙動もあるんですね、なんじゃこれは?
ちなみにうちの実験はイヤフォンジャックの出力か、50Ω終端したファンクションジェネレーターでやってるのですが、今度もう少し信号源インピーダンスを上げた状態でも見ておきます。
どうもバッファアンプを入れておいた方が安心みたいですね。

re:RP2040の誤差の件

原因については私も同じ意見で、下記にちょっと書いてます。
https://twitter.com/radiopench1/status/1538808629293223936?t=k9EEgcZMouzD7g--c-lrhQ&s=19
あと、エラータと読むのが正解だったとは全く知りませんでした。みんなエラッタと言ってるのでもう直らないでしょうね。
恥ずかしいことに、このツイートで私は eratta とローマ字表記で書いちゃったりしてます。

投稿のダブリ、片方を消しておきます。

re:RP2040の誤差の件

二重投稿の削除でお手数をおかけしました。
実は以前にもあったように投稿成功の直前まで、投稿が十回以上ハネられておりました。
文言を少しずつ変えてもだめでしたので、PCからではなく、WiFi接続をオフにしたスマホから投稿してみたところ成功しました(問題の原因が少し絞れましたね)。
ただ、成功して気が緩んだせいかスマホのタッチ操作を誤ってしまい、二重投稿となってしまいました。

ADCのエラーについてのコメントですが、情報不足に加えて逐次比較型ADCについての私の理解も不足している状態で軽はずみな文章を書いてしまったことを後悔しています。
きちんと自分自身で納得できる説明ができるようになりましたら、再度コメントさせていただきたいと思います。

今回もスマホからの投稿です。

re2:RP2040の誤差の件

vabenecosiさん、コメント投稿でご迷惑おかけしてすみません。

他の方からも同じような話を頂いていて気になっているのですが、回避方法が判らないでいます。というか自分自身が投稿できなかったことがほとんど無いので、原因を調べるのが難しいです。

投稿がハネられる件

1つの仮説ですが、投稿者がコメント、名前等を書き終えて「投稿する」ボタンを押したタイミングで、FC2が投稿者のIPアドレスを見てハネている、と考えられます。
投稿者が、PCからインターネットサービスプロバイダを通じてネットに接続している場合、DDNSによりその時点で割り当てられているIPアドレスを使っていますので、それがたまたまFC2のブラックリストに該当すればハネられるということになります。
投稿した時期により問題が起きたり、起きなかったりするのも、DDNSにより割り当てられるIPアドレスが変わるからだと説明できます。

一方、スマホからキャリアのゲートウェイを通じてインターネットに接続している場合は、キャリアのゲートウェイのIPアドレスは固定でしょうし、またそれがブラックリストに載ることもないだろうと思います(そんな仮説を立てて今回トライしてみました)。

re: 投稿がハネられる件

済みません。
訂正です。
先のコメントの中のDDNSをDNSと読み替えてください。

re2:投稿がハネられる件

FC2側でドメインやIPアドレスに対するアクセス規制を行うことはありそうですが、その内容は公開されていないので判らないんですよね。
あと、念の為にこのブログのコメントの設定を確認したのですが、特に変わったところはありませんでした。

re2:投稿がハネられる件

なかなか確認は難しいですよね。

ご参考までに私が今回の問題に関してお知らせしていなかったことを補足しておきます。
1. PCを使い投稿がハネられ続けた際に、本文に「これはテストです。」のみを記入した投稿を試した。→ NG。
2.PCを使い投稿がハネられ続けた際に、名前を「vabenecosi」ではなく、「vab」として投稿を試した。→ NG。
3.スマホから投稿して成功した際には、直前にPCから投稿を試してNGだった本文をそのまま用いた。

以上です。

re3:投稿がハネられる件

vabenecosiさん、詳しい状況のご連絡ありがとうございます。

凄く短いメッセージでもダメだったんですね。となるとNGワードなどにひっかかったのでは無くて、通信路に対するアクセス規制にひっかかった感じでしょうか。

FC2にはアダルトコンテンツもあるので、ネット上の攻防が他より多いのかも知れませんが、いまさら乗り換える訳にも行きません。

re4:投稿がハネられる件

そうなんですよ。
もし、FC2も巻き込んで原因追及の話が進むことになりましたら、協力させていただきます。

私の方は、当てずっぽうかも知れませんが一応対策が見つかったような気がしてますので、このままでも構いません。


re5:投稿がハネられる件

vabenecosiさん、了解です。いろいろ情報ありがとうございました。

re:RP2040の誤差の件

ADCのエラーについて、当方のブログの方に記事を書きました。
数えてみたら1年4か月振りの投稿となってました(サボリ過ぎ!)。


re2:RP2040の誤差の件

イメージは理解していたつもりですが、実際の回路の動きの解説ありがとうございます。
カレンダー
05 | 2023/06 | 07
- - - - 1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 -
プロフィール

ラジオペンチ

Author:ラジオペンチ
電子工作を中心としたブログです。たまに近所(東京都稲城市)の話題など。60過ぎて視力や器用さの衰えを感じつつ日々挑戦!
コメントを入れる時にメールアドレスの記入は不要です。なお、非公開コメントは受け付けていません。
記事の内容のご利用は読者の自己責任でお願いします。

記事が気に入ったらクリックを!
最新記事
カテゴリ
最新コメント
リンク
FC2カウンター
検索フォーム
月別アーカイブ
RSSリンクの表示
QRコード
QRコード