Raspberry Pi Pico Wと0.96-inch 80x160 LCDで2CH WEBオシロスコープ・Pulse generator・Function Generator・周波数カウンタ

更新日 2026.10.20 登録日 2024.09.13
* *

大阪教育大学の光永さんの Arduino でオシロスコープ は古い128x64のLCDディスプレイ用に作られたものですが、それを基に128x64の1.3インチOLEDで使えるように変更して Raspberry Pi Pico WとOLEDで2CH WEBオシロスコープ・Pulse generator・Function Generator・周波数カウンタ を作ったので、それを基に0.96-inch 80x160 LCDで使えるようにしてみました。このディスプレイはAmazonだと1000円くらいしますが、AliExpressだと送料込みで300円くらいで買えるので気軽に使えます。OLED版よりも少し広い範囲を表示できますが、解像度が高くなった分文字表示が小さくなりました。その代わりカラーで表示出来るので、2チャンネルの区別が分かりやすくなりました。。サンプル数は160ポイントです。

画面レイアウトとGUI、波形描画方法はOLED版を元にしています。画面全体と同じ大きさのスプライトを使うことで描画方法はOLED版とほぼ同じになっています。

周波数カウンタは1kHz単位のものを仮実装です。また、等価時間サンプリングはRaspberry Pi Picoで実装する方法が分からないのであきらめました。

開発環境は Arduino IDE 2.3.10 + Raspberry Pi Pico/RP2040 by Earle F. Philhower, III version 6.3.0です。
この環境ではAnalogRead()が使えるのですがオーバーヘッドが多過ぎるようで遅いので、adc_read()を使うようにしました。また、単発のadc_read()では速度に限界があるので高速サンプリング時にはDMAを使って単一チャンネルで500kspsまで出来るようにしました。2チャンネルなら250kspsができるようにしました。

(2026.10.14 追記) Scoppyで2Mspsまで出来るという記事 Quadrupling the sample rate of an RP2040 oscilloscope を見たので、v1.03で2Mspsと1Mspsが出来るようにしました。ただし、ADCクロックを4倍までオーバークロックすることになるので若干精度が落ちる恐れがあります。

時間軸拡大機能があります。2us/divは500kspsの10倍拡大、4us/divは5倍拡大になります。拡大にはsin(x)/xによる補間をしています。 (2026.10.14 update)

Raspberry Pi PicoにはEEPROMが無いのですが、EEPROMのシミュレーションを利用して設定を保存するようにしました。

RP2040-Zeroでも使えるようにしました。ピン割り当てが若干変わります。周波数カウンタ入力のGP22は裏側の小さいパッドになってしまうので実質的に使うのは困難です。WEB機能は搭載されていませんがコンパクトに組むことができます。Raspberry Pi PicoではSPI1を使っていますが、RP2040-Zeroでは基板端のGP9-GP13を使わなくて済むようにSPI0を使うように変更しました。
*

ソースコード

最新版はGitHubに置いてあります
https://github.com/siliconvalley4066/RaspberryPiPicoWOLEDOscilloscope/tree/IPS80x160

RPPicoIPSOscillo106.zip 2026.10.20 update
RPPicoIPSOscillo102.zip 2026.07.14 update

CPU速度は当初125MHzを想定していました。 Raspberry Pi Pico/RP2040 by Earle F. Philhower, IIIの環境ではdefaultで133MHzになっていてDDSとPWMの周波数がずれる問題が発生したので、システムクロック周波数を取得して自動的に対応するようにしました。ただし、PWMの周波数可変範囲が変動します。

LCDのドライバはTFT_eSPIです。インストールされていない場合はライブラリマネージャーから検索してインストールしてください。Raspberry Pi PicoとST7735を使用するためにカスタマイズする必要があります。

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

WebSocketsのライブラリはライブラリマネージャーから検索できるものではなく、以下を使いました。
Links2004/arduinoWebSockets
WebSockets by Markus Sattler version 2.7.2 を使うようにしました。(2026.10.14 update)

Pi Pico用にも変更無しでコンパイル出来るように自動的にpre-defineを見てWEB機能を外すようにしてあります。

Arduino Mbed OS RP2040 Boards 3.1.1 でもコンパイルできますが、CPUがPi PicoのみでWEB表示と設定保存は出来ません。

RP2040-Zeroでビルドする場合はArduino IDEのボード"Waveshare RP2040 Zero"を選択します。

回路図

Raspberry Pi PicoのADCの入力インピーダンスが低いようなので、rail-to-railのCMOSオペアンプMCP6022のボルテージフォロワを追加して10:1プローブを使えるようにしました。入力保護のために100kohmを追加してゲインが0.9倍になっていますが、ソフトウェアの対応はまだです。動作確認するだけなら入力回路は省略して直接A/D入力に接続出来ます。 (2026.10.14 update)
*

RP2040-Zeroの回路図:
*

操作方法

先ず起動する前にArduino IDEのシリアルモニターを開いておきます。プログラムが開始してWiFiアクセスポイントに接続成功したらIPアドレスを取得してシリアルモニタに表示します。そのIPアドレスをWebブラウザのアドレスバーに入力すればWEBオシロに接続できるはずです。
例えばシリアルモニタに、
WiFi Connected. IP = 192.168.1.128
と表示されたら、Webブラウザのアドレスバーに192.168.1.128と入力します。

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

Page 1

  • 一番上がCH1の電圧レンジ、2番目がCH2の電圧レンジです。Rightボタンを押すと値が上がり、Leftボタンを押すと下がります。
  • 3番目が時間軸レンジです。Rightボタンを押すと早くなり、Leftボタンを押すと遅くなります。
  • 4番目はReal Time SamplingかDMA使用かの表示です。この位置でRightボタンかLeftボタンを押すと時間軸拡大のx1,x2,x5,x10 が選択出来ます。拡大にはsin(x)/xによる補間をしています。(2026.07.14 update)
  • 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の設定項目。
  • 1番目のCH1と表示されている位置ではRightボタンとLeftボタンで 時間軸拡大x2,x5,x10の時の拡大位置の変更が出来ます。拡大位置は画面下部の横線で表示します。(2026.07.14 update)
  • 2番目がCH1の、6番目がCH2の非表示や反転表示の切り替えです。Leftボタンで表示・非表示、Rightボタンで正転・反転の切り替えが出来ます。
  • 3番目がCH1の電圧レンジ、7番目がCH2の電圧レンジです。
  • 4番目はCH1の、8番目がCH2の波形表示上下位置です。Rightボタンを押すと上に上がり、Leftボタンを押すと下がります。ボタンを長押しすると連続変化します。左下同時押しすると標準の位置最下端にリセットします。
  • 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"はPWM DDS Function GeneratorのOn/Offです。Rightボタンを押すとOnになり、Leftボタンを押すとOffになります。
  • 4番目はPWM DDS Function Generatorの波形切り替えです。RightボタンとLeftボタンでは逆方向に切り替わります。
  • 5番目"FREQ"はPWM DDS Function Generatorの周波数設定です。Rightボタンを押すと増加し、Leftボタンを押すと減少します。ボタンを長押しすると連続変化し加速します。
  • 6番目"MSR1/MSR2"はどちらのチャンネルの周波数測定と電圧測定をするかの選択です。Leftボタンを押すとMSR1でCH1に、Rightボタンを押すとMSR2でCH2になります。
  • 7番目"FCNT"は周波数カウンタのOn/Offです。Rightボタンを押すとOnになり、Leftボタンを押すとOffになります。8行目に計測した周波数を表示します。他のページでは表示しません。
  • ADCのオーバークロックについて

    (2026.10.14 追記) 標準の使用条件ではADCは48MHzのUSBクロックで96サイクルを使って1サンプルを取得するので最高500kspsになります。このADCクロックを96MHzにすれば1Msps、192MHzにすれば2Mspsが出来るようになります。ただし仕様範囲外なので精度が落ちる恐れがあります。でも実際に4倍の192MHzにしてもさほど大きな劣化は無く動作しています。電圧レベルで2%程度の劣化のようです。
    これを実現するためには、システムクロックを必要な周波数に変更してから、ADCクロックをUSBクロックからシステムクロックに切り替えることになります。

  • 1Msps (10us/div) ではシステムクロックを 96MHz に下げ
  • 2Msps (5us/div) ではシステムクロックを 192MHz にオーバークロックします
  • システムクロックを変更することによってPulse GeneratorやPWM DDS Function Generatorにも影響が出ます。 Pulse Generatorは出力周波数が変わってしまうので周波数表示をそれに合わせて変更するようにしています。周波数の可変範囲は変わってしまいます。 PWM DDS Function Generatorはクロック切り替え時に設定を変更して同じ周波数を出せるようにしましたが、設定変更時に出力波形が乱れる恐れがあります。
    画面表示にも影響が出る可能性はありますが現状では大丈夫そうです。 WiFiに影響があるかどうかは未確認です。

    OPアンプにMCP6002を使うと5μs/divレンジで矩形波の立ち上がり立下りにスルーレート0.6V/μsの限界による傾きが見えるようになります。よりスルーレートの高いMCP6022等のOPアンプを使うのが良さそうです。

    Pulse Generatorについて

    PWMで発生できるパルスをほぼ全て出せるようにしました。125MHzを1/2から1/65536まで設定できます。分周比は1/1から1/255まで全て使います。発生できる周波数は7.48Hzから62.5MHzまでになります。周波数自体を設定するのではなく、発生できる上または下の周波数へ設定を変更して、その設定で発生される周波数を計算して表示します。周波数の高い方は62.5MHz, 41.67MHz, 31.25MHz, 25MHz, 20.83MHzのように飛び飛びの値になる。Duty cycleも実現可能な値が限られていて50%も不可能な場合がある。周波数の低い側の分解能は1/65536になり細かく設定できます。インタラプトは発生しません。

    PWM DDS Function Generatorについて

    Lab3 - Laboratory for Experimental Computer Science を流用させていただきました。波形データはその他色々な所から集めました。周波数の設定と波形の選択だけがオリジナルです。周波数の分解能は取り敢えず0.01Hzにしました。インタラプト処理が入るので速いサンプリング時にオシロスコープの波形が間延びするようなら明示的にOFFにした方が良い。サンプリング周波数はATMEGA版の31kHzの約2倍の61kHzに上げてみました。メモリに余裕があるので用意した23波形すべてを使えます。
    リンク先が消えているようなので同じ内容を探してみました。 Arduino Sinewave Generator

    周波数カウンタについて

    APIに周波数を計測するfrequency_count_khz()が有ったので利用してみました。サンプリングした波形から算出して画面上部に表示している周波数とは別物です。GP22ピンに入力されたデジタル信号の周波数をカウントする機能です。2kHz以上の周波数を1kHzの分解能で計測出来ます。周波数の上限は分かりませんが内蔵のPulse Generatorで発生した62.5MHzが計測出来ました。試しに内部のシステムクロックを測定するように指定するとちゃんと125MHzが得られました。これ位の高周波になると配線による波形歪みに注意しないとまともに計測できない恐れがあります。

    Known Bugs

  • 原理的に周波数測定には画面上で2周期以上が必要。
  • トリガモードのOneがうまく機能しない。
  • トリガが掛からない状態でトリガモードをNormにすると、トリガ検出から抜け出せなくなり操作不能になる。トリガが掛かる入力を入れれば復帰する。
  • 2ch表示で信号源インピーダンスが大きい場合は相互に観測波形に影響が出る。
  • 2ch間でレベル差が大きい部分には相互干渉が発生することがある。
  • Pulse generatorはCPUクロックを分周していて1/2から整数分の1の周波数を発生する。周波数の高い方は62.5MHz, 41.67MHz, 31.25MHz, 25MHz, 20.83MHzのように飛び飛びの値になる。Duty cycleも実現可能な値が限られていて50%も不可能な場合がある。周波数の低い側の分解能は1/65536になる。
  • HOLD中の時間軸拡大は出来ません。(2026.07.14 update)
  • これ単体で2チャンネル入力にPulse generatorとFunction Generatorの出力を入れて波形観測して遊べます。
  • 改良可能性

  • 取り込みサンプル数を増やして表示位置を移動できるようにしてみたい。
  • 時間軸拡大表示。5倍、10倍にできますが位置は波形の先頭に固定です。2倍、5倍、10倍が選択出来て拡大位置も移動できるようになりました。(2026.07.14 update)
  • 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, 500us, 200us, 120us (83ksps),
    (DMA mode) 100us, 40us (250ksps), (1 channel) 20us (500ksps), 10us, 5us (2Msps)
    トリガモード Auto, Normal, Scan
    トリガ極性 rise/fall edge
    トリガソース CH1 or CH2
    トリガレベル調整 画面内位置を上下に調整
    外部トリガ No
    波形位置調整 上下に調整可能
    波形反転表示 Yes
    電圧測定表示 Max, Average, Min (AC入力でもDCレベルを表示)
    周波数&Duty測定 Yes
    電圧・周波数・Duty表示 表示・非表示切り替え
    文字表示 文字サイズ固定
    FFT Yes
    A/D変換分解能 12bits
    サンプル数 160samples/channel (8bits/channel) 12bit/sampleを電圧レンジに応じて0から79にスケーリングして表示
    表示解像度 LCD: 160x80 dots, 水平10dots/div 垂直10dots/div
    WEB: 800x400 dots, 水平50dots/div 垂直50dots/div
    等価時間サンプリング No
    設定状態EEPROM保存 Yes
    操作方法 5方向スイッチ (Left, Right, Down, Up)
    プリトリガー No
    ホールドオフ機能 No
    時間軸拡大表示 x2, x5, x10 sin(x)/x補間
    X-Y表示 No
    Pulse Generator 7.48Hz to 62.5MHz 約3.3Vpp方形波 Duty ratio可変
    Function Generator 8bit PWM DDS 0.01Hz to 9999.99Hz(実用は400Hzまで) 約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
    周波数カウンタ Yes 分解能1kHz 2kHzから125MHz程度まで
    PCへのデータ転送 No
    SDカードへの波形保存 No


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