ESP32とOLEDで2CHオシロスコープ・Pulse generator・Function Generator

更新日 2022.12.25 登録日 2022.05.31
*

大阪教育大学の光永さんの Arduino でオシロスコープ は古い128x64のLCDディスプレイ用に作られたものですが、それを基に128x64の1.3インチOLEDで使えるように変更して ArduinoとOLEDで2CHオシロスコープ・Pulse generator・Function Generator・周波数カウンタ を作ったので、それを基にESP32に移植しました。
Pulse generatorとDDS Function GeneratorとFFTは実装済みですが、周波数カウンタは未実装です。また、等価時間サンプリングはESP32で実装する方法が分からないのであきらめました。

開発環境は Arduino IDE 1.8.19 + Arduino core for the ESP32 2.0.3です。 この環境ではAnalogRead()が使えるのですがオーバーヘッドが多過ぎるようで遅いので、adc1_get_raw()とadc2_get_raw()を使うようにしました。それでもまだ遅いです。 I2Sを使って1Mspsまで出来るようにしてみましたが不安定です。500kspsまで出来るようにしてみました。(訂正 2022.12.25)

ADCのリニアリティーは悪いし、高速サンプリングは不安定、PWMはジッターが不安、Cosine Wave Generatorは周波数の高い方でギザギザが乗ると良いところ無しの感がします。それでも曲がりなりにも200kHzの正弦波を出せるというところだけは利点でしょうか。

ESP32はCPUパワーが必要な場合やWiFiやBlueToothを使う用途に適していると思いますが、余っているESP32が有ったら一つ作っておくと役に立つこともあるかもしれません。そこで、WiFi機能を利用してWEBオシロスコープにする実験中です。小さいOLEDではなくパソコンやタブレットやスマートフォンのWEBブラウザの画面で波形を見ることができるようになりました。
* ESP32で2CH WEBオシロスコープ・Pulse generator・Function Generator

ソースコード

ESP32GOscillo124a.zip 2022.12.25 update

ESP32GOscillo100.zip Old version

OLEDのドライバはSH1106用です。Adafruit_SH110X.hがインストールされていない場合はライブラリマネージャーから検索してインストールしてください。SSD1306用にするには#define DISPLAY_IS_SSD1306のコメントを外せばOKです。

回路図

10:1プローブを使うために入力インピーダンスを1Mohmに近付けたいので次のような入力回路にしました。
*

操作方法

ATMEGA版ではタクトスイッチ4個で操作するようにしましたが、スイッチの場所を取るので5方向スイッチが使えるようにしました。5方向スイッチでは上下同時押しや左右同時押しが出来ないので、右上同時押しと左下同時押しに変更しました。#define BUTTON5DIR を有効にすれば5方向スイッチにすることができます。
画面右側のメニューは4ページ構成になっています。UpボタンとDownボタンでメニュー内の項目を移動します。一番上の項目でUpボタンを押すと前のページに切り替わります。一番下の項目でDownボタンを押すと次のページに切り替わります。それぞれの項目の位置でRightボタンかLeftボタンを押すとその項目の値を変更したりOn/Offの切り替えをします。
ページに関係なくUpボタンとDownボタンを同時押しすると文字表示を消して全画面波形表示になります(5方向スイッチでは右上同時押しになります)。再度同時押しすれば元に戻ります。

Page 1

  • 一番上がCH1の電圧レンジ、2番目がCH2の電圧レンジです。Rightボタンを押すと値が上がり、Leftボタンを押すと下がります。
  • 3番目が時間軸レンジです。Rightボタンを押すと早くなり、Leftボタンを押すと遅くなります。
  • 4番目はReal Time SamplingかDMA使用かの表示で、この位置はスキップします。
  • 5番目はトリガモードで、Rightボタンを押すとAuto->Norm->Scan->One->Autoと切り替わります。Leftボタンを押すと逆方向に切り替わります。
  • 6番目はトリガソースとトリガエッジの設定です。TG1が表示されている時はCH1をトリガソースにします。Leftボタンを押すとトリガソースを切り替えます。Rightボタンを押すとトリガエッジの上下の切り替えが出来ます。上矢印か下矢印が表示されてます。
  • 7番目はトリガレベルです。Rightボタンを押すと値が上がり、Leftボタンを押すと下がります。波形エリアのグリッドの右端に短い線でトリガレベルを表示しています。ボタンを長押しすると連続変化します。
  • 8番目はRun/Holdの切り替えです。RightボタンでもLeftボタン交互に切り替わります。
  • Page 2

  • 上半分がCH1の設定項目、下半分がCH2の設定項目。
  • 2番目がCH1の、6番目がCH2の非表示や反転表示の切り替えです。Leftボタンで表示・非表示、Rightボタンで正転・反転の切り替えが出来ます。
  • 3番目がCH1の電圧レンジ、7番目がCH2の電圧レンジです。
  • 4番目はCH1の、8番目がCH2の波形表示上下位置です。Rightボタンを押すと上に上がり、Leftボタンを押すと下がります。ボタンを長押しすると連続変化します。RightボタンとLeftボタンを同時押しすると標準の位置最下端にリセットします(5方向スイッチでは左下同時押しになります)。
  • Page 3

  • 一番上がCH1の電圧レンジです。
  • 2番目が時間軸レンジです。
  • 3番目がFFTモード切り替えです。Rightボタンを押すとFFT表示になります。Leftボタンを押すと波形表示に戻ります。FFT表示はCH1のみです。
  • 4番目"FREQ"は周波数とDuty比計測結果の表示切り替えです。Rightボタンを押すと表示になり、Leftボタンを押すと非表示になります。
  • 5番目"VOLT"は電圧計測結果の表示切り替えです。Rightボタンを押すと表示になり、Leftボタンを押すと非表示になります。
  • 6番目"PWM"はPulse generatorのOn/Offです。Rightボタンを押すとOnになり、Leftボタンを押すとOffになります。
  • 7番目"DUTY"はPulse generatorのDuty比設定です。Rightボタンを押すと増加し、Leftボタンを押すと減少します。ボタンを長押しすると連続変化し加速します。
  • 8番目"FREQ"はPulse generatorの周波数設定です。Rightボタンを押すと増加し、Leftボタンを押すと減少します。ボタンを長押しすると連続変化し加速します。
  • Page 4

  • 一番上がCH1の電圧レンジです。
  • 2番目が時間軸レンジです。
  • 3番目"DDS"はDDS Function GeneratorのOn/Offです。Rightボタンを押すとOnになり、Leftボタンを押すとOffになります。
  • 4番目はDDS Function Generatorの波形切り替えです。RightボタンとLeftボタンでは逆方向に切り替わります。
  • 5番目"FREQ"はDDS Function Generatorの周波数設定です。Rightボタンを押すと増加し、Leftボタンを押すと減少します。ボタンを長押しすると連続変化し加速します。
  • 【未実装】6番目"FCNT"は周波数カウンタのOn/Offです。Rightボタンを押すとOnになり、Leftボタンを押すとOffになります。7行目に計測した周波数を表示します。他のページでは表示しません。OnにするとPulse generatorとDDS Function Generatorは停止します。
  • Pulse Generatorについて

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

    DDS Function Generatorについて

    Lab3 - Laboratory for Experimental Computer Science を流用させていただきました。波形データはその他色々な所から集めました。周波数の設定と波形の選択だけがオリジナルです。周波数の分解能は取り敢えず0.01Hzにしました。インタラプト処理が入るので速いサンプリング時にオシロスコープの波形が間延びするようなら明示的にOFFにした方が良い。インタラプトのオーバーヘッドが大きいようで、サンプリング周波数が5kHzまでしか上げられませんでした。ATMEGA版の31kHzより遥かに低い周波数です。せっかく8ビットDACがあるのに残念ですが、とりあえずローパスフィルタは無くても使えます。その代わりメモリに余裕があるので用意した23波形すべてを使えます。
    (追記 2022.08.09)リンク先が消えているようなので同じ内容を探してみました。 Arduino Sinewave Generator

    ESP32にはCosine Wave Generatorがあって、CPUの負荷なくsine波形なら50Hzから200kHzまで出せる。
    参考: GitHub - krzychb/dac-cosine: API to operate cosine waveform generator inside ESP32
    ただし、約130Hzより低い周波数はRTC 8 MHz Clockの分周比を設定する必要があり、他に何か影響があると怖いので分周比の設定はやめた。
    dac_cw_generator_config()で130Hzから55000Hzまでuint32_tで出来るのだが、試してみると65537Hzまで行けた。65535の二つ上までってどういうことなのか分からないが、内部の計算でオーバーフローとか起こっているのだろうか?周波数は何でもできるわけではなく130Hzステップでしか変わらないようだ。また、オフセットの設定にバグがあって、int8_tで-128から+127まで設定できるはずなのが、0を設定しても-128になってしまう。オフセットと周波数の設定はこのAPIを使うのはやめて、上記参考記事の方法を使わせてもらった。 結局129.70Hzから129.70Hzステップで約200kHzまで設定できるようになりました。上限はもっと行けて600kHzでも何かしら波形が出てきますが波形歪みがひどくなります。100kHzでも結構ギザギザが乗っています。

    DDS Function GeneratorとCosine Wave Generatorとの切り替えは周波数によって切り替えます。
    0.01Hzから518.79HzまではDDS Function Generatorで、それ以上は波形の設定にかかわらずCosine Wave Generatorに切り替わり、518.80Hzから129.70HzステップでCosine Wave Generatorになります。周波数が下がる方向には518.80Hzから389.10Hz, 259.40Hz, 129.70まではCosine Wave Generatorでそれ以下はDDS Function Generatorになります。この時の389.10Hz, 259.40Hz, 129.70はDDS Function Generatorよりきれいな波形が出せます。

    I2S(Inter-IC Sound) ADCサンプリングについて

    I2Sを使えば150kspsができるとか、1Mspsのオシロを作ったという記事 esp32TTGO_i2s_scope (tested on core 1.0.5, not working with esp core 2.0.3) があったので実装してみました。時間軸の10us, 20us, 50us, 67us, 100us, 200us/div20us, 40us, 100us, 133us, 200us, 400us/divがI2Sで動作します。(訂正 2022.12.25)

    ESP-IDFのドキュメント ESP-IDF Programming Guide には150kspsが上限と書いてあるのですが、それ以上でも設定できたので1Mspsまで設定できるようにしました。総じてI2Sでのサンプリングは時間軸がふらついて不安定です。1Mspsでデータは取れますが、同じ値が3回から4回程続くのでADCの実力は200kspsから300kspsの間位と思われます。仕様で150kspsまでとなっているのは妥当な所でしょう。150kspsになる時間軸は67us/divです。波形観測したところでは50kHzを超えた信号は訳の分からない波形になりました。測定対象に注意が必要です。

    (追記 2022.12.25)データをよく見ると、サンプリング周波数が低い時でも2回ずつ同じ値が続いています。どうやらI2S_CHANNEL_FMT_ALL_LEFTにしてもデータの並びはLRLRでRにはLの値が入っているようです。そこでLの値だけ取り出すように変更したら、階段状態が無くなり綺麗なデータになりました。したがって、1Mspsだと思っていた設定では500kspsになります。

    Known Bugs

  • 波形表示が所々途切れることがある。
  • ESP32のADCの直線性が悪く、特に0V近辺と3.3V近辺がつぶれている。
  • 原理的に周波数測定には画面上で2周期以上が必要。
  • 周波数測定と電圧測定はCH1のみ。CH2のみ表示でもCH1の測定値が出る。
  • トリガモードのOneがうまく機能しない。
  • トリガが掛からない状態でトリガモードをNormにすると、トリガ検出から抜け出せなくなり操作不能になる。トリガが掛かる入力を入れれば復帰する。
  • 2ch表示で信号源インピーダンスが大きい場合は相互に観測波形に影響が出る。入力インピーダンスが下がるのを許容して入力回路の抵抗値2Mohmを200kohm以下に下げれば軽減できると思う。
  • 2ch間でレベル差が大きい部分には相互干渉が発生することがある。
  • ADC入力の保護抵抗を省略したのでESP32が壊れやすい。直列に1kohmから10kohmの抵抗を入れておいた方が良い。
  • Pulse generatorは周辺クロックをRate Multiplierで分周していて256/256から129/256の周波数を発生する。周波数の高い方でも一見細かく設定できているように見えるがジッターが多い。
  • これ単体で2チャンネル入力にPulse generatorとFunction Generatorの出力を入れて波形観測して遊べます。
  • 改良可能性

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

    機能 内容
    入力チャンネル数 2
    入力結合 DC and AC
    入力電圧範囲 0 to 3.3V
    入力インピーダンス 1Mohm
    電圧レンジ(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, 1ms (10ksps),
    (samples only 1 channel) 500us, 200us, 100us, 67us, 50us, 20us, 10us (1Msps) 400us, 200us, 133us, 100us, 40us, 20us (500ksps)
    トリガモード 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 (8bits/channel) 12bit/sampleを電圧レンジに応じて6bitにスケーリングして表示
    表示解像度 128x64 dots, 10dots/div
    等価時間サンプリング No
    設定状態EEPROM保存 Yes
    操作方法 タクトスイッチ4個 (Left, Right, Down, Up) または 5方向スイッチ (Left, Right, Down, Up)
    プリトリガー No
    ホールドオフ機能 No
    時間軸拡大表示 No
    X-Y表示 No
    Pulse Generator 4.768Hz to 40MHz 約3.3Vpp方形波 Duty ratio可変
    Function Generator 8bit DAC DDS 0.01Hz to 518.79Hz(実用は200Hzまで) 約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
    8bit DAC Cosine Wave Generator 129.70Hzから129.70Hzステップで200kHz程度まで。
    周波数カウンタ No
    PCへのデータ転送 No
    SDカードへの波形保存 No

    関連するオシロスコープ

  • Arduino UNO/Nano OLED版: ArduinoとOLEDで2CHオシロスコープ・Pulse generator・Function Generator・周波数カウンタ
  • Arduino UNO/Pro Mini LCD版: ArduinoとLCDタッチシールドで2CHオシロスコープ
  • ESP32 OLED版: ESP32とOLEDで2CHオシロスコープ・Pulse generator・Function Generator
  • ESP32 OLED WEB版: ESP32で2CH WEBオシロスコープ・Pulse generator・Function Generator
  • ESP32 LCD WEB版: ESP32とTFTタッチスクリーンLCDで2CH WEBオシロスコープ・Pulse generator・Function Generator
  • Raspberry Pi Pico OLED版: Raspberry Pi Pico WとOLEDで2CH WEBオシロスコープ・Pulse generator・Function Generator・周波数カウンタ
  • Raspberry Pi Pico LCD版: Raspberry Pi Pico WとTFTタッチスクリーンLCDで2CHオシロスコープ・Pulse generator・Function Generator・周波数カウンタ
  • STM32F103C8T6 OLED版: STM32F103C8T6とOLEDで2CHオシロスコープ・Pulse generator・Function Generator
  • STM32F103C8T6 LCD版: STM32F103C8T6とTFTタッチスクリーンLCDで2CHオシロスコープ・Pulse generator・Function Generator
  • STM32F103C8T6 0.96-inch 80x160 LCD版: STM32F103C8T6と0.96-inch 80x160 LCDで2CHオシロスコープ・Pulse generator・Function Generator
  • STM32F103C8T6 DLO-138-SPI: STM32F103C8T6とTFT LCDで2CHオシロスコープDLO-138-SPI

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