Home > ARM > STM32 Oscilloscope

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…

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

Categories: ARM Tags: , ,
  1. Frank
    February 18th, 2010 at 22:58 | #1

    Great work, great video!

  2. Satish Nair
    April 1st, 2010 at 16:47 | #2

    Great work using stm32. gives me some inspiration!

  3. dudedevil
    April 27th, 2010 at 15:38 | #4

    How did you achived the flicker free graphics . Can you please tell me.

    • April 27th, 2010 at 17:47 | #5

      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!

  4. Kannan
    June 8th, 2010 at 09:07 | #6

    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

    • June 8th, 2010 at 18:11 | #7

      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.

  5. Kannan
    June 11th, 2010 at 10:43 | #8

    @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…?

  6. June 11th, 2010 at 11:33 | #9

    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!

  7. Ivan
    July 22nd, 2011 at 09:51 | #10

    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.

  8. July 30th, 2011 at 20:46 | #11

    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

  9. Zero
    October 14th, 2011 at 17:22 | #12

    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.

  10. October 17th, 2011 at 14:21 | #13

    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

  11. saivn
    November 24th, 2012 at 16:20 | #14

    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 🙂

  12. December 4th, 2012 at 21:01 | #15

    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.

  13. December 12th, 2012 at 22:48 | #16

    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.

  14. December 13th, 2012 at 20:44 | #17

    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:

    u32* fft = compute_fft(SampleBuffer);

    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

  15. December 17th, 2012 at 20:53 | #18

    @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.

  16. December 22nd, 2012 at 00:37 | #19

    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

  17. Hao Doan
    March 23rd, 2013 at 10:30 | #20

    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 ?

  18. March 24th, 2013 at 18:50 | #21

    @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

  19. Hao Doan
    March 25th, 2013 at 04:44 | #22

    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 !

  20. March 26th, 2013 at 19:20 | #23

    @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

    SysTick_Config(SystemFrequency / 1000000)

    Then everything should be good to go!

    Regards Thomas

  21. Hao Doan
    March 27th, 2013 at 05:33 | #24

    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 !

  22. Thamanoon
    August 11th, 2014 at 22:22 | #25

    Thank for your code, I would like to modify it to use with CoIDE and my RedBull stm32f103zet board. Thanks!

  23. August 11th, 2014 at 23:08 | #26

    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!

  24. Thamanoon
    August 20th, 2014 at 22:55 | #27

    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:
    I think it’s better to modify to use TIM for sampling ADC or not?

  25. Thamanoon
    August 21st, 2014 at 01:05 | #28

    It’s no need linker file.

  26. August 27th, 2014 at 21:14 | #29

    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.

  27. Thamanoon
    September 1st, 2014 at 03:11 | #30

    @Thomas Jespersen
    I think libraries are useful and come with CMSIS libraries.

  28. shivangi rana
    March 27th, 2019 at 03:22 | #31

    hiii i have to implement 256 point fft for stm32f303vc ….please give me idea about that

  29. shivangi rana
    March 27th, 2019 at 06:41 | #32

    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

  30. Indula
    November 2nd, 2019 at 07:31 | #33

    Does it better than the dsPIC by microchip to calculate the FFT in terms of speed and ease of programming?

  1. No trackbacks yet.