Project showcase
YetAnother USB Oscilloscope

YetAnother USB Oscilloscope © GPL3+

A USB based oscilloscope that squeezes everything out of the Arduino MKR / Zero ADC. It features Isochronous WinUSB transfer and OpenGL.

  • 6 respects

Components and supplies

Abx00003 iso both
Arduino Zero & Genuino Zero
or any other SAMD21G18 board, I used Arduino MKR 1010 Wifi

Apps and online services

Ide web
Arduino IDE
Alternatively you may use Atmel Studio (in which I originally programmed this)
Microsoft Visual Studio 2019

About this project

Most of the Arduino Zero/MKR-based oscilloscopes are either:

  • using the computer's sound card
  • using the USB port but are limited by the Bulk USB transfer protocol, ie. 64bytes per ms following a 27 byte per ms transfer request (USB 2.0)

The Arduino Zero/MKR features a 350kSps 12-bit ADC. Which are awesome specs thinking about it. However, unleashing this capability is another story. The SAMD21G18 hosted in the Arduino Zero/MKR provides a USB2.0 full speed.

Consequently, accessing the 350kSps ADC, requires the oscilloscope solution to capture these samples, transfer them over the USB2.0 line and project them on the screen at a 60Hz rate, that is within a 16ms time frame. Moreover, to allow accurate timing of the samples, the ADC readings need to be accompagnied by a time measurement.

This project goes on the quest to crack this challenge!

The below image lays out the main features of the application:

The challenge in numbers:

60hz or 16ms per frame vs ADC: 350kSps

=> 5600 samples per 16ms,

1 sample = overhead bytes (integrity at least) + 12/16/8 bit sample + 12/16/8 bit timestamp = 3 to 6 bytes

=> 5600 x 3 to 6 bytes per 16ms = 16 800 to 33 600 bytes per 16ms

USB2.0 Full Speed delivers:

  • in USB Bulk transfer: 64bytes per ms ~ 1024bytes per 16ms --> To little!!
  • in USB Isochronous transfer: 1023bytes per ms ~ 16 368bytes per 16ms --> OK

The above (wrongly) assumes USB transfer can occur in parallel with the ADC capturing.

=> implement multi-threading accross the line were possible, because it will be necessary to get as close as possible to our goal.

openGL requires:

  • transformation of ADC readings and timestamp data into {-1;1} data. We want to do this on the CPU (judged fastest) in another thread.
  • building of screen. Done on GPU by OpenGL

The above example (assuming readings are accurate), show:

We are sampling at 270kSps (when we are sampling, remember USB transfer on Arduino board will take processor time as well).

The time to collect and send the 1023byte data accross the USB line takes around 6,7ms: 1023 bytes data here equals: 1023 x 8 / (12 + 12 + 7) = 264 samples repeated 4 times to attain 1024 samples (theoretically it would only take 4 ms).

This data is transformed, build and drawn in.15ms+.35ms+1.6ms ~2.1ms.

The total frame rate openGL is measuring 9.2ms (letting the program run as fast as possible). Hence, we could try to increase the sample reading to 2048, without sacrficing too much screen refresh rate.

As we wrote above, we need to implement multiple threads to allow parallel processing as much as possible.

The application features 3 threads:

1) C# graphical user interface

(split from other threads to have the relatively slow UI interfere at least as possible with the main task, ie. capture USB and project on screen)

2) C++ DLL OpenGL. A native C DLL to wrap the OpenGL window. The benefit is easy portability of the code towards other platform / UI. OpenGL is open source and one of the fastest out there.

3) C++ DLL USB. A native C DLL to wrap the winUSB driver. Reason for the choice was that the winUSB.sys USB driver is on every Windows computer and it supports isochronous data transfer. Isochronous data transfer is used for streaming data. It leaves behind data integrity checks for speed. In this way you can tranfer 1023bytes per ms.

By implementing a muli-threading scheme, the screen can build while the other thread is capturing the new data from the USB line, while the user is hovering its mouse over the user interface.

Installing the application:

The application is not that user friendly to be used:

1) The Arduino board (or any other ADC / USB capturing device) needs to have Isochronous USB datatransfer implemented. The ArduinoCore does not support this by default. In the sketch provided in this project, I provide the Arduino code to extend the ArduinoCore with an Isochronous USB interface (without losing the possibility to still use the Serial.print capability). The extension can be used in the regular Arduino IDE (so no need to change the ArduinoCore itself).

2) The WinUSB.inf driver file needs to be installed by installing it running Windows in test mode. This because of a lack of driver certificate.

3) Currently I have left the YetAnotherUSB Oscilloscope software uncompiled on the Github. This to invite users to go into the code and adjust, compile and build on their own.

Future improvements:

The YetAnotherUSB Oscilloscope software is developed on VS 2019 with latest.NET framework and tested on 64-bit. In other words, the application is relatively untested and underdeveloped to run on multiple platforms (32 bit or linux).

Also the multi-threading has not been made super robust. (Possible infinite loops are possible in extreme cases, eg. unplugging the USB whilest reading, etc.)

Some features are still missing, ie. FFT analysis, triggers and memorizing capability.

I hope this can be inspiring for you and might you can use / borrow the code for your own (further) development.

Keep making!


Win YetAnotherUSBOscilloscope software (uncompiled)
C# application for the User Interface C++ DLL for OpenGL oscilloscope window C++ DLL for WinUSB connection Inf file for the WinUSB driver (you need to install in Test mode as I could not inlcude a certificate)
Arduino ADC with Isochronous USB
The code to load to the Arduino Zero / MKR. It configures the Arduino A1 pin as ADC input and implements the Isochronous USB data access


ADC scheme
The A1 pin is set to capture the ADC data
2020 05 24 11 55 23 window   kopie mihu9bqwsc


Similar projects you might like

Let's Build an SN76489 USB MIDI Synth With Arduino Nano

Project tutorial by tyrkelko

  • 1 comment
  • 6 respects

Arduino Oscilloscope

Project showcase by wayri

  • 27 respects

Making Arduino-Based RC Transmitter of USB Flight Simulator

Project showcase by tsar_

  • 9 respects

How to Make a Mini Oscilloscope at Home Using Arduino Nano

Project tutorial by CiferTech

  • 33 respects

Control Arduino Using Smartphone via USB with Blynk App

Project tutorial by Smart Technology

  • 1 comment
  • 4 respects
Add projectSign up / Login