W tym artykule zaprezentuje oraz wytłumaczę jak możemy zbudować własny układ odbiornika audio ze spectrum. Do wykonania modelu wykorzystałem wymieniony wyżej mikrofon ze wzmacniaczem MAX9814. W modelu również zostały wykorzystane kilka nigdy wcześniej nie używanych przez nas bibliotek (takich jak np. fix_fft) , których działanie również mam zamiar pokazać.


Spis treści
- Krótki opis Mikrofonu
- Specyfikacja
- Podłączenie układu
- Program
- Pliki do pobrania (w tym biblioteki)
Krótki opis
Mikrofon o zakresie od 20Hz do 20kHz. Częstotliwość dźwięku jest pobierana przez układ dzięki napięciom na analogowym pinie Arduino. A następnie dzięki bibliotece fix_fft zamieniana na odpowiedni zakres dźwiękowy który można następnie wyświetlić na oledzie.
Specyfikacja
- Napięcie zasilania: od 2,7 V do 5,5 V
- Wyjście: 2 Vpp dla 1,25 V bias
- Zakres częstotliwości: od 20 Hz do 20 kHz
- Programowalna wartość Attack/Release ratio
- Automatyczne wzmocnienie
- Maksymalna wartość wzmocnienia: 40 dB / 50 dB / 60 dB (domyślnie)
- Wymiary: 26 x 14 mm
Połączenie układu
Elementy:
- Arduino Mega/Uno/Nano
- Mikrofon Moduł MAX9814
- Oled 128×64
- Rezystkor 0.25W 10kΩ 5%
- Płytka stykowa
- 4x kable stykowe (mes-żęń)
- 3xkable stykowe (męs)
Arduino -> Oled:
- A5(SDA) -> SDA
- A4(SCL) -> SCL
- GND -> GND
- 5V -> VCC
Arduino -> Mikrofon (wpinamy mikrofon do płytki stykowej)
- 5V – VCC
- GND – GND
- A0 – OUT (+rezystor)

Program
- Definicja zmiennych i załączenie biblioteka. Utworzenie obiektu biblioteki NanoEngine.
#include <fix_fft.h> #include <ssd1306.h> #include <nano_engine.h> #define SAMPLING_FREQUENCY 15000 #define TIME_FACTOR 3 #define SCALE_FACTOR 12 #ifdef LOG_OUTPUT const float log_scale = 64./log(64./SCALE_FACTOR + 1.); #endif const float coeff = 1./TIME_FACTOR; const unsigned int sampling_period_us = round(1000000 * (2.0 / SAMPLING_FREQUENCY)); int8_t data[64], buff[32]; unsigned long microseconds; int summ, avg; NanoEngine<TILE_32x32_MONO> engine;
2. Funkcja void setup(). Przypisanie wartości dla zmiennych oraz aktywacja oled i działania obiektu engine.
void setup() {
OSCCAL = 240;
ADCSRA &= ~(bit (ADPS0) | bit (ADPS1) | bit (ADPS2));
ADCSRA |= bit (ADPS2);
ADCSRA |= bit (ADPS0);
ssd1306_128x64_i2c_init();
ssd1306_clearScreen();
engine.begin();
}3. Funkcja void loop(). Funkcje for zajmują się zmianą wysokości słupków mocy. Natomiast obiekt engine redukcją szumów.
void loop() {
summ = 0;
for (int i = 0; i < 64; i++) {
microseconds = micros();
data[i] = ((analogRead(A0)) >> 2) - 128;
summ += data[i];
while (micros() < (microseconds + sampling_period_us)) {
}
}
avg = summ/64;
for (int i = 0; i < 64; i++){
data[i] -= avg;
}
fix_fftr(data, 6, 0);
for(int count = 0; count < 32; count++){
if(data[count] < 0) data[count] = 0;
#ifdef LOG_OUTPUT
else data[count] = log_scale*log((float)(data[count]+1));
#else
else data[count] *= SCALE_FACTOR;
#endif
data[count] = (float)buff[count] * anti_coeff + (float)data[count] * coeff;
buff[count] = data[count];
if(data[count] > 63) data[count] = 63;
}
engine.refresh();
engine.canvas.clear();
for(int i = 0; i < 8; i++){
engine.canvas.drawVLine(i*4,31-(data[i]+1),31);
}
engine.canvas.blt(0,32);
engine.canvas.clear();
for(int i = 0; i < 8; i++){
if(data[i] > 31) engine.canvas.drawVLine(i*4,31-(data[i]-31),31);
}
engine.canvas.blt(0,0);
engine.canvas.clear();
for(int i = 8; i < 16; i++){
engine.canvas.drawVLine((i-8)*4,31-(data[i]+1),31);
}
engine.canvas.blt(32,32);
engine.canvas.clear();
for(int i = 8; i < 16; i++){
if(data[i] > 31) engine.canvas.drawVLine((i-8)*4,31-(data[i]-31),31);
}
engine.canvas.blt(32,0);
engine.canvas.clear();
for(int i = 16; i < 24; i++){
engine.canvas.drawVLine((i-16)*4,31-(data[i]+1),31);
}
engine.canvas.blt(64,32);
engine.canvas.clear();
for(int i = 16; i < 24; i++){
if(data[i] > 31) engine.canvas.drawVLine((i-16)*4,31-(data[i]-31),31);
}
engine.canvas.blt(64,0);
engine.canvas.clear();
for(int i = 24; i < 32; i++){
engine.canvas.drawVLine((i-24)*4,31-(data[i]+1),31);
}
engine.canvas.blt(96,32);
engine.canvas.clear();
for(int i = 24; i < 32; i++){
if(data[i] > 31) engine.canvas.drawVLine((i-24)*4,31-(data[i]-31),31);
}
engine.canvas.blt(96,0);
}







