New Project: USB Oscilloscope

I started a project to build a USB-oscilloscope to learn more about (analog) electronics. The project will be as OpenSource as possible. Unfortunately some tools I use to build the project are only available as closed source (more of this below), but all the stuff I create will be fully open source.

The project is currently in a very early state so don't expect too much. It is still far away from a “real” oscilloscope. The whole analog frontend is missing, there is no triggering and I can't tell you how accurate the measurements are (probably not at all). What it currently does is displaying a waveform of a measured voltage on the computer. The input can be between 0V and 3.3V. The sampling rate is around 20k samples per second.

On the left you can see a screenshot from the GUI Application that displays a measured waveform. The values on the time axis do not correspond to any real values in seconds (they just count the samples). In the following I will describe what I did so far. For the details have a look at the source code and schematics provided below.


I don't want to go in a detailed requirement analysis here. I want to spend my time with tinkering around and not writing down requirements (you could call it an agile methodology). Still I have some initial requirements in the head it should comply. These are (roughly):

  • The system measures multiple consecutive voltage levels.
  • The system displays the measured voltages to the user in a diagram (voltage over time).
  • The system permits the user to control its operation over a standard PC.
  • The system displays the diagram on the PC display to the user.

Most non-functional requirements (like accuracy, sample rate etc.) are left open intentionally. I just started with the parts I had lying around and will replace them in the design when it no longer has the performance for what I want to do.


A device which performs the acquisition is connected over USB to a PC. Software on the PC used to display and control the acquisition device over the USB connection.

The capturing device consists of the following parts:

  • An analog frontend (attenuation and then amplifying the incoming signal)
  • An Analog-to-Digital converter (ADC)
  • A microcontroller to perform the measurements
  • An USB-Controller

The hardware mainly consists of a PIC24 which I had lying around (namely a PIC24FJ64GB002). It contains the necessary components for a first version of my USB-oscilloscope, namely an analog to digital converter as well as a USB interface.

The PC Software consists of the following parts:

  • A base protocol class for the communication with the aqcuisition device
  • A GUI-application displaying the results
  • A command line tool permitting to send single commands to the device

Currently the tools have a hard coded serial device, if you want to use these tools you have to change the line opening the serial interface.


The choice of the PIC24 defined the development environment for the firmware. It is written in the MPLAB.X IDE from microchip. As a compiler I use the XC16 which is based on gcc. Unfortunately not all of the microchip software is open source. For programming I use a PICKit3.

I currently do all the development on a Fedora Linux running in a virtual machine on a Windows 8.1 Laptop (using virtualbox). I had some problems with an older version of MPLAB.X on windows and the connection with the PICKit. Running it in the virtual machine solved this problem.

The software on the PC will be developed in python, this should permit maximal portability. The user interface is created with PyQt. The communication with the PIC24 is handled with the pyserial library.

The schematics (and maybe later the PCB layout) are created with KiCad. KiCad has become quite a mature EDA Suite which fits my needs quite nicely. As not all parts I use were available in the library, I had to create them myself. They are also provided with the source.

The prototype is built on a standard breadboard. This will certainly limit the possible accuracy of the oscilloscope and will be replaced in a later version with a PCB.

Last but not least, I use many tools from my lab. This includes a function generator, a digital storage oscilloscope, a soldering station, a multimeter and some small parts.


The PIC is mounted on a standard breadboard. Every pair of power supply pins, such as VDD, VSS, AVDD and AVSS are connected to decoupling capacitors (100nF and two 1uF on the breadboard power rails). The layout of the breadboard limits how close the capacitors can be put to the corresponding pins, this certainly has an influence on the ripple on of the power supplies. The internal voltage regulator is activated (DISVREG tied to ground). I did not have any 10uF ceramic or tantalum as required by the datasheet. I took an electrolytic capacitor and measured it's ESR with my ESR meter and from 1kHz on it was below the required 5 Ohm. The circuit seems to work in this configuration. I will order some capacitors next time I order some parts.

The PIC is running from it's internal oscillator which runs at 8MHz. This is run through a PLL to create the 48MHz for the USB controller and 32MHz for the CPU. The accuracy of 0.25% of the internal oscillator will have an impact on the time resolution of the sampling.


The variant of the PIC24 microcontroller I'm using has USB support already built in. It does not require much effort to create a working USB connection. The USB connection in my project is based on an example project from the microchip mla. It creates a CDC (communication) device which has a default driver in many operating systems.

The physical connection to the PIC24 is done according to the datasheet. For the time being I used the self-power only, powering the PIC from a lab power supply. For connecting the device to the PC I cut off the connector from a regular USB cable, soldered a pin strip to the cables and fixated with some hot glue.

First I implemented an ascii based protocol which sent every measured value separately. This was extremely slow (around 3.5 seconds for 100 values). I then changed the protocol to binary and sent all data in chunks of 255 bytes. This dramatically increased the transfer speed (500 values in 7ms). The protocol currently offers two commands, one can either request one single value or a set of values (the length is determined in te firmware of the PIC and can not be parametrized). This is sufficient for displaying first waveforms and testing.

Analog to Digital conversion

To convert the analog input signal to digital values, I used the analog to digital converter of the PIC. Currently I run the conversions from a loop until the required amount of data has been collected. After each conversion the data is written to a memory location from where it will be sent to the PC later on.

From the plot of a 1kHz signal, I estimated the sampling rate to be around 20ksps. It should be possible to increase this to a much higher value as the datasheet claims 500ksps. I did not tweak any values in the conversion process, I think a lot can be won there.

Conclusion and Next Steps

So far I can measure waveforms up to a frequency of around 10kHz (due to the sampling rate of 20ksps, see Nyquist sampling theorem for details). The lack of a trigger system is an essential part missing in an oscilloscope. As I haven't performed any real measurements, I don't know the accuracy of my measurements.

In a next step I will therefore implement the trigger system and do some measurements on the accuracy of the measurement. I intent to document my next steps on this blog so stay tuned.

The project is still in a very early state. With the material provided (source/schematics) it should be possible to build it up for yourself but it still requires quite some knowledge and some tinkering.


You can download the source here: oscilloscope_2014-07-16.tgz

Enter your comment. Wiki syntax is allowed: