Analisador de Espectro de Áudio Arduino 32 Bandas — Display Linear e Pseudo-Log
Componentes e Materiais
| Arduino Nano R3 | ×1 |
| Resistor 10 kΩ | ×1 |
| Resistor 100 kΩ | ×2 |
| Resistor 4,75 kΩ | ×3 |
| Jumpers (genéricos) | ×1 |
| Protoboard (genérica) | ×1 |
| Cabo USB-A para Mini-USB | ×1 |
| Chave Tátil (Top Actuated) | ×1 |
| Header Macho 36 Posições 1 Linha (0,1") | ×1 |
Ferramentas e Máquinas Necessárias
- Ferro de Solda (genérico)
Software e Serviços Online
- Arduino IDE
Sobre Este Projeto
Este projeto marca minha primeira incursão em eletrônica de áudio baseada em Arduino. Inspirado no visualizador de áudio do Shajeeb, expandi o display para incluir modo linear de 32 bandas e modo pseudo-log de 11 bandas. Construí tabelas de mapeamento logarítmico personalizadas no Excel e as integrei no firmware para resposta de frequência mais precisa.
Um botão tátil alterna entre os dois modos de display, permitindo troca rápida durante performance ou experimentação.
Sinta-se à vontade para ajustar o firmware ou hardware para seus próprios projetos criativos.
Código Fonte
32_Band_LED_Spectrum_Analyzer-009.ino (Arduino)
// Código modificado por Christian Suryanto, baseado em (c) 2019 Shajeeb TM
// HAZI TECH
// Atualizado por 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;
}
Esquemáticos
Processo de manufatura
- Alerta Inteligente de Sede para Plantas – Sensor DIY para Hidratação Ideal
- Relógio de Palavras em Italiano com Arduino Nano, NeoPixel, LCD e RTC
- Economize Pinos do Arduino: Conecte Teclado 4x3 com Apenas Três Conexões
- Medidor kWh Confiável com Sigfox e Arduino MKR Fox 1200
- Monitor de Temperatura com Bluetooth usando Arduino Nano
- Medidor de Capacitância Autoranging DIY (10 pF–10 µF) – Montagem Fácil com Arduino
- Fechadura por Gestos Sem Toque: Acesso Seguro com APDS-9960 e Arduino
- Companion IC: Relógio, Ohmímetro, Capacímetro e Testador de Diodos com Arduino Nano
- Circuito de Entrada Analógica Isolada para Arduino
- Teste de Tempo de Reação Preciso com Arduino UNO