DIY Oscilloscope with Raspberry Pi
By: Victor Corona
Tags: Science, Raspberry Pi, Engineering, Electronics, Oscilloscope

I chose to create an oscilloscope that can be ran on the raspberry pi. The idea is to create an analog wave using the pi as well as collect data from an analog to digital converter and plot that data in real time. The analog signal is to come from one of the GPIO pins on the pi, and the circuit tested will be a simple LED and resistor. The output voltage will be plotted in real time to show display the waveform. This project will be added to and developed more as long as I keep working on it and will update the code here https://github.com/VictorCorona/RPi-Oscilloscope.

The setup for this project is simple. I used software that is already installed on the raspberry pi setup for our 129L class. The hardware required for this will be listed here;

Analog to digital converter (Supplied at the beginning of quarter from adafruit) Breadboard Desired Test Circuit (Resistor and LED) Jumper Wired for GPIO pins

Before running the program, it is important to setup the wiring while the pi is off and unplugged. Note that I am referring to pin numbers instead of GPIO numbers in this section before making connections.

Raspberry Pi GPIO pin Diagram

I use pin 1 for 3.3V output and set this to the positive power rail of the breadboard. I then use pin 6 as the ground connection and connect it to the negative power rail on the breadboard. Pin number 3 (GPIO 2) is used as the data connection to the ADC. Pin 5 (GPIO 3) is used as the clock connection on the ADC. The last pin used is pin 32 (GPIO 12) as the analog signal source. The voltage reading is taken between the resistor and the LED and is used as A2 on the ADC. A3 on the ADC is connected to the ground power rail.

Connecting the simple LED circuit shows visible feedback if the circuit is connected properly; this is why I chose to use this design. The circuit is now set up and is ready to be used to collect data.

My Wiring Setup

I created a square wave function generator to be output from GPIO pin 12 using the RPi GPIO library that is pre-installed on the pi. This part initializes the pin to be used as a pulse width modulation output (PWM), and sets it to a frequency that is chosen by the user. The duty-cycle of the signal is set to 50 percent to allow enough time for the cycle to fully be read by the ADC.

The main function is set to only trigger the rest of the code if the voltage read by the ADC is greater than a trigger level set by the user. This trigger level is used in oscilloscopes to only show waveforms when they are detected and ignoring noise from the internal circuit. The trigger will ask you to re-enter the trigger value if after 3 seconds of acquiring voltage readings and the function does not detect anything. The trigger can be seen more easily with a continuous sine wave, but in the square wave used here it is shown by the beginning of the graph set at its peak voltage of the square wave.

The plot is then initialized through the class Scope. The y-limit on the graph is set to a max voltage of 5V, likewise the minimum voltage on the graph is set to -5V. The x-limit of the graph is set by maximum time to be shown on the graph. This maxtime is set by the frequency to show the best waveform.

The graph is then updated as the ADC collects more voltage samples and is plotted on the graph in real time. When you exit the graph it will restore the GPIO pins to their initial state so that there is no signal running through the circuit while the program is not running.

This method of sampling data works well for frequencies lower than 1KHz. Above that the graph starts to lag behind. I believe this has to do with the sampling rate of the ADC, since it is required to sample at at least twice the frequency of the signal and as the sampling frequency increases, the noise from the ADC also increases. After testing many different combinations of output and sample frequencies I determined it was best to leave the ADC to the sample rate of 3300 samples per second for the cleanest waveforms regardless of whatever noise was added to it.

The Circuit I used to Test

Using matplotlib animation also runs slow to plot the data and contributes to the noisy output of the waveform. I originally wanted to use the pygame library to plot the data points, but found out that the to plot data with it uses matplotlib anyway. I decided it would be faster to just use matplotlib and try to make my code run faster. This works out somewhat but the maximum frequency that I am able to get good results with is around 100Hz.

RC Circuit Test

This project will be updated often so make sure to check the github for updates and feel free to add your own code to better optimize the data collection.