Build an Audio Spectrum Analyzer with Arduino and LEDs
An audio spectrum analyzer with Arduino is one of the most visually impressive electronics projects you can build. By analyzing audio frequencies in real-time and displaying them as LED bar graphs, you create a professional-looking VU meter that responds to music, speech, or any sound source. This guide walks through building a complete spectrum analyzer using Arduino, an electret microphone, and an LED matrix — all readily available in India for under ₹800.
How FFT Audio Analysis Works
A spectrum analyzer works by decomposing an audio signal into its constituent frequencies using Fast Fourier Transform (FFT). The human hearing range spans 20Hz–20kHz, and a spectrum analyzer displays the amplitude (loudness) at different frequency bands simultaneously — typically split into 8, 16, or 32 bands.
On Arduino Uno (16MHz, 10-bit ADC), we can sample audio at approximately 9,600 samples/second, giving a Nyquist frequency of 4,800Hz. This covers the most musically important range (bass 20-300Hz, midrange 300Hz-4kHz, presence 4-8kHz). Using the ArduinoFFT library, a 64-point FFT executes in approximately 2ms — fast enough for responsive LED updates at 30 fps.
Components Required
- Arduino Uno or Nano (₹250-350)
- Electret microphone module with MAX4466 or LM393 (₹80-150)
- LED bar graph (10-segment) × 4 pieces, or individual LEDs × 40 (₹120-200)
- 74HC595 shift registers × 5 (for 8-column display) (₹40-80)
- Resistors: 220Ω × 40 (for LED current limiting) (₹20)
- 100µF and 100nF capacitors (₹10)
- 3.5mm audio jack + cable (₹30-50)
- Breadboard or PCB (₹50-100)
- Total estimated cost: ₹600-950
Recommended Product
Analog Sound Sensor Microphone Module for Arduino
High-sensitivity electret microphone module with analog output — perfect audio input for spectrum analyzer projects. Adjustable gain via onboard potentiometer.
Category: Audio & Sound Modules
Circuit Schematic
The microphone module connects to Arduino’s analog input. Power the module from 3.3V (not 5V) for lower noise floor. The 74HC595 shift registers chain together to drive multiple LED columns with only 3 Arduino pins.
/* Circuit Connections:
*
* MICROPHONE MODULE:
* VCC → Arduino 3.3V
* GND → Arduino GND
* OUT → Arduino A0 (via 10K pull-down to GND)
*
* 74HC595 CHAIN (for 8 LED columns):
* Arduino Pin 11 → DS (Data in of first 595)
* Arduino Pin 12 → SHCP (Clock) — all 595s in parallel
* Arduino Pin 8 → STCP (Latch) — all 595s in parallel
* QA-QH → LED anodes (via 220Ω resistors)
* Next 595: DS connected to Q7S (serial output) of previous
*
* LED ROWS (common cathodes):
* Arduino Pins 2-9 → 10 LED row cathodes (via 470Ω)
*/
Arduino FFT Code
// Audio Spectrum Analyzer with Arduino FFT
// Library: arduinoFFT (install via Library Manager)
// Install: Sketch → Include Library → Manage Libraries → Search "arduinoFFT"
#include "arduinoFFT.h"
#define SAMPLES 64 // Must be power of 2
#define SAMPLING_FREQ 9615 // Max for Arduino Uno (depends on ADC speed)
#define MIC_PIN A0
#define NUM_BANDS 8 // Number of frequency bands to display
double vReal[SAMPLES];
double vImag[SAMPLES];
ArduinoFFT FFT = ArduinoFFT(vReal, vImag, SAMPLES, SAMPLING_FREQ);
// Shift register pins
#define DATA_PIN 11
#define CLOCK_PIN 12
#define LATCH_PIN 8
// LED row pins (columns 1-8 = frequency bands)
int rowPins[8] = {2, 3, 4, 5, 6, 7, 9, 10};
int bandValues[8] = {0}; // Current amplitude for each band
int peakValues[8] = {0}; // Peak hold values
void setup() {
Serial.begin(115200);
// Setup shift register pins
pinMode(DATA_PIN, OUTPUT);
pinMode(CLOCK_PIN, OUTPUT);
pinMode(LATCH_PIN, OUTPUT);
// Setup LED row pins
for (int i = 0; i < 8; i++) {
pinMode(rowPins[i], OUTPUT);
digitalWrite(rowPins[i], HIGH); // Common cathode: HIGH = OFF
}
Serial.println("Audio Spectrum Analyzer Ready");
}
void loop() {
// Sample audio at precise intervals
unsigned int sampling_period_us = round(1000000.0 / SAMPLING_FREQ);
unsigned long microseconds = micros();
for (int i = 0; i < SAMPLES; i++) {
vReal[i] = analogRead(MIC_PIN) - 512; // Center around zero
vImag[i] = 0;
while (micros() - microseconds < sampling_period_us) {} // Wait
microseconds += sampling_period_us;
}
// Apply FFT
FFT.Windowing(FFT_WIN_TYP_HAMMING, FFT_FORWARD);
FFT.Compute(FFT_FORWARD);
FFT.ComplexToMagnitude();
// Map FFT bins to 8 frequency bands
// Bins 0-1: DC and very low (skip)
// Bands: Sub-bass, Bass, Low-Mid, Mid, Upper-Mid, Presence, Brilliance, Air
int bandBins[9] = {2, 3, 5, 8, 13, 21, 28, 37, 48}; // Logarithmic spacing
for (int band = 0; band < NUM_BANDS; band++) {
double bandAmp = 0;
int binCount = bandBins[band+1] - bandBins[band];
for (int bin = bandBins[band]; bin = peakValues[band]) {
peakValues[band] = bandValues[band];
} else if (peakValues[band] > 0) {
peakValues[band]--; // Slow decay
}
}
// Update LED display
updateDisplay();
}
void updateDisplay() {
// Multiplex through 8 rows
for (int row = 0; row < 8; row++) {
// Build column data for this row
byte colData = 0;
for (int band = 0; band row) {
colData |= (1 << band);
}
// Peak indicator
if (peakValues[band] == row + 1) {
colData |= (1 << band);
}
}
// Activate row (common cathode - LOW = active)
for (int r = 0; r < 8; r++) {
digitalWrite(rowPins[r], (r == row) ? LOW : HIGH);
}
// Shift out column data
digitalWrite(LATCH_PIN, LOW);
shiftOut(DATA_PIN, CLOCK_PIN, MSBFIRST, colData);
digitalWrite(LATCH_PIN, HIGH);
delayMicroseconds(500); // Display each row briefly
}
}
LED Matrix Display
For a cleaner build, use a MAX7219-based 8×8 LED matrix module (₹120-180) instead of individual LEDs and shift registers. The MAX7219 handles all multiplexing internally and connects to Arduino via SPI (3 wires). The LedControl library makes programming straightforward.
// MAX7219 LED Matrix version (simpler wiring)
#include <LedControl.h>
// LedControl(DIN, CLK, CS, numDevices)
LedControl lc = LedControl(11, 13, 10, 1);
void setupMatrix() {
lc.shutdown(0, false); // Wake up MAX7219
lc.setIntensity(0, 8); // Brightness 0-15
lc.clearDisplay(0);
}
void displayBand(int band, int value) {
// band: 0-7 (column), value: 0-8 (height)
for (int row = 0; row < 8; row++) {
lc.setLed(0, 7-row, band, row < value); // Bottom-up filling
}
}
Recommended Product
INMP441 MEMS Microphone Module for ESP32
Upgrade to MEMS microphone for superior SNR and frequency response. Ideal for advanced spectrum analyzer builds with ESP32 and I2S interface.
Category: Audio & Sound Modules
Advanced: MSGEQ7 for Better Performance
The MSGEQ7 is a dedicated 7-band graphic equalizer IC that performs analog spectrum analysis in hardware. It outputs 7 frequency bands (63Hz, 160Hz, 400Hz, 1kHz, 2.5kHz, 6.25kHz, 16kHz) via a multiplexed analog output. This is much faster and more accurate than Arduino software FFT, allowing 60fps updates and freeing Arduino resources for display work.
// MSGEQ7 Spectrum Analyzer (faster, dedicated IC)
#define STROBE_PIN 4
#define RESET_PIN 5
#define AUDIO_PIN A0
int spectrum[7]; // 7-band output
void readMSGEQ7() {
digitalWrite(RESET_PIN, HIGH);
delayMicroseconds(1);
digitalWrite(RESET_PIN, LOW);
for (int band = 0; band < 7; band++) {
digitalWrite(STROBE_PIN, LOW);
delayMicroseconds(36); // MSGEQ7 settling time
spectrum[band] = analogRead(AUDIO_PIN); // 0-1023
digitalWrite(STROBE_PIN, HIGH);
}
// spectrum[0] = 63Hz (sub-bass)
// spectrum[3] = 1kHz (midrange)
// spectrum[6] = 16kHz (air frequencies)
}
Enclosure and Finishing
For a professional look popular in Indian electronics fairs and school projects:
- Use a transparent acrylic sheet (2-3mm) for the LED face panel — available at plastic shops in metro cities for ₹50-100
- Colored transparent acrylic for color-coded frequency bands (red=bass, green=mid, blue=treble)
- Alternatively, use frosted film over clear LEDs for diffused glow effect
- 3D-printed enclosure: design in Tinkercad (free), print at local makerspaces (₹100-200)
- Add a 3.5mm audio jack input alongside the microphone for direct line-in from phone/computer
Recommended Product
Mini Digital Amplifier Module — 3W
Combine spectrum analyzer with this amplifier for a complete audio visualizer + speaker system. Perfect for music rooms and home studio setups.
Category: Audio & Sound Modules
Frequently Asked Questions
Q: Can Arduino Uno handle real-time FFT fast enough?
A: Yes, for 64-point FFT. Arduino Uno with arduinoFFT library processes a 64-sample FFT in approximately 2ms, allowing 30+ fps display updates. For 256-point FFT (better frequency resolution), you need an Arduino Due (84MHz) or ESP32 (240MHz).
Q: My spectrum analyzer shows noise even when music is off. How to fix?
A: Common causes: (1) Set a minimum threshold — only display if amplitude > 50 (noise floor), (2) Add 100µF bypass capacitor on microphone VCC, (3) Keep microphone away from switching power supplies, (4) Use shielded audio cable for microphone, (5) Power Arduino from linear supply not switching USB charger.
Q: How many frequency bands can I display?
A: With Arduino Uno, 8-16 bands at good refresh rates. ESP32’s dual-core 240MHz processor can handle 64+ bands. For LED displays, 8 columns × 8 rows (8 frequency bands, 8 amplitude levels) is the sweet spot for a impressive visual result.
Q: Can I use this project for a school science fair?
A: Absolutely! Audio spectrum analyzers consistently win at Indian school science fairs and engineering college exhibitions. Add an explanation board about FFT math, frequency content of different instruments, and applications in music production. Budget ₹800-1500 for a complete presentation-ready build.
Q: What’s the difference between VU meter and spectrum analyzer?
A: A VU meter shows overall loudness (single bar), while a spectrum analyzer shows loudness at each frequency separately (multiple bars). VU meters are simpler (just rectify + smooth the audio signal), while spectrum analyzers require FFT computation to separate frequency components.
Add comment