ESP32-C3 Super Miniで2CH WEBオシロスコープ・Pulse generator・Function Generator

更新日 2026.10.20 登録日 2026.07.02
* *

以前 ESP32で2CH WEBオシロスコープ・Pulse generator・Function Generator を作りましたが、コンパクトなESP32-C3 Super Miniでも使えるようにしました。 ただし現状ではDMAを使ったADCが出来ないのでサンプリング周波数の上限が20kspsに少し届かないくらい DMAを使ってもサンプリング周波数の上限が83kspsなのであまりお勧めできない仕上がりになっています(2026.08.02 修正)。 シングルコアのESP32-C3でも何とかWEBオシロスコープとして動いていますが若干不安定です。 まだ不完全ですがPCやスマートフォンの大きな画面で波形を確認できますので、サンプリング周波数が遅くてもよいから使ってみたいという方はお試しください。

ソースコードは「ESP32で2CH WEBオシロスコープ」と一本化できたのですが、性能に違いがあり過ぎるのでこの別ページで紹介します。

開発環境は Arduino IDE 2.3.10 + esp32 by Espressif Systems 3.3.12です。 (2026.10.03 update)

この環境ではAnalogRead()が使えるのですがオーバーヘッドが多過ぎるようで遅いので、adc1_get_raw()を使うようにしました。それでもまだ遅いです。 無印ESP32はI2Sを使って500kspsまで出来るようにしましたが、ESP32-C3はI2Sが有るもののADCとの接続が有りません。DMAを使うContinuous Modeが使えるはずなのですが、Arduino環境ではコンパイルが通っても壊れたデータしかが出て来ません。ESP-IDF v4.4+なら動くらしいのでArduino環境が対応するのを待つしかありません。

(2026.08.02 追記)あれこれ試しているうちにDMAを使うContinuous Modeが使えるようになりました。設定の仕方が悪かったのか、esp32 by Espressif Systems 3.3.11になって良くなったのか分かりません。それでもサンプリング周波数の上限は83.333kspsとあまり高くはありません。

ソースコード

最新版はGitHubのESP32OLEDOscilloscopeに置いてあるものが使えます。
https://github.com/siliconvalley4066/ESP32OLEDOscilloscope

ESP32WebOscillo143.zip (2026.10.20 update)

ボードは"Nologo ESP32C3 Super Mini"を選択します。
USB CDC On Bootは何故か"Enabled"が二つあって"Disabled"が無いのですが"Enabled"であればシリアルモニターが使えます。

OLEDは小さくても良いので0.96インチにして、ドライバはSSD1306用です。Adafruit_SSD1306.hがインストールされていない場合はライブラリマネージャーから検索してインストールしてください。写真はAliExpressで購入したOLEDとスイッチ4個が一体になったモジュールを使いました。SH1106用にするには#define DISPLAY_IS_SSD1306の行をコメントにしてAdafruit_SH110Xをライブラリマネージャーから検索してインストールすればOKです。

WebTask.inoの
const char* ssid = "XXXX";
const char* pass = "YYYY";
に使用するWiFiアクセスポイントのssidとpasswordをXXXXとYYYYに記入する必要があります。ソースコードを少し変更すればAPモードにすることも可能です。
(削除 2026/10/20)

v1.43からWiFiマネージャーを採用しました。 初期設定を行う際は、「ESP32_XXXXXXXX」(「XXXXXXXX」は固有のチップID)という名称のアクセスポイントに接続し、ブラウザで「192.168.4.1」にアクセスしてください。その後、接続先となるWiFiネットワークのSSIDとパスワードを入力します。一度設定が完了すれば、それ以降の設定は不要です。設定を変更したい場合は、デバイスの起動時に「DOWN」ボタンを長押ししてください。 (追記 2026/10/20)

WebSocketsのライブラリはライブラリマネージャーから検索できるものを使いました。
WebSockets by Markus Sattler version 2.7.2

余計な電波を出したくないとか消費電力を減らしたいとか技適が無いので怖いとかでWEB機能が不要な場合は

//#define NOWEB
のコメントを外せば無効に出来ます。

使用ライブラリ: (追記 2026/10/20)

  • Adafruit_SSD1306
  • Adafruit_SH110X
  • arduinoFFT by Enrique Condes 2.0.0
  • WebSockets by Markus Sattler version 2.7.2
  • WiFiManager by tzapu 2.0.17
  • 回路図

    ADC_ATTEN_DB_12にしても2.9V辺りでAD変換の値が4095になるので3.3Vまで観測できるように入力にアッテネータを入れました。抵抗値は現物合わせで調整してください。
    *

    DCモードだけにして簡単にすることができます。
    *

    操作方法

    ESP32で2CH WEBオシロスコープ・Pulse generator・Function Generatorと同じです。

    Pulse Generatorについて

    LEDCのPWMで発生できるパルスをほぼ全て出せるようにしました。80MHzを1/2から1/16384まで設定できます。分周比は1/1から1/256まで全て使います。発生できる周波数は19.07Hzから40MHzまでになります。周波数自体を設定するのではなく、発生できる上または下の周波数へ設定を変更して、その設定で発生される周波数を計算して表示します。Duty cycleも実現可能な値が限られている。周波数の分解能は1/256になり、ATMEGA版より荒くなります。なお、分周器がRate Multiplierなのでジッターが発生する可能性があります。

    v1.41まではLEDCに関しての認識が間違っていたのが分かってv1.42で設定方法を修正しました。
    80MHzを1/1から1/1023まで分周することと、Resolutionを1bitから14bitまで使うことで4.773Hzから40MHzまでを発生出来ます。
    高い方の周波数はResolution=1bitで1/1, 1/3, 1/4 ... 1/1023と変化させて小数点以下を使わずになるべく細かく周波数を設定できるようにしましたが、dutyは50%固定になります。
    低い方の周波数はResolution=14bitで1/512から1/1023まで変化させて最低4.773Hzになります。
    このような設定を実現するためにより低レベルのledc_ll_set_duty_resolution()やledc_hal_set_clock_divider()というライブラリを使っています。周波数カウンタでもLEDCを使っていて時々相互干渉してリブートすることがあります。なるべく干渉が無いように対策をしていますが完全には解消できていません。 (2026.10.03 update)

    DDS Function Generatorについて

    ESP32-C3にはDACが有りません。その代わりにPWMを使っても良いのですがSigma-Delta変換を使いました。

    波形の発生原理には Arduino Sinewave Generator を流用させていただきました。波形データはその他色々な所から集めました。周波数の設定と波形の選択だけがオリジナルです。周波数の分解能は取り敢えず0.01Hzにしました。インタラプト処理が入るので速いサンプリング時にオシロスコープの波形が間延びするようなら明示的にOFFにした方が良い。インタラプトのオーバーヘッドが大きいようで、サンプリング周波数が5kHzまでしか上げられませんでした。ATMEGA版の31kHzより遥かに低い周波数です。メモリに余裕があるので用意した23波形すべてを使えます。

    ESP32-C3にはCosine Wave Generatorが無いので波形発生はSigma-Delta変換だけで、0.01Hzから999.99Hzまで指定できます。波形テーブルをフルに使うのは19.5Hz以下ですが、実用的な上限は1周期50サンプルで良ければ100Hz程度です。

    Sigma-Delta変換の矩形波"rect256"で時々中間レベルが出てしまいますが原因不明です。

    DMA ADCサンプリングについて

    DMAを使うContinuous Modeが使えるはずなのですが、Arduino環境ではコンパイルが通っても壊れたデータしかが出て来ません。ESP-IDF v4.4+なら動くらしいのでArduino環境が対応するのを待つしかありません。(2026.08.02 削除)

    (2026.08.02 追記)DMAを使うContinuous Modeを使います。それでもサンプリング周波数の上限は83.333kspsとあまり高くはありません。50ksps以上はシングルチャンネル、40kspsから10ksps迄はデュアルチャンネルで動作させます。

    ADCの非直線性

    ESP32-C3も無印ESP32と同じようにADCの直線性が悪く、特に3.3V近辺がつぶれています。 その曲がり具合も違っていたので2区間の直線近似の補正値を変更しました。

    ESP32-C3 Super Miniの注意点

  • GPIO2がBoot Mode端子になっていて10kohmでプルアップされている。高インピーダンスのADC入力としては使えない。
  • GPIO8とGPIO9がBoot関係端子になっていて10kohmでプルアップされている。I2Cで使う分には大きな問題は無いが入力端子として使う場合は注意が必要。
  • GPIO8はオンボードLED (LED_BUILTIN) につながっているのでI2Cを使う場合にはLEDを制御してはいけない。I2C通信があると点滅する。オンボードLEDを自由に点滅したい場合はI2Cのピン割り当てを変更する必要がある。
  • GPIO9はBOOT buttonにつながっている。I2C通信中ににボタンを押すと通信エラーになる。
  • Known Bugs

  • 波形表示が所々途切れることがある。
  • ESP32-C3のADCの直線性が悪く、目視では分かり難い程度に補正しているが不十分かも。
  • 原理的に周波数測定には画面上で2周期以上が必要。
  • トリガモードのOneがうまく機能しない。
  • トリガが掛からない状態でトリガモードをNormにすると、トリガ検出から抜け出せなくなり操作不能になる。トリガが掛かる入力を入れれば復帰する。
  • 2ch表示で信号源インピーダンスが大きい場合は相互に観測波形に影響が出る
  • 2ch間でレベル差が大きい部分には相互干渉が発生することがある。
  • Pulse generatorは周辺クロックをRate Multiplierで分周していて256/256から129/256の周波数を発生する。周波数の高い方でも一見細かく設定できているように見えるがジッターが多い。その後設定方法を変更して整数分の1だけを使うようにしてジッターは減っている。 2026.10.03 update
  • HOLD中の時間軸拡大は出来ません。(2026.10.03 update)
  • 時間軸レンジ1ms/divの2ch表示と500us/divではサンプリングレートが2割程低下している。(2026.08.02 追記)v1.37でContinuous Modeを利用して解消した。
  • WEB表示のWave Selectの初期値がsine256のままで実機の状態を反映していない。
  • AC/DCの切り替えでオフセットを自動切換えしていない。その都度リセットしてください。
  • 改良可能性

  • 取り込みサンプル数を増やして表示位置を移動できるようにしてみたい。
  • Hold Off調整機能を入れた方が便利かもしれない。
  • 機能概要

    機能 内容
    入力チャンネル数 2
    入力結合 DC and AC
    入力電圧範囲 0 to 3.3V
    入力インピーダンス 125kohm
    電圧レンジ(volts/div) 1V, 0.5V, 0.2V, 0.1V, 50mV
    時間レンジ(time/div) 10s, 5s, 2s, 1s, 0.5s, 0.2s, 0.1s, 50ms, 20ms, 10ms, 5ms, 2ms (5ksps),
    (DMA) 1ms, 500us, 250us, (samples only 1 channel) 200us, 120us
    トリガモード Auto, Normal, Scan
    トリガ極性 rise/fall edge
    トリガソース CH1 or CH2
    トリガレベル調整 画面内位置を上下に調整
    外部トリガ No
    波形位置調整 上下に調整可能
    波形反転表示 Yes
    電圧測定表示 Max, Average, Min (AC入力でもDCレベルを表示)
    周波数&Duty測定 Yes
    電圧・周波数・Duty表示 表示・非表示切り替え
    文字表示 文字サイズ固定
    FFT Yes
    A/D変換分解能 12bits
    サンプル数 128samples/channel 12bit/sampleを電圧レンジに応じて0から400にスケーリングして表示
    表示解像度 128x400 dots, 水平10dots/div 垂直50dots/div
    等価時間サンプリング No
    設定状態EEPROM保存 Yes
    操作方法 タクトスイッチ4個 (Left, Right, Down, Up) または 5方向スイッチ (Left, Right, Down, Up)
    プリトリガー No
    ホールドオフ機能 No
    時間軸拡大表示 x2, x5, x10 sin(x)/x補間
    X-Y表示 No
    Pulse Generator 4.773Hz to 40MHz 約3.3Vpp方形波 Duty ratio可変
    Function Generator 8bit Sigma-Delta DDS 0.01Hz to 999.99Hz(実用は100Hzまで) 約3.3Vpp
    23波形 sine, saw, revsaw, triangle, rectangle, 20% pulse, 10% pulse, 5% pulse, 1dot pulse, noise, gaussian noise, ECG, sinc5, sinc10, sinc20, sine 2 harmonic, sine 3 harmonic, chopped sine, sine abs, trapezoid, step2, step4, chainsaw
    周波数カウンタ No
    PCへのデータ転送 No
    SDカードへの波形保存 No


    <=Arduinoで電子工作に戻る
    <=Siliconvalley4066番地に戻る
    ゲストブックへ
    siliconvalley4066@yahoo.co.jp