This project has a working implementation of an (FFT-powered) audio spectrum analyzer with direct input from a 3.5mm jack. Compared to pictures below, I have added loudspeaker hardware (two 3W 4-Ohm stereo dynamic drivers, MAX98306 3.7W stereo amplifier) in order to turn this into a full-fledged Hi-Fi speaker. Currently working on isolating source of noise issues and working on a solution with a combination of better low-pass filtering, external discrete ADC, cleaner power, and improved wire routing.
Please refer to the project board.
A custom bluetooth speaker project conceived from an FFT mini-project. This MCU version serves as a test bed for the FPGA version.
- Overview
- Feature List
- Future Changes and Additions
- Issues
- List of Components and Tools
- Derived Sources
- Schematic Diagram
- References
This project began as a side project to a side project in understanding and implementing Discrete Fast Fourier Transforms (DFFTs) in FPGAs. I figured, why not give it a real application and plug an audio signal in to be visualized? And here we are. In the image below, I have an Arduino MKR Zero connected to an analog 3.5mm audio signal sampled at ~20 KHz (for a max frequency detection range of 0-10 KHz) with an adjustable sample count from 8 to 256 for 4 to 128 columns on the visualizer.
This repository contains the microcontroller version of what I hope to eventually implement in an FPGA in this repository. It is faster to develop and experiment with MCUs first as the toolset is less complex, and I am already more familiar with them. Currently, I am looking to add a user interface to this audio spectrum visualizer and turn it into a full-fledged custom wireless/wired speaker of my own design.
The prototype board as of 07.03.2021. The device with the larger screen cut off at the top of the frame is an Arduino Mega 2560-based Oscilloscope
- Real-Time Audio Visualization with Adjustable Frequency Range and Number of Columns
- Dual SSD1306 Displays
- Battery-Powered, micro-USB Rechargeable
- Audio Signal Input via 3.5mm Jack
The wireless functionality and UI portions of the code have yet to be added. Loudspeaker functionality is being worked on. Additionally, it is a long ways off, but I am already beginning to sketch designs and choose final hardware for a polished, custom PCB and accoustically-optimized enclosure version of this project.
Please look at the project board for a more accurate day-to-day view of current issues and features being worked on.
Right now, the project contains a functioning audio spectrum visualizer, but parameters to adjust the view can only be tweaked in source code. Additionally, the spectrum graph and speakers show varying amounts of "noise" depending on how clean the audio signal and power source are. This has yet to be fully resolved and may not be possible without reconfiguration and addition of more hardware (decoupling capacitors have already been added).
Please look at the project board for a more accurate day-to-day view of current issues and features being worked on.
-
3.7v 2300 mAh LiPo Battery with 2-pin JST connector (optional if desired for project to not require USB power all the time)
-
Breadboard
-
3x 5.1 KOhm In-Line Resistors
-
2x 100 KOhm In-Line Resistors (for audio signal voltage divider)
-
4x 10 KOhm In-Line Resistors (for pulldown purposes with the buttons)
-
2x 100 nF Capacitors
-
4x Pushbutton Switches
-
Tentative Component Additions (For Loudspeaker)
- Arduino IDE
- Arduino Libraries
I initially started this project off with the code and hardware components/config from this repository. There is also an Arduino Project Hub writeup.
I then proceeded to heavily modify the project. I subdivided the code into logical functions and made the FFT visualizer much more parameterizable (adjusting the number of columns samples, etc.). Instead of using a MAX7219-driven 32x8 LED matrix, I used a 128x64 SSD1306 OLED display (I2C version). The code has also been ported over to the Arduino MKR Zero which uses an entirely different microcontroller. This provides far more power and memory to support the higher resolution display and faster FFT calculation with more samples.
In the images on this README, four buttons and a second SSD1306 display can also be seen. These will support a future UI to adjust parameters of the FFT visualizer and control the future Bluetooth speaker functionality of this project.
It is worth mentioning while shajeebtm's project is capable of displaying all frequency ranges up to about 18KHz, I have (temporarily) intentionally set my max frequency at roughly 10KHz as the majority of the audio signal does not go beyond this range.
A quick-and-dirty early prototype I made my code running on both a MKR Zero (top) and Nano (bottom). Notice the MKR Zero's display shows 64 audio columns while the Nano only has 16. This is because the latter does not have enough dynamic memory nor speed to hold and do work any more ADC samples required for the FFT. It was possible for shajeebtm's project to display 32 columns on a Nano, but that is because his LED matrix requires less memory to be driven than a 128x64 display.
Switching from the Arduino Nano to the MKR Zero requires a significant rewrite of the code which configures the sampling rate of the ADC. The default Arduino analogRead()
function does not sample at a rate fast enough for an appreciable frequency range to be detected by the discrete FFT algorithm. In other words, the audio spectrum visualizer would probably only display frequency bars up to about 1KHz. In order to fix this, the prescaler value set for the ADC must be changed. The prescaler value divides the system clock speed by a power of 2.
Depending on the bit resolution the ADC is set at (8, 10, or 12 bits), each analog to digital conversion will take 5-7 clock cycles. In order to calculate the sampling rate, the formula is as follows:
Sampling Rate = SAMD21 Clock Speed / (Prescaler Value x Conversion Clocks Needed)
Doing this is very simple with the ATMega328P on an Nano, but is a much more involved process on a SAMD21 the MKR Zero has. I followed the videos and code provided by a guide found here.
Please refer to the Source Code/Hardware Inspiration, Documentation, and Technical Guides section found at the bottom of this README in 8. References.
As the project's hardware configuration is still in flux with many components to be added, there is no diagram here. However, it should be sufficient to follow the schematic shown on shajeebtm's project page. Just replace the Arduino Nano for the MKR Zero and substitute the SSD1306 for the MAX7219 on the I2C bus. Refer to the comments in the code to figure out which pins the I/O has been likewise re-mapped to.
As the MKR Zero is all 3.3V logic, connect the wire which links 5V to the display mode button to the MKR Zero's 3.3V power pin instead.
- Arduino 32 Band Audio Spectrum Visualizer / Analyzer - shajeebtm
- Speeding up the ADC on Arduino SAMD21 Boards (Zero, Mkr, etc) - ForceTronics
- Microcontroller Data Sheets
- Atmel SAMD21 - Used in the Arduino MKR Zero in this project.
- Refer to Ch. 33 (starting at page 781) for information about the ADC. A diagram of the registers you'll likely need to manipulate to adjust the sample rate as ForceTronics' guide suggests is on page 782.
- Atmel ATmega328P - Used in the Arduino Nano in shajeebtm's project.
- Refer to Ch. 23 (starting at page 205) for information about the ADC. The register you'll need to change to adjust the sample rate (via the prescaler) is ADCSRA.
- Atmel SAMD21 - Used in the Arduino MKR Zero in this project.
- SSD1306 OLED Display
- SAMD21 ADC
- Getting the Most out of the SAM D21's ADC - Stargirl Flowers - Conversion Time Calculator Enclosed
- Reading Analog Values with the SAMD21's ADC - Stargirl Flowers
- Device Communication Protocols
- Understanding Fast Fourier Transforms
- Digital Audio
- Signal Filtering
- On ADCs and DACs
- Arduino MKR Vidor 4000 - Another MKR-series board that looks very interesting as it also contains a Intel Cyclone 10CL016 FPGA to supplement the SAMD21 MCU, more I/O, and wireless radios. I am considering switching to this board in the future for expansions of this project.
Last Updated: 2021.07.14 18:39 PST