Тема: Анализатор спектра на матрице 8x8 MAX7219
Основная статья - http://rcl-radio.ru/?p=104916
////////// |PORT |pin | Arduino
// MAX7219
#define CLK PD2 // | 4 | D2
#define CS PD3 // | 5 | D3
#define DIN PD4 // | 6 | D4
#define AUTO_GAIN 1 // автонастройка по громкости
#define LOW_PASS 40 // нижний порог чувствительности шумов (нет скачков при отсутствии звука)
#define DEF_GAIN 300 // максимальный порог по умолчанию
#define FHT_N 256 // ширина спектра х2
#define LOG_OUT 1
#define INPUT_GAIN 1.0
#define BR 0 // яркость
#include <FHT.h> // http://forum.rcl-radio.ru/misc.php?action=pan_download&item=297&download=1
byte posOffset[32] = {4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,21,22,23,24,25,26,27,28,29,30,31,32,33,34};
int i1;
unsigned long data[32];
unsigned long data1,data2,data3,data4,data5,data6,data7,data8;
byte a[32];
int ur[32],urr[32];
unsigned long gainTimer;
int gain_sp = DEF_GAIN;
int maxValue;
int maxValue_f;
float k = 0.5;
void setup(){
ADMUX = 0b11000000; ADCSRA = 0b11010110;
DDRD |= (1 << DIN) | (1 << CS) | (1 << CLK);
max7219_L(0x0F, 0);// тест выкл.
max7219_L(0x0C, 0x01010101);// вкл. индик.
max7219_L(0x0A, 0x01010101*BR);// яркость
max7219_L(0x09, 0);// дешифраторы выкл.
max7219_L(0x0B, 0x07070707);// кол-во разрядов
}
void loop(){
analyzeAudio();
for (int i = 0; i < FHT_N/2; i++) {
if (fht_log_out[i] < LOW_PASS) fht_log_out[i] = 0;
fht_log_out[i] = (float)fht_log_out[i] * INPUT_GAIN;}
maxValue = 0;
for (int pos = 0; pos < 32; pos++) {
if (fht_log_out[posOffset[pos]] > maxValue) maxValue = fht_log_out[posOffset[pos]];
int posLevel = map(fht_log_out[posOffset[pos]], LOW_PASS, gain_sp, 0, 8);posLevel = constrain(posLevel, 0, 8);
urr[pos] = posLevel;
if(urr[pos]<ur[pos]){ur[pos]=ur[pos]-1;}
else{ur[pos] = posLevel;}
delayMicroseconds(10);
switch(ur[pos]){
case 0: a[pos]=0b00000000;break;
case 1: a[pos]=0b00000001;break;
case 2: a[pos]=0b00000011;break;
case 3: a[pos]=0b00000111;break;
case 4: a[pos]=0b00001111;break;
case 5: a[pos]=0b00011111;break;
case 6: a[pos]=0b00111111;break;
case 7: a[pos]=0b01111111;break;
case 8: a[pos]=0b11111111;break;
}
data1 = data1 + ((uint32_t(a[pos] >> 0) & 1)<<pos);
data2 = data2 + ((uint32_t(a[pos] >> 1) & 1)<<pos);
data3 = data3 + ((uint32_t(a[pos] >> 2) & 1)<<pos);
data4 = data4 + ((uint32_t(a[pos] >> 3) & 1)<<pos);
data5 = data5 + ((uint32_t(a[pos] >> 4) & 1)<<pos);
data6 = data6 + ((uint32_t(a[pos] >> 5) & 1)<<pos);
data7 = data7 + ((uint32_t(a[pos] >> 6) & 1)<<pos);
data8 = data8 + ((uint32_t(a[pos] >> 7) & 1)<<pos);
}
max7219_L(8, data8 );
max7219_L(7, data7 );
max7219_L(6, data6 );
max7219_L(5, data5 );
max7219_L(4, data4 );
max7219_L(3, data3 );
max7219_L(2, data2 );
max7219_L(1, data1 );
data1=0;data2=0;data3=0;data4=0;data5=0;data6=0;data7=0;data8=0;
if (AUTO_GAIN) {
if (millis() - gainTimer > 10) {
maxValue_f = maxValue * k + maxValue_f * (1 - k);
if (maxValue_f > LOW_PASS) gain_sp = maxValue_f;
else gain_sp = DEF_GAIN;
gainTimer = millis();}}
}
void max7219_L(byte reg_n, unsigned long h){
byte h1 = h >> 24;
byte h2 = h >> 16;
byte h3 = h >> 8;
byte h4 = h;
PORTD &=~(1 << CS);WriteBit16(reg_n,h1);WriteBit16(reg_n,h2);WriteBit16(reg_n,h3);WriteBit16(reg_n,h4);PORTD |=(1 << CS);
}
void WriteBit16(byte reg, byte data){
for(char i = 7; i >= 0; i--){
PORTD &= ~(1 << CLK);
if(((reg >> i) & 1) == 1){PORTD |= (1 << DIN);}else{PORTD &= ~(1 << DIN);}
PORTD |=(1 << CLK);}
for(char i = 7; i >= 0; i--){
PORTD &= ~(1 << CLK);
if(((data >> i) & 1) == 1){PORTD |= (1 << DIN);}else{PORTD &= ~(1 << DIN);}
PORTD |=(1 << CLK);}
PORTD &= ~(1 << CLK);PORTD |= (1 << DIN);
}
void analyzeAudio() {
while(i1 < FHT_N){i1++;
do{ADCSRA |= (1 << ADSC);}
while((ADCSRA & (1 << ADIF)) == 0);fht_input[i1] = (ADCL|ADCH << 8);}i1=0;
fht_window(); // window the data for better frequency response
fht_reorder(); // reorder the data before doing the fht
fht_run(); // process the data in the fht
fht_mag_log(); // take the output of the fht
}