STM32 Oscilloscope
This week I got some inspiration from the ST DSP library, so I made my own oscilloscope with the STM32 and my 320×240 pixels QTFT screen. I made the code from scratch, both the sampling and screen updating code – but I used the ST DSP library for the FFT calculations of course
You can see the video of the project here…
httphd://www.youtube.com/watch?v=llDmjxUtoRA
Due to the huge amount of requests I’ve decided to publish the code used in this project.
The code is a bit messy as it contains bits of code that is never reached – fx in the main() function.
As said above, the code uses the ST DSP Library to do the FFT calculations, and it just uses one of the ADC inputs for the sampling.
The code package can be downloaded here: STM32 Oscilloscope
Great work, great video!
Great work using stm32. gives me some inspiration!
Thanks 🙂
How did you achived the flicker free graphics . Can you please tell me.
Flicker-free graphics?
The display is a display with a digital controller, which takes care of the v-sync. So I just write to that digital controller as a RAM, and then it remembers everything!
hi i am kannan, i saw ur video.. its really good work.. can u give any idea to use DSPs..how u used FFT results to made it to display….pls give me some idea.. this is my mail id.. kanna89ece@hotmail.com
Hi and welcome Kannan.
The FFT functions I’m using comes from ST’s DSP library, despite the fact that the STM32 isn’t a DSP, it’s a microprocessor!
In this project I use an AD port to read a number of samples, which I then use to calculate the FFT data. The FFT is kind of a spectrum showing which frequencies there are in the data!
Then you can use this FFT data and the fundamental frequency (kind of sampling frequency) to calculate the frequency there is most of.
The Fundamental Frequency is reciprocal to the sample time – this means that if you fill a buffer in 2 msec, the fundamental frequency would be 500Hz (1/0.002)
But all this are a little more complicated when using DSP’s, but the results would also be a bit better, as the chip is made for such things.
@Thomas Jespersen
thank you thomas… oh so you used microprocesor…and i understood the way u did it… so the microprocessor u use provide many DSP libraries or u download it.. i actually work on ARM controllers… will there be any DSP libraries available for ARM processors…
i thot using normal processor for DSP applications is tougher than doing it in DSPs.. how ever u hav done it using libraries… good work.. thank you.. do you know how to do power calculatons using DSPs….can you tell me abt that…?
@Kannan
ST has provided every STM32 (an Cortex-M3 ARM processor) users with an easy-to-use DSP library, and they also included great documentation and code examples.
Unfortunately I haven’t messed a lot with DSP’s yet, I have two boards from Analog Devices though – the Blackfin BF533 and another. But I haven’t tried using them for real yet!
Hi. kannan
I’m new to STM32 development. Your project is very interesting. I need something like this for example. Can You send me the code of this project ?
Kind Regards.
@Ivan
Dear Ivan.
Sure I can. Please send me a mail so I can send you the project folder. You can either use my direct mail address or the Contact formular at the front page.
My mail is: thomasj(at)tkjelectronics.dk
Best Regards
Thomas Jespersen
hi, Thomas great work, you make look easy and fun to work with STM32, i used the ST?s DSP library, too in one of my proyects which also i used the ADC in order to take samples and then extract the fundamental frecuency but the frecuency that the FFT give me is not correct, i dont know what i am doing wrong, can You send me the code of this project ? i really appreciate your help
Thank you in advance.
@Zero
Hi.
When trying to extract the fundamental frequency, do you use the already available example, which comes with the DSP library, for that? I cam recommend having a look at the FFT example as it gives a good point of view on how to use the library.
I have also uploaded the project now so you can have a look and see how I did it.
The link is in the bottom of the blog post.
Best Regards
Thomas Jespersen
HI Thomas, great work! Could you explain me,please! in your code, where “SampleBuffer[SamplesCount] = (ADC_Read<<20)-0x7FFFFFFF" – that's mean – Left shift the ADC value (0-4096) to a 32-bit value, and make it signed (-2,147,483,648 to +2,147,483,647)
I don't understand why must we Left shift 20 the ADC value (0-4096) to a 32-bit value? how does it work? Thank you very much 🙂
@saivn
This is because we scale the input buffer to match the required buffer size for the FFT to work properly. As the ADC is only 12-bit but the FFT is 32-bit we scale the ADC input to fit the FFT.
And then we also sign the value as real analog values vary from -1 to 1, in our case with the ADC 0 is -1 and 4095 is 1 – which makes 2048 = 0.
Thanks for posting your code, Thomas. One question, I don’t see where you actually run the FFT? What function are you calling to run the FFT? Thanks.
@dext0rb
First I call “GetSamples(SamplingDelay);” to fill up the SampleBuffer array with ADC readings together with a calculated sampling frequency.
Next I use this array with samples as the input for the FFT calculating function:
Now the calculated FFT array can be found within the fft pointer and this pointer can then be used to find/extract the fundamental frequency which is the frequency with the peak value insied the calculated FFT array.
I hope this answered your questions.
Regards Thomas
@Thomas Jespersen
Thanks for the reply. I do not see the call to compute_fft(SampleBuffer) in main.c ???
Perhaps you have uploaded a different version of code? Or perhaps I am very blind. 😀
I see how to use compute_fft, just wondering how it was called in the demo program.
@dext0rb
Hmm, true. In the uploaded code I didn’t use the FFT algorithm as I didn’t calculate the fundamental frequency.
The code shown in the video is a bit newer but much more unpolished – which you can also see by the ‘bad characters’ in the video!
But I would of course like to share this with you all, as long as you have these things in mind: STM32_Oscilloscope_2012.zip
Merry Christmas
Hi Thosmas !
I have use your code and modify to caculate fundamental frequency as below :
u16 Fs
u32 *ff_out;
Fs = GetSamples();
ff_out = (u32*)compute_fft(SampleBuffer, 64);//SampleBuffer get from ADC
freq = fundamental_frequency(ff_out,Fs);
But I can’t caculate right freq.Can you help me ?
@Hao Doan
To be able to compute the fundamental frequency you need to turn the FFT output into the right frequency scale.
To do this you need to make your sampling frequency exact or at least know the current sampling frequency.
You can find an updated version of the project, which includes the capability of calculating the fundamental frequency due to a known sampling frequency.
This updated project can be downloaded here: STM32_Oscilloscope_2012.zip
Regards Thomas
Thanks Thomas.I dont understand this function :
u16 CalculateSamplingDelay(u32 SamplingFreq) {
return 937274*pow(SamplingFreq,-0.995);
}
can you explain for me ?
I using STM32F100C6T6 with Fclock = 24 Mhz to measure frquency.So with this clock f CalculateSamplingDelay function have right ?
Thanks !
@Hao Doan
That specific function is only used when changing the wanted sampling frequency (OriginalSampleFreq)
The real sampling frequency itself is calculated when the samples is taken.
So as long as your SystemFrequency is correct, and your SysTick is set to 1us
Then everything should be good to go!
Regards Thomas
Thank.I measured frequency.with Fclok 24Mhz ,I only get sample frequency max 10Khz.I intend use DMA and set sample frequency ADC_SampleTime_1Cycles5.If so Can I increase sample frequency ?Thanks !
Thank for your code, I would like to modify it to use with CoIDE and my RedBull stm32f103zet board. Thanks!
@Thamanoon
Keep me updated by letting me know how it goes with getting the project to work inside CoIDE.
As I remember you will for sure need to do some modifications to the linker file and startup files, as these are for Ride7 only!
Hi Thomas!
I make new project in CoIDE to use with stm32f103zet RedBull board with some modification for show sine wave in vertical. It’s not difficult to make new project in CoIDE, we can include CMSIS and startup file by tick on RCC in peripherals Repository. Here this link:
http://www.electoday.com/index.php/topic,11938.0.html
I think it’s better to modify to use TIM for sampling ADC or not?
Thank!
It’s no need linker file.
@Thamanoon
I definitely agree with you. CoIDE is a great IDE as it comes with its’ repository of “tickable” libraries.
Though please have in mind and make sure that these libraries are the latest and updated as well, as I have experienced them becoming outdated! 🙂
For the sampling I would recommend making a Timer-interrupt based sampler or even better a DMA based sampler to offload the processor, which is probably how I would do it now if I was about to redo this project.
@Thomas Jespersen
I think libraries are useful and come with CMSIS libraries.
hiii i have to implement 256 point fft for stm32f303vc ….please give me idea about that
how i used this for implement fft on stm32f303vc board.how give input as asine wave to calculate fft of sine wave for 256 point redix 4 fft
Does it better than the dsPIC by microchip to calculate the FFT in terms of speed and ease of programming?