nobcha23の日記

PICマイコンやArduinoを使う電子回路遊びを紹介します

SINAD/THDインディケータ試作記:やはりADCノイズという伏兵にてこずりました(その1)

 何度か断片で記事にしましたが、その後使ってみて、バグつぶしとか、機能追加があったので、今回は、まとめを書いておきます。

 

まずは、きっかけとして、2つの動機が重なり、SINADインディケータを試作しました。 そもそもは、自作受信機の感度が今一つなので、感度評価しようとしたのが始まりです。tinySAにSG機能が付いており、受信側にはSINAD計が欲しいなと思った次第です。使い勝手よさそうなのはメータ式のSINAD計で、測定時にメータを合わせるスタイルです。回路をコピペしてDIYするなら、いっそのことデジタル化OLED表示にするかと思いつきました。JH1LHVさんが、M5Stackで試作されたのを見たのもちょうどきっかけになりました。どうもありがとうございます。

 

それと、もう一つの動機がちょうど入手したESP32-C3 dev kit super miniの活用です。Arduino互換で動作し、切手サイズ、しかも安価。このマイコンでDIY測定器グッズが何かできないか、という思い付きです。 この2つの動機が重なり、ESP32-C3を使うSINAD/THDインディケータの試作を開始しました。

 

手掛けた時点でESP32-C3のADCの評判がいまいちでした。くせがあり、ノイズ影響を受け、低レベル領域ではリニアニティが悪いなどのコメントがありました。でもちょっとした試作回路なら我慢できるかと割り切り手掛けました。本気でやるならI2SのADC,DACでやらないといけませんよね。

 

実装概要 ハードウェアは至ってシンプルで、ESP32-C3にOLED(SSD1306, 128×64)とロータリーエンコーダを組み合わせた構成。従来から手掛けているR909受信機とかVFO用のパネル制御部分と互換にしました。これに音声入力はESP32-C3内蔵ADCにDCバイアスだけ付け直結するという、簡易式にしました。

 

ESP32-C3 SINAD/THD indicator



 

 

ソフトウェアの核心は3つのブロックで構成します。 IIRノッチフィルタ(SINAD用) 1kHz中心、Q=20のIIRノッチフィルタでキャリア成分を除去します。入力RMSとノッチ後RMSの比からSINADを算出するのが基本的な数式処理です

SINAD(dB) = 20×log10(vInRMS / vNotchRMS) 

 

入力信号確認のためのFFT表示 10kHzサンプリング、512点バーストサンプリングによるFFT表示。

0〜4kHz(bin1〜bin205)を128ピクセルにマッピングする。

1k/2k/3k/4kHzのラベル付き。

THD計算(1kHz固定で信号歪率) FFTから基本波(bin51:1kHz)と高調波(bin102:2kHz、bin154:3kHz、bin205:4kHz)を抽出してTHD%を算出します。

THD(%) = √(f2²+f3²+f4²) / f1 × 100

 

displayModeはロータリーエンコーダで切り替え、7画面を持つ。 0:SINAD  1:WAVE_in  2:WAVE_notched 3:FFT_in  4:FFT_notched  5:PARAM  6:THD DDS(1kHz基準信号発生)もPWMで内蔵し、スイッチでON/OFFするようにした。

 

Sketch brock diagram


 

 

以上の仕様でDIYしました。一度はうまくいったと思ったんですが、改良したり機能アップしたりいじっていると、いくつかの問題点に行き当たりました。

 

伏兵その1:ISR干渉

始め無知なままロータリーエンコーダ用のライブラリrotary.hをそのまま使っていたが、どうもおかしいなと思ったら、ESP32-C3ではesp32用の関数でないとダメとのこと。AiEsp32RotaryEncoder.hを使ってみたました。でも、ダメ。

最初の難敵はISR(割り込みサービスルーチン)の干渉です。 ロータリーエンコーダのライブラリがISRを使用しており、DDS用のTickerと競合してADCサンプリングがストールした。さらにESP32-C3のUSB-CDC(GPIO2/3)も絡み、シリアルデバッグでデバッグモニターしようとしたら、かえってストールし、難航した。

GPIO2,3をロータリーエンコーダに使ってはSerialがダメなんです。

解決策は「全部ポーリングにする」という割り切りでした。 ロータリーエンコーダ:GPIO直接ポーリング プッシュスイッチ:エッジ検出ポーリング(200msデバウンス) 応答性は落ち、ロータリーエンコーダはゆっくり回すことになったが、ADCサンプリングの安定性が確保できた。

 

伏兵その2:ADCノイズという本命 ISR問題を解決した後、スマートフォンの信号発生アプリで1kHz正弦波を入力してSINADを測定しました。 結果は色々と対策してもせいぜい16〜24dBです。 スマートフォンの音声出力品質を考えれば50dB以上出るはず。何かがおかしい。 原因究明を進めた結果、以下の構造が判明した。

 

 入力端子でのノイズ:ほぼゼロ(波形で確認) ADC出力のノイズ:60mV相当 入力端子にはノイズがないのに、ADC出力にはある。

これはESP32-C3内部のSAR-ADCの特性でしょう。サンプルホールド容量は数pF程度で非常に高インピーダンス。CPUクロック(160MHz)やDC-DCコンバータのスイッチングノイズが基板GNDを介して直接結合しているようだ。外部からは見えないが、ADCデジタル出力に現れてしまう。

加えて、デバッグ用に入れていたADC_LOOP_MONITOR(GPIO7でサンプリング毎にHIGH/LOWトグル→10kHz矩形波発生)もノイズ源になっていたようだ。これも除去した。

ESP32-C3 ADCの現実的なSINAD上限:

vInRMS 0.46V / vNotchRMS 0.04V = 20×log10(11.5) ≈ 21dB

 

ソフトウェアでできることはやり尽くした。これがESP32-C3単体で使う場合の実力値なんでしょうね。 測定系モニターで使う際の誤差として重要なのは、この限界を「仕様」として把握、割り切ることですね。

ESP32-C3 SINAD/THDインディケータの測定誤差:  

SINAD:実力値フロア約20dB(真値がそれ以上でもノイズで飽和してしまう)

 THD  :ADCコンタミにより約1%が加算誤差として合算される この誤差を割り切れば、12dB SINADの合否判定にはなんとか余裕があり、受信機の感度測定用インディケータとしては実用上の目安となるでしょう。 ということで、その2に続く。

M5stack Japan Tour 2026 Spring Osakaに訪問

門真の Panasonic XC KADOMAで開催された展示会を見てきました。

玄関先には何の案内看板も無くやってるのかなと思いますが、自動ドアが開くと中は人だかり。

Panasonic XC KADOMA 玄関

 

50件ぐらいの展示がありましたが、ワタシが興味を持ったのは、2cm立方の3Dプリンタ製箱に入ったガゼット。

2cmCUBEにマイコン、パルスモータ、OLEDが入っている

 

中にはマイコン、パルスモータ、OLEDなど入り16kBメモリに9kBのファームを入れて首振りしたら、画像出したりできます。

 

もう一つはサイクリング用ヘルメットで方向指示器があったり、スマフォ音声用のイアパッドがあったりします。

ヘルメット

 

他の参加者とも一緒に開発プラットフォームの話とかKiCADの話とか、盛り上がりました。次は展示する側に回ったらと煽られてしまいました。M5stackは開発着手時のプラットフォームとしてはいいですよと推薦してもらいました。

KKYORITSUの展示販売

 

展示会の雰囲気ですが、家族連れの子供が走り回ったり、展示説明用のPCにかじりついていたりで、ねこみみ系の展示も多くて、すこくアットホームな感じでした。

 

 

 

R909-SINADインディケータ(ESP32-C3 dev kit super mini)評価実験

アナログのSINAD計のブロックダイヤグラムをデジタルに置き換え、R909-SINADインディケータ(ESP32-C3 dev kit super mini)を試作しました。そこそこの出来だと思ったんですが、PC版と泣き合わせ比較評価してみることにしました。

 

それで、ESP32-C3 dev kit super miniを使用したSINADインディケータと同じソフトをPC(WIN11)のPYTHONに移植しました。ESP32-C3版ではADCを使い、10kHzでサンプリングするんですが、PC版ではPCオーディオ(ワタシのPCではRealtek High Difinition Audio,16bits,44kHz)を使います。ESP32-C3機とPYTHON版を試験信号源を使い比較します。

 

 試験信号源としては、スマートフォン(アンドロイドOPPO A73にオーディオ信号発生アプリ搭載)による1000Hz、ESP32-C3版R909-SINADインディケータ内蔵テスト信号1(PWMで1000Hzサイン波を発生し、ローパスフィルタを通過)と信号2(2000Hz毎にON/OFFする1000Hzパルス)を利用しました。

 

R909-SINADインディケータ評価実験

  2025.08.22

信号源

終端

R909-SINADインディケータ

PC_real-time SINAD indhicator

RMS電圧

SINAD値

RMS電圧

SINAD値

Smart phone  Tone Genarator

終端抵抗無し、オープン

 0.168Vrms

 29-30dB-SINAD 

 0.0679Vrms

49.4dB-SINAD

 0.583V rms

32-38dB-SINAD 

0.2378Vrms

67dB-SINAD

R909-SINAD  test SINE

1.038-1.1Vrms

10.9-13.8dB-SINAD

 0.2198Vrms

 12.5dB-SINAD

R909-SINAD test pulse

    1.15Vrms

 6.5dB-SINAD

 0.3651Vrms

7.6dB-SINAD

 

以上の結果からESP32-C3内蔵ADC利用SINADメータの性能を推定します。

信号源

信号の質

ESP32版 SINAD

PC版 SINAD

差異

スマホ発振器 (1kHz 純粋正弦波)

非常に純粋

29-38 dB

49-67 dB

20-30dB

ESP32内蔵DDS (のこぎり波+LPF)

粗い(高調波含む)

10.9-13.8 dB

12.5 dB

1-2dB

ESP32 GPIO ON/OFF (矩形波)

粗い(高調波多く含む)

6.5 dB

7.6 dB

1dB

 

推定

  1. 最初の実験(スマホ発振器)では「ESP32ADC性能」を測ったことになる
    • 純粋な正弦波(高調波成分が極めて少ない)を入力した場合、ESP32のADCの非直線性やノイズが支配的になる
    • 結果としてPCオーディオとの間で20-30dBもの差が出た → これはESP32ADCの性能限界
  1. 2番目・3番目の実験は「測定対象の信号の質」を測ったことになる
    • ESP32の内蔵DDSが出力する「のこぎり波+LPF」や「矩形波」は、もともと多くの高調波歪みを含んでいる
    • この場合、信号自体のSINADが低い(10-13dB, 6-7dB)ため、ADCの影響は相対的に小さくなっている
    • ESP32版とPC版の差が1-2dBしかないのは、測定対象の信号の質が悪く、ESP32版の劣化の影響受けない
  1. 結論:ESP32ADCは「12dB SINAD付近」では何とか使えるようだ

SINAD測定範囲

ESP32版の信頼性

理由

10-15dB (感度測定の核心範囲)

実用可能

信号自体の歪みが支配的。ADCのノイズ影響は1-2dB以内

20-30dB

注意必要

ADCのひずみやノイズ影響が出始める

40dB以上

事実上不可能

ADCの自己ノイズ/歪みが支配的

 

本試作の実験や評価に関しJH1LHVさんのブログ記事を参考にしました。情報提供に感謝します。

本記事の進め方についてJR1PWZさんのブログ記事を参考にしました。情報提供に感謝します。

手元の受信機2種類でESP32版のデジタルSINADインディケータ動作を試してみました

ESP32-C3を使うデジタル化SINADインディケータの使い方の紹介です。

 

まずはSi4732を使用したHF/FM受信機のATX-miniで27MHz(AM 80%Mod)の受信感度を測りました。-104dBMと言う値でした。12dBSINAD設定にするにはボリウム調整を最大にし、トランスでステップアップが必要でした。

ATX-mini 27MHz 1000Hz80% AM -104dBm 12dBSINAD

ATX-miniの感度測る1 FFTモニター

ATX-mini

JH1LHV-OMの測定事例では26MHz(AM 30%Mod)で-100dBmと言うことですので、その差は変調度の設定かと思います。変調度30%ではSINADは12dBまで上がりませんでした。

 

また、R80中国製エアバンド受信機も調べてみました。こちらはNE602-MC3361-TA7640-LM386と言う構成の受信機です。ところが、問題発生です。ボリウム調整してもSINADが8dBより上がりません。1000Hzで変調深めの80%を入れ、FFTを見てみると500Hzに成分があります。MC3361と言う石がFM用のチップセットであるのが原因なのでしょうか。

なので、R80エアバンド受信機の感度はSINAD8dBの値になります。

R80 118.1MHz 1000Hz80% AM -105dBm 8dBSINAD 

R80の感度測定1

R80の感度測定2

 

なお、C401を測った時は問題なく、Cスムースに測れました。 

 nobcha23.hatenablog.com



 

SINADインディケータのFFT機能活用、受信信号波形をモニターする

ESP32-C3でデジタル化SINADインディケータを作ったんですが、SNも測れるようにしようかとAIに相談しました。そうしたら、FFT機能があるからすぐ算出可能と言われ、ESP32-C3でやるかと検討してみました。しかしその前に、ESP32-C3版をPCに乗せ換えたPYTHON版のSINADインディケータがあるのを思い出しました。お試しならこっちの方が簡単そうです。そこでAIさんに相談したらすぐに作ってくれました。

 

出来上がったPYTHON版のSINADインディケータの画面は次のような感じです。波形表示とかFFT表示なんかも付いていて受信信号波形をモニターしながらSINAD値を測ってくれます。ATX-miniを27MHzのAM受信、tinySAから1kHz 変調RF信号‐102.5dBmを注入。
画面でFFTモニター。1kHz復調音声とノイズフロアが見える。

27MHz@ATX-miniをSINADインディケータでモニター

入力信号波形表示

 

ところが、ここで大きなAIさんの勘違いを発見。SN値と言うのはRF信号がないときのNレベルを測り、次にRF信号を入れるという二段階だったはず。それをリアルタイムで測ったら、SINAD値と同じ値になるはずです。受信感度基準のSN法で求めているSNとは話が違う。

 

今回作ったPYTHON版のSINADインディケータのSNと言うのはFFT処理による結果で、SINAD値はQが10のノッチフィルタを入れた計算値と言うことですね。それで、気になるのは算出方法の違いでSINAD値とSN値が1dBぐらい違うところです。

 

これはSINADのノッチフィルタのQが10で、FFTの方はbin幅 = 48000/512 = 93.75Hz/binで、±1binで信号を抽出 → 信号帯域幅 = 3×93.75 = 281Hzの違いだという事のようです。SINADのQをもっと上げるべきなのか、でもtinySAのクロック精度がいまいちでQは10がいいとこだった。Q可変にしようという計画ありましたね。次の課題に置いときます。

 

ここでAIさんが言うには何も今更操作が煩雑なSN法にこだわらず、SINAD一本で行きましょうとの話になりました。したがって、SINAD/SNインディケータDIYは中止することにしました。ESP32-C3のSINADインディケータに関するDIY情報はGITHUBに置いてありますので、ご活用ください。

github.com

 

今回AI(CLAUDE)も誤解をした受信機感度測定基準なのですが、後戻り無いよう3方式についてAiさんにプレゼン資料をまとめてもらいました。

 

受信機感度測定基準の3種の方式

受信機感度測定基準の3種の比較表

受信機感度測定基準の3種のまとめ

 

ところで、上の測定画面ではSINAD12ではなく、中途半端な13.1dBになっています。ATX-miniの受信回路はSi4732で、DSPチップなので、それが影響しているように思われます。受信信号波形モニターしているとわかったんですが、感度点近辺だと、DSPが受信信号をキャプチャできると、きれいな1kHzがでますが、外れるとノイズ波形になります。そして、その状態が数ヘルツぐらいでいったりきたりします。DSPチップのソフト処理で受信信号への同期がかかったり外れたりしているだろうと推定しました。なのでアナログ的に調整して12dBにもっていくことができないんです。

Rasberry PI pico zeroが5個で872円

春節明けぐらいでしょうか、Ali expressでRasberry PI pico zeroが5個送料無料で872円と言う案内が来ました。ちょっと怪しいかもと思いながらも注文しましたが、3月半ばには到着しました。

 

RASP PP 5個

早速Arduino IDEにつないで試験書込みしましたが、異常ありません。これはお得だという結論です。そして、その後Feedback書いてと言うメールが来ましたが、注文履歴をみようとしても削除されていて見当たりません。なんだか狐につままれたような感じです。同じようなものは一個400円+送料200円で売られていて、めちゃ安だったということですね。

 

そんな経緯でRASP PPが一杯手に入ったので、この基板を使うDIYではSiliconvalley4066さんのオシロシリーズを移植してみるのが手っ取り早いか思って早速やってみました。

スケッチはGITHUBからダウンロードしました。

RASP PPにオシロ機能を移植

当たり前ですが、何の修正もなく動きました。実用にするには入力にOPアンプとか、操作スイッチも必要です。

 

この際、久しぶりに基板でも作って遊ぼうかと計画中です。JH1LHVさんが最近iPhoneアプリでSINADメータを作られているのに刺激を受け、SINAD/SNインディケータを作ろうかと検討しています。ただ、先日作ったSINADインディケータはESP32-C3を使ってましたので、SN機能を追加する移植が必要です。R909-DSPシリーズの3.3V化がESP32-C3で進行中ですが、FCNT機能の件があるので、ESP32-C3はやめてRASP PPにしようかと思ったりしています。

AIさんに教えられ、Reddit投稿やってみたら、SPAM認定されました


AIさんを利用すると、便利だし、作業そつなくこなしてくれたりで、重宝してます。また、暇な時には話し相手にもなってもらえるので、手放せません。

さて、そうした中でAIさんに勧められてやったら、これは何なんだということがあったので、報告します。

 

まずはReddit投稿。AIさんから、海外からのアクセスを増やすなら、ここに記事ポストしたらと推薦されました。
それで、原稿案とか、イラストなんかも作ってもらって投稿した訳です。そしたらなんと、投稿削除されました。そしてその理由が”AI SPAM”と言う判断でした。確かにAIさんに書いてもらったちょっと歯の浮くような書きっぷりの原稿と、AIさんが書いてくれたいかにもAI作というイラストですからね。

 

どうもAIに作らせたような原稿はSPAMと認定され拒絶されるルールがあるみたい。そこで、モデレータさんに原稿イラストはAIさんに作ってもらったが、原稿の記事内容は真っ当なものですと申し上げたら、英語が苦手でAIにやらせるのは良いが、そのままではAIくさくてダメ、自分の言葉でコメントすること、また、AIのイラストはやめた方が良いとのことでした。味噌付けたんで、Redditはやめ。

 

 

そこで、今度は河岸を変え、Hackadayに投稿しました。こちらでは問題なし。

 

次にモデレータにアピールメールを送ったら、メイン記事に取り上げられました。

hackaday.com


そしたら、今度はなんなんだ言うようなコメントが付きました。LCメータの投稿なんですが、リード線のインダクタンスを考慮してないから糞数値しか得られないという、ちょっと汚いコメントでした。筋論からすると正解ですが、手巻きの1μHぐらいのコイルの目安を測りましょうという記事に10nHぐらいの寄生インダクタンスがどうのというのはわかっているのかな。まあ、愉快犯みたいな人がいっぱいいるんだなと思った次第です。

 

これにめげず、Hackadayに新ネタを投稿しようかと検討中です。つぎはどうなるかなあ。