#define AUTO_GAIN 1 // автонастройка по громкости #define VOL_THR 45 // порог тишины (ниже него отображения на матрице не будет) #define LOW_PASS 40 // нижний порог чувствительности шумов (нет скачков при отсутствии звука) #define DEF_GAIN 120 // максимальный порог по умолчанию #define FHT_N 256 // ширина спектра х2 #define LOG_OUT 1 #include #include #include LiquidCrystal lcd(12, 11, 5, 4, 3, 2);// RS,E,D4,D5,D6,D7 byte posOffset[16] = {2, 3, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30}; // вч выше byte maxValue, maxValue_f,www=1,gain_sp = DEF_GAIN; float k = 0.1; int i1,yyy,spek; unsigned long gainTimer; void setup(){ Serial.begin(9600); ADMUX = 0b01100000; ADCSRA = 0b11010100; lcd.begin(16, 2); pinMode(9,INPUT); spek = EEPROM.read(100); } void loop(){ if(digitalRead(9)==HIGH){spek++;EEPROM.update(100,spek); www=1;if(spek>5){spek=0;}delay(300);} if(spek==0&&www==1){ byte v1[8] = {0, 0, 0, 0, 0, 0, 0, 4}; byte v2[8] = {0, 0, 0, 0, 0, 0, 4, 4}; byte v3[8] = {0, 0, 0, 0, 0, 4, 4, 4}; byte v4[8] = {0, 0, 0, 0, 4, 4, 4, 4}; byte v5[8] = {0, 0, 0, 4, 4, 4, 4, 4}; byte v6[8] = {0, 0, 4, 4, 4, 4, 4, 4}; byte v7[8] = {0, 4, 4, 4, 4, 4, 4, 4}; byte v8[8] = {4, 4, 4, 4, 4, 4, 4, 4}; lcd.createChar(0, v1);lcd.createChar(1, v2);lcd.createChar(2, v3);lcd.createChar(3, v4);lcd.createChar(4, v5);lcd.createChar(5, v6);lcd.createChar(6, v7);lcd.createChar(7, v8); www=0;} if(spek==1&&www==1){ byte v1[8] = {0, 0, 0, 0, 0, 0, 0, 14}; byte v2[8] = {0, 0, 0, 0, 0, 0, 14, 14}; byte v3[8] = {0, 0, 0, 0, 0, 14, 14, 14}; byte v4[8] = {0, 0, 0, 0, 14, 14, 14, 14}; byte v5[8] = {0, 0, 0, 14, 14, 14, 14, 14}; byte v6[8] = {0, 0, 14, 14, 14, 14, 14, 14}; byte v7[8] = {0, 14, 14, 14, 14, 14, 14, 14}; byte v8[8] = {14, 14, 14, 14, 14, 14, 14, 14}; lcd.createChar(0, v1);lcd.createChar(1, v2);lcd.createChar(2, v3);lcd.createChar(3, v4);lcd.createChar(4, v5);lcd.createChar(5, v6);lcd.createChar(6, v7);lcd.createChar(7, v8); www=0;} if(spek==2&&www==1){ byte v1[8] = {0, 0, 0, 0, 0, 0, 0, 10}; byte v2[8] = {0, 0, 0, 0, 0, 0, 10, 10}; byte v3[8] = {0, 0, 0, 0, 0, 10, 10, 10}; byte v4[8] = {0, 0, 0, 0, 10, 10, 10, 10}; byte v5[8] = {0, 0, 0, 10, 10, 10, 10, 10}; byte v6[8] = {0, 0, 10, 10, 10, 10, 10, 10}; byte v7[8] = {0, 10, 10, 10, 10, 10, 10, 10}; byte v8[8] = {10, 10, 10, 10, 10, 10, 10, 10}; lcd.createChar(0, v1);lcd.createChar(1, v2);lcd.createChar(2, v3);lcd.createChar(3, v4);lcd.createChar(4, v5);lcd.createChar(5, v6);lcd.createChar(6, v7);lcd.createChar(7, v8); www=0;} if(spek==3&&www==1){ byte v1[8] = {0, 0, 0, 0, 0, 0, 0, 27}; byte v2[8] = {0, 0, 0, 0, 0, 0, 27, 27}; byte v3[8] = {0, 0, 0, 0, 0, 27, 27, 27}; byte v4[8] = {0, 0, 0, 0, 27, 27, 27, 27}; byte v5[8] = {0, 0, 0, 27, 27, 27, 27, 27}; byte v6[8] = {0, 0, 27, 27, 27, 27, 27, 27}; byte v7[8] = {0, 27, 27, 27, 27, 27, 27, 27}; byte v8[8] = {27, 27, 27, 27, 27, 27, 27, 27}; lcd.createChar(0, v1);lcd.createChar(1, v2);lcd.createChar(2, v3);lcd.createChar(3, v4);lcd.createChar(4, v5);lcd.createChar(5, v6);lcd.createChar(6, v7);lcd.createChar(7, v8); www=0;} if(spek==4&&www==1){ byte v1[8] = {0, 0, 0, 0, 0, 0, 0, 31}; byte v2[8] = {0, 0, 0, 0, 0, 0, 31, 31}; byte v3[8] = {0, 0, 0, 0, 0, 31, 31, 31}; byte v4[8] = {0, 0, 0, 0, 31, 31, 31, 31}; byte v5[8] = {0, 0, 0, 31, 31, 31, 31, 31}; byte v6[8] = {0, 0, 31, 31, 31, 31, 31, 31}; byte v7[8] = {0, 31, 31, 31, 31, 31, 31, 31}; byte v8[8] = {31, 31, 31, 31, 31, 31, 31, 31}; lcd.createChar(0, v1);lcd.createChar(1, v2);lcd.createChar(2, v3);lcd.createChar(3, v4);lcd.createChar(4, v5);lcd.createChar(5, v6);lcd.createChar(6, v7);lcd.createChar(7, v8); www=0;} if(spek==5&&www==1){ byte v1[8] = {0, 0, 0, 0, 0, 0, 0, 21}; byte v2[8] = {0, 0, 0, 0, 0, 0, 21, 21}; byte v3[8] = {0, 0, 0, 0, 0, 21, 21, 21}; byte v4[8] = {0, 0, 0, 0, 21, 21, 21, 21}; byte v5[8] = {0, 0, 0, 21, 21, 21, 21, 21}; byte v6[8] = {0, 0, 21, 21, 21, 21, 21, 21}; byte v7[8] = {0, 21, 21, 21, 21, 21, 21, 21}; byte v8[8] = {21, 21, 21, 21, 21, 21, 21, 21}; lcd.createChar(0, v1);lcd.createChar(1, v2);lcd.createChar(2, v3);lcd.createChar(3, v4);lcd.createChar(4, v5);lcd.createChar(5, v6);lcd.createChar(6, v7);lcd.createChar(7, v8); www=0;} analyzeAudio(); // функция FHT, забивает массив fht_log_out[] величинами по спектру for (int pos = 0; pos < 16; pos++) { if (fht_log_out[posOffset[pos]] > maxValue) maxValue = fht_log_out[posOffset[pos]]; lcd.setCursor(pos, 0); int posLevel = map(fht_log_out[posOffset[pos]], LOW_PASS, gain_sp, 0, 15);posLevel = constrain(posLevel, 0, 15); while(yyy<2){yyy++;delay(2); if (posLevel > 7) {lcd.write((uint8_t)posLevel-8);lcd.setCursor(pos, 1);lcd.write((uint8_t)7);} else {lcd.print(" ");lcd.setCursor(pos, 1);lcd.write((uint8_t)posLevel); }}yyy=0;} if (AUTO_GAIN) { maxValue_f = maxValue * k + maxValue_f * (1 - k); if (millis() - gainTimer > 1500) { if (maxValue_f > VOL_THR) gain_sp = maxValue_f; else gain_sp = 150;gainTimer = millis();} else {gain_sp = DEF_GAIN;}} }// loop 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 }