Spark Logic

$10 O-Scope revisited

ahull Sat May 09, 2015 12:56 pm

Over the last few days I’ve been playing with Ray’s STM32 Oscilloscope idea.

Image

Some preliminary results are available here..

https://github.com/pingumacpenguin/STM3 … ontruction

My take on the Scope Sketch is here..

https://github.com/pingumacpenguin/STM32-O-Scope

Its a fun little project and well worth building just for the entertainment value. Currently bandwidth is a little limited, but with a little extra effort it would be possible to make a fully functional 2MHz Scope for next to nothing. Ideal for probing i2c, audio and other low speed signals.

EDIT: We managed to squeeze the maximum speed out of the ADC, read further through the thread for details. The github code includes all of the enhancements made of the course of this thread.

Replies

madias Sat May 09, 2015 1:18 pm

Interesting project!
I own a DSO nano (also STM32 powered) with benq firmware and the tools is really useful (I use it for audio data).
It would be interesting if there is a possibility to get 2 (or more) channels out of it (with half speed or so).

mrburnette Sat May 09, 2015 3:02 pm

Wow!

Your implementation and enhancements surely takes the idea into the usable category!

Thanks.

Ray

ahull Sat May 09, 2015 8:55 pm

madias wrote:Interesting project!
I own a DSO nano (also STM32 powered) with benq firmware and the tools is really useful (I use it for audio data).
It would be interesting if there is a possibility to get 2 (or more) channels out of it (with half speed or so).

ahull Sun May 10, 2015 1:32 pm

A quick change to the code (no DMA or other trickery involved) allows me to push the sampling loop down to 3us per conversion…

Code now reads…

const adc_dev *dev = PIN_MAP[analogInPin].adc_device;
int pinMapPB0 = PIN_MAP[analogInPin].adc_channel;
adc_set_sample_rate(dev, ADC_SMPR_13_5);

for (uint16_t j = 0; j <= maxSamples - 1 ; j++ )
{
dataPoints[j] = adc_read(dev, pinMapPB0);
}

ahull Sun May 10, 2015 2:29 pm

Furthermore…. :D … if we move the register setup outside of the loop. (See https://github.com/leaflabs/leaflabs-do … erview.rst for the secret sauce that give the clues as to how to do this).

const adc_dev *dev = PIN_MAP[analogInPin].adc_device;
int pinMapPB0 = PIN_MAP[analogInPin].adc_channel;
adc_set_sample_rate(dev, ADC_SMPR_13_5);
adc_reg_map *regs = dev->regs;
adc_set_reg_seqlen(dev, 1);
regs->SQR3 = pinMapPB0;

for (uint16_t j = 0; j <= maxSamples ; j++ )
{
regs->CR2 |= ADC_CR2_SWSTART;
while (!(regs->SR & ADC_SR_EOC))
;
dataPoints[j]=(regs->DR & ADC_DR_DATA);
}

ahull Sun May 10, 2015 7:43 pm

Dropping the sample time to 7.5 clock cycles gives us 427616 samples/sec and a bandwidth of 213,808 Hz but we start to see some ringing in the signal path, which can be trimmed out with a little additional capacitance in our probe.

ahull Sun May 10, 2015 7:54 pm

Dropping the sample time still further to 1.5 clock cycles still yields a usable result, with 6144 samples taking a mere 11792 microseconds.

Image

We see more artifacts on the signal, but it is still usable and with a sample now taking 1.919270833 microseconds, we are getting pretty close to the theoretical minimum ADC conversion time. This gives us 521,031.207598372 samples per second, for a bandwidth of 260,515.603799186 Hz (i.e. just over 260.5 kHz) which ‘aint bad.

The signal could be cleaned up slightly by using a proper scope probe and adjusting its trimmer. I’ll give that a shot tomorrow. The lack of a separate ADC ground plane and clean ADC Vref on these little boards is noticeable at this kind of frequency. Also the volts per division is out, not sure if that is due to attenuation due to the higher frequency or problems with my code.

If you want to learn a little bit about scope probes and high frequency signals take a look here..
https://www.dfad.com.au/links/THE%20SEC … 0OCt09.pdf

I’m happy with that. If I get a bit of spare time, I may look at using the ADC with DMA – but if anybody else wants to take a crack at beating 1.9 uS per conversion *with* DMA and an interrupt service routine, the gauntlet has been thrown. :D

The updated sketch is on github. https://github.com/pingumacpenguin/STM32-O-Scope

ahull Sun May 10, 2015 10:54 pm

One thing I may have failed to mention. The sketch can also spit out the data on the USB serial port, so you can analyze it further. Here is a sample plot using gnuplot http://www.gnuplot.info/ of the 6144 samples in one buffer taken with the latest sketch of a slightly noisy pwm signal.

Simply type s <enter> on the Serial Console and it fires back the data points.
Paste these into a csv file and feed it to gnuplot.

gnuplut> plot ‘serial.csv’

Image

We can zoom in…

gnuplot> plot [500:2000] ‘serial.csv’ with lines

Image

.. you get the idea…

mrburnette Mon May 11, 2015 2:25 am

I’m impressed.

My initial idea was to just provide a low-cost teaching aid, but the current implementation is well beyond that! Great work.

Ray

madias Mon May 11, 2015 9:13 pm

ahull: Too bad that I just no time for a new project have, but your O-Scope is high on the “must build” list!

mrburnette Mon May 11, 2015 10:07 pm

@ahull;
Very nice project! Obviously, this is not your first time out on the town ;)

Ray

ahull Mon May 11, 2015 11:28 pm

Obviously, this is not your first time out on the town @Ray you could be right… I suspect I’m another candidate for the memory belts. ( viewtopic.php?f=35&t=113#p827 ) :D

ahull Wed May 13, 2015 9:57 pm

STM32-O-Scope was in needed of a case upgrade as the re-purposed chocolate box was starting to fall apart. In keeping with the $10 theme, the box had to be inexpensive.

A quick visit to “Pounstretchers” to get the “food container as a project box” [http://chdk.setepontos.com/index.php?topic=10284.0] that a lot of one off projects wind up in provided something much more amusing. A £1.99 “squeaky pig dog toy”.. OK it doubled my project box budget, but I hope the results are worth it.

Image

Mr Pig is going to have a window in his side (after some minor surgery), and all of the gubbins below is going to wind up in his ample belly with just a USB lead to connect him to the laptop and eventually a couple of LiPo batteries will be added, since our porcine friend has plenty of spare girth to accommodate them.

Image
(Hot snot fest and big mess O’ wires)

As well as being an obvious reference to Mr Lears nonsense, the ring in the end of his nose will be the square wave test point. Initial build photos start here.. https://plus.google.com/u/0/photos?pid= … 4282217370

mrburnette Wed May 13, 2015 11:34 pm

What a great way to bring home the bacon!

Porkbelly politics has nothing on this techno porker.

Too funny. I needed a good laugh, this was perfect.

Ray

victor_pv Thu May 14, 2015 2:39 pm

Guys that is starting to look like a professional oscilloscope even with the $10 tag :D

Ahull I think you should look at adding DMA for the capture. You can set a timer to trigger each DMA transfer, so you can precisely set the capture frequency with the TIMER, trigger the transfer, then dump the data to the screen.

I am wasting most of my time with the bootloader the usb enumeration stuff, but if I get a minute I’ll try to see if I can test ADC DMA captures.
If that worked fine, all you would need would be 2 buttons or a touch screen to adjust the capture frequency

ahull Thu May 14, 2015 9:58 pm

@Victor, if you do get a chance to get something working for ADC – DMA transfer using one of the timers that would be perfect. It would give us full speed on the ADC too I suspect. Currently I’m only polling the ADC, but if we can use DMA and the timer to to precise ADC conversions we will get more accurate timings (although even polling gives some pretty accurate results so far as I can tell).

I must admit I’m quite enjoying messing about with this, what actually sparked my interest in the STM32F103 was the built in RTC, but that has taken a back seat for the time being, and this little project has taken over.

One thing I did discover is that the PWM frequency is actually not 1100 Hz as stated by Leaflabs, but actually 550 Hz – on the PWM pin I am using, seems the pre-scaler value they used for timer 3 is out (I’m using PB1 for my test output pin).

It was pretty obvious something was wrong, when I looked at it on the STM32-O-Scope screen, and when I compared the results on my office scope it showed the STM32-O-Scope was measuring the period correctly. I though I had a bug in my code. I then checked and there is some info about this on the leaflabs forum. I’m going to mess with the timers next if I get a chance, and see if I can set up some control over the output frequency using serial port commands.

I’ve pushed my latest code to git if anybody else wants to play. :D


I am wasting most of my time with the bootloader the usb enumeration stuff, but if I get a minute I’ll try to see if I can test ADC DMA captures.
If that worked fine, all you would need would be 2 buttons or a touch screen to adjust the capture frequency

I have a bunch of serial commands configured, including one to increase/decrease the timebase, so I can just hook in to those.
I have a touch screen, but I haven’t started to play with the touch library yet.

victor_pv Fri May 15, 2015 4:52 pm

From what I remember from an STM application note I read a while back, we can configure ADC1 and ADC2 to take samples in tandem, resulting in 2M samples/s which is a pretty respectable speed for such a device. I’see if I can find how they did it and adapt it to the maple. I would think it should not take much effort as the DMA functions from leaflabs are working as expected so far. we will see about their timer’s code after what you noticed with the PWM…

ahull Fri May 15, 2015 5:44 pm

I believe you are correct.. http://www.st.com/web/en/resource/techn … 258017.pdf <<Page 10

2.2.1 Description

The dual fast interleaved ADC mode is intended for the conversion of one channel. ADC1
and ADC2 convert the selected channel alternately with a period of 7 ADC clock cycles.
This means that the channel is converted every 7 clock cycles. Each ADC converts the
channel every 14 ADC clock cycles. With a 14 MHz ADC clock, it is thus possible to reach
2 Msamples per second: 14 MHz/7 = 2 MHz (sampling frequency). The conversion can be
started by external trigger or by software and the conversion results of ADC1 and ADC2 are
stored into ADC1 data register (32-bit format)

If we can manage this little trick plus DMA and timer tick based timebase, we are 99% of the way to a “real” oscilloscope. We would still need some method of calibration and there may be issues with input impedance affecting the simplistic 1 Meg Ohm resistor as attenuator approach I have adopted… but I’m sure we can fix that in software :D

Sign in to reply