Disco Fever!

I have been working on a spectrum analyzer based on the STM32F303 Nucleo.  The analyzer uses a 16 LED WS2812B led ring to output spectrum data.  There were lots of interesting things on the way.

First of all, it seems that there are times when you should use gcc as your linker rather than ld.  It would appear that there are lots of options and switches built into gcc which it quietly passes on to the linker.  This tripped me up when specifying floating point options and specifying the FPU type.  After LOTS of fiddling and searching of mailing lists the problem was solved and the Makefile contains the necessary switches for the FPU and floating point libraries to all work together.

During the course of this project I tried to use the CMSIS fft functions – after all, they are optimized for ARM by ARM.  Sadly this didn’t work out because the 64k for flash memory in the STM32F303 isn’t big enough apparently.  I reverted to an fft function I’ve been using for years now on other MCU’s.  Its a lot smaller and executes quickly enough : the signal processing time for 512 samples is about 8.5ms.

Finally, the last hurdle to be overcome involved the WS2812B’s.  In a previous post I described the use of the STM32F042 with the WS2812 ring.  This MCU runs at 48MHz making it easy to generate a 3MHz SPI bus frequency : just divide by 16.  The STM32F303 however runs at 64MHz and only certain divisors are available (8/16/32 etc).  Initially I tried running the SPI at 2MHz and this worked for one or two LED’s however it did not work well for 16.  4MHz was then tried and its seems its ok although there is some flicker with certain combinations of LED colours.

The circuit.



The video

The video below shows the STM32F303 performing a live FFT and controlling a WS2812 LED ring. The LED ring is driven as follows:
At the 6 o’clock position is low frequency. As you move anti-clockwise around the ring, each LED represents a higher frequency component.  Each LED represents a step of 128Hz so 2048Hz is the maximum frequency shown.  The system samples at 32768Hz however most of the music energy is at the lower end of the spectrum.  The LED ring is showing a “zoomed in” version of the spectrum

The LED colours change as follows (16 steps):
Blue : low magnitude
Yellow-Green : medium magnitude
Red : large magnitude


The music is from the Free Music Archive.  The track is Pianoman Sofa by Lobo Loco.



The code

The code is available on github at the link below.