Industrial manufacturing
Industrial Internet of Things | Industrial materials | Equipment Maintenance and Repair | Industrial programming |
home  MfgRobots >> Industrial manufacturing >  >> Manufacturing Technology >> Manufacturing process

32‑Band Arduino Audio Spectrum Analyzer – Linear & Pseudo‑Log Display

Components & Supplies

32‑Band Arduino Audio Spectrum Analyzer – Linear & Pseudo‑Log Display
Arduino Nano R3
×1
32‑Band Arduino Audio Spectrum Analyzer – Linear & Pseudo‑Log Display
Resistor 10kΩ
×1
32‑Band Arduino Audio Spectrum Analyzer – Linear & Pseudo‑Log Display
Resistor 100kΩ
×2
32‑Band Arduino Audio Spectrum Analyzer – Linear & Pseudo‑Log Display
Resistor 4.75kΩ
×3
32‑Band Arduino Audio Spectrum Analyzer – Linear & Pseudo‑Log Display
Jumper Wires (generic)
×1
32‑Band Arduino Audio Spectrum Analyzer – Linear & Pseudo‑Log Display
Breadboard (generic)
×1
32‑Band Arduino Audio Spectrum Analyzer – Linear & Pseudo‑Log Display
USB‑A to Mini‑USB Cable
×1
32‑Band Arduino Audio Spectrum Analyzer – Linear & Pseudo‑Log Display
Tactile Switch (Top Actuated)
×1
32‑Band Arduino Audio Spectrum Analyzer – Linear & Pseudo‑Log Display
Male Header 36‑Position 1‑Row (0.1")
×1

Tools & Machines Needed

32‑Band Arduino Audio Spectrum Analyzer – Linear & Pseudo‑Log Display
Soldering Iron (generic)

Software & Online Services

32‑Band Arduino Audio Spectrum Analyzer – Linear & Pseudo‑Log Display
Arduino IDE

About This Project

This project marks my first foray into Arduino‑based audio electronics. Inspired by Shajeeb’s audio visualizer, I expanded the display to include a 32‑band linear mode and an 11‑band pseudo‑log mode. I built custom logarithmic mapping tables in Excel and integrated them into the firmware for a more accurate frequency response.

A tactile button toggles between the two display modes, allowing quick switching during performance or experimentation.

Feel free to tweak the firmware or hardware to fit your own creative projects.

Source Code

  • 32_Band_LED_Spectrum_Analyzer-009.ino
32_Band_LED_Spectrum_Analyzer-009.ino Arduino
// Modified code by Christian Suryanto, based on (c) 2019 Shajeeb TM
// HAZI TECH
// Updated by Christian Suryanto

#include <arduinoFFT.h>
#include <MD_MAX72xx.h>
#include <SPI.h>
#include <EEPROM.h>

#define HARDWARE_TYPE MD_MAX72XX::FC16_HW
#define CLK_PIN   13
#define DATA_PIN  11
#define CS_PIN    10

#define SAMPLES 64
#define MAX_DEVICES 4
#define xres 32
#define yres 8

#define PREV 0xFF02FD
#define NEXT 0xFFC23D
#define PWR 0xFFA25D

int audio_response = 35;

double vReal[SAMPLES];
double vImag[SAMPLES];
char data_avgs[xres];

int yvalue;
int displaycolumn , displayvalue;
int peaks[xres];
const int buttonPin = 6;
int state = HIGH;
int previousState = LOW;
int displaymode;
unsigned long lastDebounceTime = 0;
unsigned long debounceDelay = 50;

int MY_ARRAY[]={0, 128, 192, 224, 240, 248, 252, 254, 255};

bool EQ_ON = true;

byte eq1[32] = {40, 45, 50, 60, 65, 70, 75, 95,
               110, 110, 110, 110, 110, 110, 110, 110,
               130, 130, 130, 130, 130, 130, 130, 130,
               145, 155, 170, 180, 215, 220, 245, 255};

byte eq2[11] = {40, 70, 75, 110, 110, 140, 145, 220, 220, 230, 250};

MD_MAX72XX mx = MD_MAX72XX(HARDWARE_TYPE, CS_PIN, MAX_DEVICES);
arduinoFFT FFT = arduinoFFT();

void setup() {
    EEPROM.update(1,1);
    displaymode = EEPROM.read(1);
    ADCSRA = 0b11100101;
    ADMUX = 0b00000000;
    pinMode(buttonPin, INPUT);
    mx.begin();
    mx.control(MD_MAX72XX::INTENSITY, 0);
    delay(50);
}

void loop() {
   int numData;
   double rSum;

   for(int i=0; i<SAMPLES; i++) {
      while(!(ADCSRA & 0x10));
      ADCSRA = 0b11110101;
      int value = ADC - 512;
      value = value / 8;
      vReal[i] = value;
      vImag[i] = 0;
    }

    FFT.Windowing(vReal, SAMPLES, FFT_WIN_TYP_HAMMING, FFT_FORWARD);
    FFT.Compute(vReal, vImag, SAMPLES, FFT_FORWARD);
    FFT.ComplexToMagnitude(vReal, vImag, SAMPLES);

    int step = (SAMPLES)/xres;

    switch (displaymode) {
      case 1 : {
        numData = 32;
        for(int i=0; i<32; i++) data_avgs[i] = (vReal[i] + vReal[SAMPLES-1-i]) / 2;
        break;
      }
      case 2 : {
        numData = 11;
        data_avgs[0] = vReal[0];
        data_avgs[1] = (vReal[0] + vReal[63] + vReal[1] + vReal[0]) / 4;
        data_avgs[2] = (vReal[1] + vReal[63] + vReal[2] + vReal[62] + vReal[3] + vReal[61]) / 6;
        data_avgs[3] = (vReal[2] + vReal[62] + vReal[3] + vReal[61] + vReal[4] + vReal[60]) / 6;
        data_avgs[4] = (vReal[5] + vReal[59] + vReal[6] + vReal[58] + vReal[7] + vReal[57]) / 6;
        data_avgs[5] = (vReal[8] + vReal[56] + vReal[9] + vReal[55] + vReal[10] + vReal[54] + vReal[11] + vReal[53]) / 8;
        data_avgs[6] = (vReal[12] + vReal[52] + vReal[13] + vReal[51] + vReal[14] + vReal[50] + vReal[15] + vReal[49]) / 8;
        data_avgs[7] = (vReal[16] + vReal[48] + vReal[17] + vReal[47] + vReal[18] + vReal[46]) / 6;
        data_avgs[8] = (vReal[19] + vReal[45] + vReal[20] + vReal[44] + vReal[21] + vReal[43] + vReal[22] + vReal[42]) / 8;
        data_avgs[9] = (vReal[23] + vReal[41] + vReal[24] + vReal[40] + vReal[25] + vReal[39] + vReal[26] + vReal[38] + vReal[27] + vReal[37]) / 10;
        data_avgs[10] = (vReal[28] + vReal[36] + vReal[29] + vReal[35] + vReal[30] + vReal[34] + vReal[31] + vReal[33]) / 8;
        break;
      }
    }

    for(int i=0; i<numData; i++) {
      data_avgs[i] = data_avgs[i] / 2;
      if (EQ_ON) {
        if (displaymode==1) data_avgs[i] = data_avgs[i] * eq1[i] / 100;
        else data_avgs[i] = data_avgs[i] * eq2[i] / 100;
      }
      data_avgs[i] = constrain(data_avgs[i],0,audio_response);
      data_avgs[i] = map(data_avgs[i], 0, audio_response, 0, yres);

      yvalue = data_avgs[i];
      peaks[i] = peaks[i]-1;
      if (yvalue > peaks[i]) peaks[i] = yvalue;
      yvalue = peaks[i];
      displayvalue = MY_ARRAY[yvalue];

      if (displaymode==1) {
        displaycolumn = 31-i;
        mx.setColumn(displaycolumn, displayvalue);
      } else {
        displaycolumn = 31-(3*i);
        mx.setColumn(displaycolumn-1, displayvalue);
        mx.setColumn(displaycolumn, displayvalue);
      }
    }

    displayModeChange();
}

void displayModeChange() {
  int reading = digitalRead(buttonPin);
  if (reading == HIGH && previousState == LOW && millis() - lastDebounceTime > debounceDelay) {
    if (displaymode==1) {
      displaymode = 2;
      mx.clear();
      delay(200);
      EEPROM.update(1,2);
    } else {
      displaymode = 1;
      mx.clear();
      delay(200);
      EEPROM.update(1,1);
    }
    lastDebounceTime = millis();
  }
  previousState = reading;
}

Schematics

32‑Band Arduino Audio Spectrum Analyzer – Linear & Pseudo‑Log Display

Manufacturing process

  1. Build an Italian Word Clock with Arduino Nano, NeoPixel, LCD, and RTC
  2. Build a Reliable Sigfox kWh Meter with Arduino MKR Fox 1200
  3. Bluetooth-Enabled Temperature Monitor with Arduino Nano
  4. Touch‑Free Gesture Lock: Secure Access with APDS‑9960 and Arduino
  5. Arduino Nano Companion Kit – Essential Components & Tools for DIY Electronics
  6. USB MIDI Adapter Kit for Arduino Micro / Leonardo – Complete Parts List
  7. RGB 32‑Band Audio Spectrum Visualizer – Arduino LED Matrix Project
  8. Build a TV Output Cable for Arduino UNO with Just Two Resistors
  9. Smart Arduino-Driven Automatic Watering System
  10. FHT Audio Spectrum Visualizer – Build a Stunning LED Audio Display