radiopenchさんが128x64OLEDモジュールを使ったペン型オシロスコープを開発されています。 ブレッドボード版もあります。時間軸は200us/divまでで、4倍拡大で50us/divになります。
ラジオペンチ ペン型オシロスコープこれを4倍拡大で20us/div(25samples/div)まで出来るようにしてみました。75kHzの矩形波を見てみました。
ついでにFFTによるスペクトラム表示もできるようにしてみました。D6ピンをLOWにするとFFT表示になります。
メモリに余裕がないので128ポイントでのFFTです。レベル方向はとりあえず適当にスケーリングしました。
また、オーディオ信号の観測のために時間軸レンジ20us/divの先にFFTの19.2kHz、9.6kHz、4.8KHzレンジを付けておきました。
ソースコードは
20210219_OLEDoscilloScopeSh1106_V310.ino
校正用パルス信号も発生できます。上記ソースコードと同じフォルダにパルス発生用のソースファイルを置いて、
setup()の中から一回だけpulse()を呼び出すだけです。ただし、出力するポートはD10固定なので、DOWNスイッチの入力ピンを移動する必要があります。
私は面倒なので最初からスイッチを付けていないので気にしません。あのダイオードの向きは逆だと思うので。
周波数とデューティー比はユーザーインターフェースを作るのが面倒だったのでソースコードで決め打ちです。実は上記写真はこのパルスを観測したものです。
校正用なら普通は1kHzですが75kHzにしています。振幅の精度は電源電圧とArduinoの実力次第です。
追加するファイルとまとめたソースコードは
20210226_OLEDoscilloScopeSh1106_V311.zip
もっと高い周波数まで見てみたいということで、等価時間サンプリングを追加してみました。
これには九州工業大学大学院情報工学府の
Arduino 簡易オシロスコープ
のソースコードを利用させていただきました。
九州工業大学のkitscopeは安全を見てか1Mspsが上限ですが、今回はハードウェアの限界の16Mspsまで試して結構安定しています。
トリガレベルは原理的に調整可能ですが、ユーザーインターフェースを付けるのが面倒なのでA/D入力端子の所で約0.5V固定にしました。Delayed trigger量も固定で50usにしました。kitscopeはtrigger levelをTimer0のPWMで発生していますが、delayMicroseconds()が使えなくなるのでTimer2のPWMに変更しました。等価時間サンプリング時はTimer1をタイミング調整に使うので、Timer1で発生するCalibration pulseは使えません。
追加した時間軸は、1.56us, 3.1us, 7.8us, 15.6us, 31us, 78us, 156us/div の7通りです。
サンプリングしたデータをそのまま表示しているので中途半端な値ばかりです。スケーリングして1,2,5に合わせることも可能でしょうが、素の性能を見たかったのでこんなことになっています。
水平軸の目盛の縦線の位置をずらしてもいいかもしれません。
尚、radiopenchさんのオリジナルからピン割り当てを変更する必要がありました。
(追記 2021.07.25)回路図を書きました。(修正 2022.07.05)R4とR5の値が逆だったので回路図を修正。
回路図を見直してみると、FFT表示切替のSW5は無くても何とかなるんじゃないかと思うようになりました。SELECTボタンでAC/DC表示まで移動するようにしてUP/DOWNで切り替えられそうですね。そのうちに直しましょう。(追記ここまで)
(追記 2021.08.06)やはり部品が少ない方が作りやすいので、SW5は使わずにSELECTボタンでAC/DC表示まで移動するようにしてUPまたはDOWNでFFTに切り替えられるようにしました。AC/DCに移動した時は下線表示ではなく、白黒反転表示にしました。こちらの方がコードサイズが小さくなるので。"#define UNDERLINE_SCOPE"を定義すれば下線表示にも出来ます。回路図もSW5を削除しました。(修正 2022.07.05))R4とR5の値が逆だったので回路図を修正。
ソースコードは
OLEDoscilloScopeSh1106_V402.ino
(追記ここまで)
オリジナルでは入力に常に約1/5のアッテネーターが入るのが何となく気に入らない。
10:1プローブを使うために入力インピーダンスを1Mohmに近付けたい。
ということで次のような入力回路を検討中です。ADC入力のインピーダンスが無視できないと抵抗値の調整が必要かもしれない。
そもそもこんなハイインピーダンスの回路で思い通り動くのか心配。
5Vレンジと2VレンジはVREF=VCCに変える必要がある。それ以上は10:1プローブ前提になる。
垂直方向の処理も全部変えないといけないし面倒だな。
0.96インチや1.3インチのOLEDでは画面が小さいのでもっと大きくしてみたい。
ということで、TV画面に出してみましょう。
TVout Libraryを使います。
ライブラリはIDEのツール->ライブラリ管理からTVoutを検索すればインストールできます。
TVとの接続は黄色い端子のRCA入力を使います。
抵抗2本でRCA端子ケーブルに接続するだけなのでOLEDより簡単です。
しかし、同期信号やビデオ信号の発生にCPUが大忙しになるうえに頻繁にインタラプト処理が入るので、
オシロの波形取り込み中はインタラプトを禁止する必要があり、画面が乱れます。
そのため、一回表示したら500msだけ表示が安定するのを待つようにしました。
同期が回復するのが遅いTVでは待ち時間を長くした方が良いかもしれません。
TV信号の出力にD9,D7,D11を使い。スイッチ入力と被るので入力検出のインタラプト設定を停止しました。
起動時のEEPROM読み出し部分で設定を変更すれば使えます。
タイマー・カウンタを占有するので、校正信号の発生はできません。
analogWrite(10,128)を使えば488Hz、tone(10,1000)を使えば1kHzが出せるはずですが。
ソースコードは
TVoscilloScopeSV4066_V100.ino
タッチパネル付きの320x240の2.4インチTFT液晶シールドに表示できるようにしました。 この液晶シールドはSDカードインターフェースを残しておくとA5とTXDとRXDしか空きがありません。A5をアナログ入力にするとして、残るTXDとRXDはUSBからのプログラムのダウンロード用に内部で接続されているのでなるべく使いたくない。RXDはAC/DC切り替えスイッチに接続しても良いが、プログラム更新時はスイッチがオープン側(DC側)になっていることを確認しなければならない。とりあえずA5だけを使って動作確認しています。
画面をほぼフルに波形に使いたかったので、横10目盛、縦8目盛にすると30dot/目盛で300x240で水平方向に20ドット余ります。元の設計は25dot/目盛だったので横軸すなわち時間軸の取り込み時間を調整し直しました。縦軸はまだ未調整です。左側10ドット幅に縦軸の電圧を縦書きに、右側には画面外アイコンの説明を縦書きに表示するようにしました。入手した液晶シールドは表示画面外にアイコンがあって、そこまでタッチセンサの検出範囲が広がっています。このアイコンの位置をタッチすることで操作できるようにしました。旧型スマホ用でしょうか、今は入手し難いかもしれません。
OLEDとは違って、表示用ライブラリがArduino側にフレームバッファを持たない方式なので描画したものがすぐ画面に反映されます。そのため、画面クリアしている様子が見えてしまい、画面がちらつきます。それを避けるために波形を描画する時は前回に線を引いた始点と終点を覚えておいて黒い線で消してから新しい始点と終点に直線を引くようにしています。なお、古い線を消した所がグリッド線の所ならばグリッド線を復元します。こんなややこしいことをしているためか時々線が途切れることがあります。 後で紹介するオシロスコープも同じ様なことをしています。
波形の取り込みのためのADCの基準電圧は1.1Vですが、タッチセンサの電圧読み取りは5V基準になっているので、基準電圧を切り替えます。切り替え時には、空読みと時間待ちをする必要があります。
使ったLCDシールドが普通にライブラリを使うと左右反転するとか赤と青が逆とか何か変なので参考までにしかならないとは思いますが、ソースコードは
LCDShieldOscilloScopeV100.ino
ESP32のDACを使ったFunction Generatorで発生したsin(x)/xもどきを観測した様子はこんな感じです。
これを4.8kHzレンジのFFT表示にするとこんな感じです。300Hzの5倍高調波まで出ていることが分かります。
電圧レンジをタップすると色がCyanになり、"up"と"down"で変更できます。時間軸レンジをタップすると色がCyanになり、"up"と"down"で変更できます。トリガエッジをタップすると、上下の切り替えが出来ます。DC表示部分をタップするとFFTモードに切り替わります。"info"ボタンをタップすると文字の大きさの大小や非表示が切り替わります。波形表示エリアをタップするとHoldのon/offをします。 "select"と"home"は未使用です。
Arduino UNO互換機でCPUにQFPパッケージを使ったものの中にはA6とA7のスルーホール付きのものがあるので、それを使ってA6をA/D入力に、A7をAC/DC切り替え入力にすれば、A5をレンジ切り替えに使えるかもしれません。さらに、Arduino NanoやPro Miniでシールド基板を使ってUNOもどきを作り、SDカード端子を配線しなければD10-D13が使えるのでレンジ切り替えを全部使えるようになるかもしれません。
(追記 2021.07.27)こちらは等価時間サンプリングを実装するのを断念しました。理由はTFT液晶シールドにD6ピンを使われているのでトリガ電圧を入力できないためです。代わりに1.1Vの内部基準電圧を使うことはできるのですが、A/Dの入力最大電圧になってしまうので使い物になりません。A/Dの基準電圧を5Vにすれば何とか使えるのですが、実時間サンプリングと等価時間サンプリングで基準電圧が違うというのも変なので、別タイプのTFT液晶シールドを使ったオシロスコープ ArduinoとLCDタッチシールドで2CHオシロスコープ の方でやりました。 (追記ここまで)
TFT液晶シールドを使ったオシロスコープは、
大阪教育大学の光永さんの
Arduino でオシロスコープ
を基にしてロシアの方(?)がタッチスクリーンで操作できるようにしたもの
Arduino uno Oscilloscope for touch 2,4" TFT display
があるのでそちらも参考になります。
(追記 2021.08.25)
また、元々は128x64 LCDを使ったものなので、それを基に128x64 OLEDに表示できるようにし、多機能化してみました。等価時間サンプリングはもとよりパルスジェネレータやファンクションジェネレータや周波数カウンタも使えるようになりました。
ArduinoとOLEDで2CHオシロスコープ・Pulse generator・Function Generator・周波数カウンタ