Monitoramento de Áudio e Visualização de Espectro com Sensor MAX9814 e Arduino

O módulo MAX9814 é um amplificador de microfone de alta performance que se destaca por possuir Controle Automático de Ganho (AGC). Essa característica o torna ideal para projetos de áudio onde o volume da fonte sonora pode variar drasticamente, permitindo capturar sons distantes sem saturar quando a fonte se aproxima. Neste guia, exploraremos como utilizar este sensor com o Arduino para medição de níveis sonoros e visualização de frequências via FFT.

Medição Estatística de Nível Sonoro (dB)

Nesta primeira abordagem, transformamos a leitura analógica do sensor em uma estimativa de decibéis (dB). O código utiliza uma fórmula de regressão linear para aproximar os valores lidos aos níveis reais de ruído ambiente. Um LED de alerta é acionado caso o ruído ultrapasse um limite pré-definido.


// Definição de pinos e variáveis globais
const int pinoMicrofone = A0;
const int pinoLedAlerta = 13;

int leituraAdc;
float nivelSom;
float nivelAnterior;

void setup() {
  Serial.begin(9600);
  pinMode(pinoLedAlerta, OUTPUT);
}

void loop() {
  nivelAnterior = nivelSom;
  leituraAdc = analogRead(pinoMicrofone);

  // Aplicação de fórmula de calibração baseada em valores experimentais
  // dB = (ADC + constante_offset) / fator_escala
  nivelSom = (leituraAdc + 83.2073) / 8.083;

  if (abs(nivelAnterior - nivelSom) > 0.5) {
    Serial.print("Intensidade: ");
    Serial.print(nivelSom);
    Serial.println(" dB");
  }

  // Acionamento visual para ruídos acima de 55dB
  if (nivelSom > 55) {
    digitalWrite(pinoLedAlerta, HIGH);
    delay(300);
    digitalWrite(pinoLedAlerta, LOW);
  }
  
  delay(100);
}

Análise de Espectro de Áudio com FFT e Display OLED

Para uma aplicação mais avançada, podemos utilizar a Transformada Rápida de Fourier (FFT) para decompor o sinal sonoro em diferentes bandas de frequência. Isso permite criar um equalizador visual em um display OLED SSD1306, mostrando como a energia do som está dsitribuída entre graves, médios e agudos.

Conexões sugeridas:

  • MAX9814 (VCC) -> Arduino (5V)
  • MAX9814 (GND) -> Arduino (GND)
  • MAX9814 (OUT) -> Arduino (A0)
  • OLED (SDA) -> Arduino (A4)
  • OLED (SCL) -> Arduino (A5)

#include "arduinoFFT.h"
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define AMOSTRAS 64          
#define FREQ_AMOSTRAGEM 8000 
#define LARGURA_TELA 128
#define ALTURA_TELA 32
#define PINO_SINAL A0

Adafruit_SSD1306 tela(LARGURA_TELA, ALTURA_TELA, &Wire, -1);
arduinoFFT FFT = arduinoFFT();

double vReal[AMOSTRAS];
double vImag[AMOSTRAS];
unsigned long periodo_micros;

void setup() {
  if(!tela.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    for(;;);
  }
  
  tela.clearDisplay();
  tela.setTextColor(SSD1306_WHITE);
  periodo_micros = round(1000000 * (1.0 / FREQ_AMOSTRAGEM));
}

void loop() {
  // Captura de amostras de áudio
  for (int i = 0; i < AMOSTRAS; i++) {
    unsigned long tempoInicio = micros();
    vReal[i] = analogRead(PINO_SINAL);
    vImag[i] = 0;
    while (micros() < (tempoInicio + periodo_micros)) {
      // Aguarda o próximo intervalo de amostragem
    }
  }

  // Processamento FFT
  FFT.Windowing(vReal, AMOSTRAS, FFT_WIN_TYP_HAMMING, FFT_FORWARD);
  FFT.Compute(vReal, vImag, AMOSTRAS, FFT_FORWARD);
  FFT.ComplexToMagnitude(vReal, vImag, AMOSTRAS);

  // Renderização do gráfico de barras no OLED
  tela.clearDisplay();
  int larguraBarra = LARGURA_TELA / (AMOSTRAS / 2);
  
  for (int i = 2; i < (AMOSTRAS / 2); i++) {
    int alturaBarra = map(vReal[i], 0, 1024, 0, ALTURA_TELA);
    tela.fillRect(i * larguraBarra, ALTURA_TELA - alturaBarra, larguraBarra - 1, alturaBarra, SSD1306_WHITE);
  }
  
  tela.display();
}

O uso do MAX9814 em conjunto com algoritmos de FFT abre portas para o desenvolvimento de sistemas de automação residencial acionados por frequências específicas, medidores de poluição sonora inteligentes e dispositivos de visualização musical de baixo custo.

Tags: Arduino MAX9814 FFT SSD1306 sensores

Publicado em 8-1 02:26