Saturday, June 6, 2015

Arduino Oscilloscope

Recently I found at a tutorial that explained how to create a simple oscilloscope with Arduino: Girino. I decided to build it and learn all I could in the process. This post contains a few learned lessons that will hopefully be useful to other Girino builders. First, these are the specs of the oscilloscope I built:
  • Board: Arduino Duemilanova (ATmega168)
  • Input voltage range: -2,5..2,5V (0..5V without level shifter)
  • Resolution: 8bit/sample
  • Maximum sampling freq: 153.8 Ksamples/s
  • Samples/trigger: 512 samples
  • Pinout
    • pin 3 (PWM): used to generate a PWM signal that gets filtered and serves as the threshold for the trigger to work.
    • pin 7 (V- of analog comparator): connected to the threshold signal (the PWM signal after the filter)
    • pin 6 (V+ of analog comparator): connected to the input signal after offset level and buffering. When V+ is greater than V- it generates an interrupt.
    • pin A0 (analog input 0): also connected to the input signal.
The amount of samples per trigger can be improved by using an Arduino UNO (ATmega328) which has double SRAM size (2KB) allowing you for 1280 samples/trigger.

The sampling frequency is calculated from the equation above. In my case, the clock's frequency was 16Mhz although it can be upgraded to 20Mhz. The division factor (prescaler in the code) values go from 2 to 128 (in powers of 2). And the amount of cycles it takes for the Arduino's analog-to-digital converter to acquire one sample is 13 cycles. The default value for division factor is 128, which results in a sampling frequency of 9.6 KSamples/s.

Before I started building Girino, I decided to simulate the amplification and threshold circuits with LTSpice for which I already organized a workshop in the past. You can find the corresponding simulation files here. For the simulation, I added some clamping diodes to protect the input of the operational amplifiers (opamp). I also added an extra opamp to the level shifter in order to decrease its output impedance.

Next, I decided to use a universal PCB board for creating the Arduino shield. For the design of the universal PCB board, I used a program called PASS which is available in Japanese. I used a very convenient universal PCB board from aitendo that has the perfect size and configuration for building Arduino shields. For that reason, I had to create my own board's drawing for PASS. You can find all the PASS design files here. Looking backwards, PASS's usability was rather bad and I wasted quite a lot of time re-drawing the same lines over and over. Next time, I will create my own PCB boards with Kicad. Note: it seems that another person already created his own PCB for a Girino-based oscilloscope.

After designing the board layout with PASS, I checked that all components actually fitted in. For that, I used a piece of styrofoam to insert the leads of each component. Notice that I simplified the original Girino's circuit by hardwiring the jumpers to what I judged to be the best solution.

As I explain in my notes, a universal PCB board is a matrix of holes and pads. The main 4 methods to join pads are solder bridges; jumper wire; naked wire; and using the leads of the components.

Once you finish wiring, it's a wise thing to double check with the help of a digital multimeter that connections are as you expected and there are no shorts.

And this is the result. I got those BNC connectors from aitendo. Unfortunately, it turned out that one of them was broken. It took me some time with the multimeter to find out.

Let's focus now on the software. The diagram above shows briefly the behaviour of the software that goes into the Arduino board. You can download the software here. It is the same software as the one released by the author, but with a few patches added (check the git log). A detailed explanation of the software is included in my notes. If you use an ATmega328, change the buffer size to 1280 bytes. The arduino software contains an interface that can be accessed through the serial port. For testing that the software and hardware are working correctly, open the Arduino serial monitor and introduce commands such as (see Girino.ino):
  • d: displays the oscilloscope parameters (baudrate, threshold, trigger event..)
  • p: change the prescaler settings (eg: p8 for a division factor of 8)
  • t: change the threshold settings

Finally, for the host software (frontend) I selected Girinoscope. I had to modify the buffer to 512 bytes for my board (leave it untouched if you have an ATMega328), check the patched software here. Building and running it just requires two instructions:

$ ant build
$ ant run

Conclusions: while building the Girino oscilloscope I learned about protection circuitry; reviewed circuit simulation with LTSpice; learned how to use PASS for creating the layout of an universal PCB board and how to wire it. Finally, I learned a lot about the detailed settings of an Arduino's program: interrupts, fast PWM, analog comparator or ADC tuning registers to name a few.


yalect said...

thank you for your project
what is the maximum frequency can's your oscilloscope work with?

Sangorrin said...


Actually you should say thanks to Girino's creator, not me.
As it says in the post, it can sample at 153.8 Ksamples/s.
That allows for a maximum BANDWIDTH of 153.8/2 KHz.
That means you can capture signals in the range 0..76.9KHz, or
if you use an the appropriate bandpass filter you can capture
signals between 1MHz and 1.0769MHz for example.