Fast plotting of arduino data in python

For a long time I’ve been trying to plot serial data that comes from a USB device such as an arduino but I could never get to work as fast as I wanted. All of my previous attempts where based in matplotlib but this approach resulted to slow. I just couldn’t update the plot quick enough. By using pygame to take care of the plotting I can get a very responsive plot.

In this post I will show you how to plot the voltage measured from an analog input of the arduino and thus, make a poor man’s oscilloscope with python.

Sending data to the computer: arduino part

The arduino analog-to-digital converter has a 10 bit resolution which means we need at least two bytes to send each value. If we call our 10-bit variable a, then the bits of a are:

bits of a
a9 a8 a7 a6 a5 a4 a3 a2 a1 a0
most significat least significant

To send a through serial protocol we put a9-a5 in one byte and a4-a0 in another and we also pad the bytes with different values so we can distinguish the first from the second byte. If we call b and c the first and second bytes respectively, the bit structure they have is:

bits of b
1 1 1 a9 a8 a7 a6 a5
bits of c
0 1 1 a4 a3 a2 a1 a0

In this way, legitimate values of b are between 224 and 255 and for c they are between 96 and 127, and this way, when we receive a byte we can tell whether is the first or second.

The arduino code to do this is

PC software

On the side of the PC the client software runs two separate threads. One is in charge of continuously reading data from the serial port and the other one updates the plot. The software is made such that this two tasks can be carried out asynchronously.

Communications Thread

This thread reads the serial data using pySerial and joins the two bytes back together to get the original number.

Plotting Thread

The action happens in the pygame main loop:



The full code can be downloaded here. With this setup I was able to get a sampling rate of about 6900 samples per second. In my laptop I get a framerate of about 300 fps and in an old computer I got about 30fps.

Some more fancy oscilloscope features like triggering should be straightforward to implement after this.


The arduino code is based on the one from lxardoscope.