MAX7219 — драйвер восьми разрядного цифрового LED индикатора с последовательным интерфейсом. Драйвер может управлять восемью семисегментными индикаторами с точкой, либо отдельно 64 светодиодами в LED панелях с общим катодом.
Драйвер MAX7219 управляется по трехпроводной последовательной шине Microwire (3-Wire). Драйвер допускают каскадирование для управления большим числом индикаторов. Каждый из разрядов индикатора имеет независимую адресацию и его содержимое может быть обновлено без необходимости перезаписи всего индикатора. ИС MAX7219 также позволяют пользователю определять режим декодирования каждого разряда.
На базе матрицы используя 4 модуля по 64 светодиода, можно собрать анализатор спектра звукового сигнала. Матрица управляется при помощи платы Arduino Nano (Atmega8, Atmega168, Atmega328), звуковой сигнал подается на вход А0 через конденсатор 0.1 мкФ.
!!! Обратите внимание, что при полной яркости LED матрица может потреблять более 1,5 А, поэтому для питания матрицы используйте отдельный источник питания 5 В с максимальным выходным током не менее 2 А!!!
////////// |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 }
Скетч анализатора спектра имеет несколько параметров которые можно изменить:
- #define LOW_PASS 40 // нижний порог чувствительности шумов (устранение скачков при отсутствии звука)
- #define DEF_GAIN 300 // максимальный порог по умолчанию
- #define INPUT_GAIN 1.0 // предусилитель входа
- #define BR 0 // яркость матрицы
Питание матрицы можно брать напрямую с платы Arduino, но при условии что значение яркости #define BR не будет превышать 3. При большой яркости матрица должна питаться от отдельного источника питания напряжением 5 В с максимальным током 1.5-2.0 А. Так же при питании матрицы от платы Arduino, питание на матрицу подается только после загрузки скетча.