Music Reactive LCD Vu Meter
LCD Vu meter for your home theatre
Components and supplies
1
Resistor 330 ohm
1
Jumper wires (generic)
1
Alphanumeric LCD, 16 x 2
1
Single Turn Potentiometer- 10k ohms
1
Gravity: Analog Sound Sensor For Arduino
1
Arduino UNO
1
Pushbutton Switch, Push-Pull
Tools and machines
1
Hot glue gun (generic)
Apps and platforms
1
Arduino IDE
Project description
Code
Code
arduino
1// https://www.youtube.com/channel/UCaXI2PcsTlH5g0et67kdD6g // 2// LCD Vu Meter // 3// By MOHD SOHAIL // 4 5 6#define AUTO_GAIN 1 // auto adjust by volume 7#define VOL_THR 45 // silence threshold (below it there will be no display on the matrix) 8#define LOW_PASS 40 // lower threshold of noise sensitivity (no jumps in the absence of sound) 9#define DEF_GAIN 120 // default maximum threshold 10#define FHT_N 256 // spectrum width x2 11#define LOG_OUT 1 12 13#include <FHT.h> 14#include <EEPROM.h> 15#include <LiquidCrystal.h> 16LiquidCrystal lcd(2, 3, 8, 9, 10, 11);// RS,E,D4,D5,D6,D7 17 18byte posOffset[16] = {2, 3, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30}; 19byte maxValue, maxValue_f,set=1,gain_sp = DEF_GAIN; 20float k = 0.1; 21int i,j,pattern; 22unsigned long gainTimer; 23int buttonPin = 12; 24 25void setup() 26{ 27Serial.begin(9600); 28ADMUX = 0b01100000; ADCSRA = 0b11010100; 29lcd.begin( 16,2 ); 30pinMode(buttonPin, INPUT); 31digitalWrite(buttonPin, LOW); // Initializing 32digitalWrite(buttonPin, HIGH); // button pin is HIGH, so it drops to 0 if pressed 33pattern = EEPROM.read(100); 34} 35 36void loop() 37{ 38if(digitalRead(buttonPin)==LOW){pattern++;EEPROM.update(100,pattern); set=1;if(pattern>5){pattern=0;}delay(300);} 39 40 if(pattern==0&&set==1){ 41 byte v1[8] = {0, 0, 0, 0, 0, 0, 0, 31}; 42 byte v2[8] = {0, 0, 0, 0, 0, 0, 31, 31}; 43 byte v3[8] = {0, 0, 0, 0, 0, 0, 31, 31}; 44 byte v4[8] = {0, 0, 0, 0, 31, 0, 31, 31}; 45 byte v5[8] = {0, 0, 0, 31, 31, 0, 31, 31}; 46 byte v6[8] = {0, 0, 0, 31, 31, 0, 31, 31}; 47 byte v7[8] = {0, 31, 0, 31, 31, 0, 31, 31}; 48 byte v8[8] = {31, 31, 0, 31, 31, 0, 31, 31}; 49 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); 50 set=0;} 51 52 if(pattern==1&&set==1){ 53 byte v1[8] = {0, 0, 0, 0, 0, 0, 0, 27}; 54 byte v2[8] = {0, 0, 0, 0, 0, 0, 27, 27}; 55 byte v3[8] = {0, 0, 0, 0, 0, 0, 27, 27}; 56 byte v4[8] = {0, 0, 0, 0, 27, 0, 27, 27}; 57 byte v5[8] = {0, 0, 0, 27, 27, 0, 27, 27}; 58 byte v6[8] = {0, 0, 0, 27, 27, 0, 27, 27}; 59 byte v7[8] = {0, 27, 0, 27, 27, 0, 27, 27}; 60 byte v8[8] = {27, 27, 0, 27, 27, 0, 27, 27}; 61 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); 62 set=0;} 63 64 if(pattern==2&&set==1){ 65 byte v1[8] = {0, 0, 0, 0, 0, 0, 0, 14}; 66 byte v2[8] = {0, 0, 0, 0, 0, 0, 14, 14}; 67 byte v3[8] = {0, 0, 0, 0, 0, 0, 14, 14}; 68 byte v4[8] = {0, 0, 0, 0, 14, 0, 14, 14}; 69 byte v5[8] = {0, 0, 0, 14, 14, 0, 14, 14}; 70 byte v6[8] = {0, 0, 0, 14, 14, 0, 14, 14}; 71 byte v7[8] = {0, 14, 0, 14, 14, 0, 14, 14}; 72 byte v8[8] = {14, 14, 0, 14, 14, 0, 14, 14}; 73 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); 74 set=0;} 75 76 if(pattern==3&&set==1){ 77 byte v1[8] = {0, 0, 0, 0, 0, 0, 0, 31}; 78 byte v2[8] = {0, 0, 0, 0, 0, 0, 31, 31}; 79 byte v3[8] = {0, 0, 0, 0, 0, 31, 31, 31}; 80 byte v4[8] = {0, 0, 0, 0, 31, 31, 31, 31}; 81 byte v5[8] = {0, 0, 0, 31, 31, 31, 31, 31}; 82 byte v6[8] = {0, 0, 31, 31, 31, 31, 31, 31}; 83 byte v7[8] = {0, 31, 31, 31, 31, 31, 31, 31}; 84 byte v8[8] = {31, 31, 31, 31, 31, 31, 31, 31}; 85 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); 86 set=0;} 87 88 if(pattern==4&&set==1){ 89 byte v1[8] = {0, 0, 0, 0, 0, 0, 0, 27}; 90 byte v2[8] = {0, 0, 0, 0, 0, 0, 27, 27}; 91 byte v3[8] = {0, 0, 0, 0, 0, 27, 27, 27}; 92 byte v4[8] = {0, 0, 0, 0, 27, 27, 27, 27}; 93 byte v5[8] = {0, 0, 0, 27, 27, 27, 27, 27}; 94 byte v6[8] = {0, 0, 27, 27, 27, 27, 27, 27}; 95 byte v7[8] = {0, 27, 27, 27, 27, 27, 27, 27}; 96 byte v8[8] = {27, 27, 27, 27, 27, 27, 27, 27}; 97 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); 98 set=0;} 99 100 if(pattern==5&&set==1){ 101 byte v1[8] = {0, 0, 0, 0, 0, 0, 0, 14}; 102 byte v2[8] = {0, 0, 0, 0, 0, 0, 14, 14}; 103 byte v3[8] = {0, 0, 0, 0, 0, 14, 14, 14}; 104 byte v4[8] = {0, 0, 0, 0, 14, 14, 14, 14}; 105 byte v5[8] = {0, 0, 0, 14, 14, 14, 14, 14}; 106 byte v6[8] = {0, 0, 14, 14, 14, 14, 14, 14}; 107 byte v7[8] = {0, 14, 14, 14, 14, 14, 14, 14}; 108 byte v8[8] = {14, 14, 14, 14, 14, 14, 14, 14}; 109 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); 110 set=0;} 111 112analyzeAudio(); // FHT function, clogs the fht_log_out [] array with values along the spectrum 113 114 for (int pos = 0; pos < 16; pos++) 115 { 116 if (fht_log_out[posOffset[pos]] > maxValue) maxValue = fht_log_out[posOffset[pos]]; 117 lcd.setCursor(pos, 0); 118 int posLevel = map(fht_log_out[posOffset[pos]], LOW_PASS, gain_sp, 0, 15);posLevel = constrain(posLevel, 0, 15); 119 120 while(j<2){j++;delay(2); 121 if (posLevel > 7) {lcd.write((uint8_t)posLevel-8);lcd.setCursor(pos, 1);lcd.write((uint8_t)7);} 122 else {lcd.print(" ");lcd.setCursor(pos, 1);lcd.write((uint8_t)posLevel); }}j=0;} 123 124 if (AUTO_GAIN) { 125 maxValue_f = maxValue * k + maxValue_f * (1 - k); 126 if (millis() - gainTimer > 1500) { 127 if (maxValue_f > VOL_THR) gain_sp = maxValue_f; 128 else gain_sp = 150;gainTimer = millis();} 129 else {gain_sp = DEF_GAIN;}} 130} // loop 131 132 133void analyzeAudio() 134{ 135while(i < FHT_N){i++; 136do{ADCSRA |= (1 << ADSC);} 137while((ADCSRA & (1 << ADIF)) == 0);fht_input[i] = (ADCL|ADCH << 8);}i=0; 138fht_window(); // window the data for better frequency response 139fht_reorder(); // reorder the data before doing the fht 140fht_run(); // process the data in the fht 141fht_mag_log(); // take the output of the fht 142} 143
Code
arduino
1// https://www.youtube.com/channel/UCaXI2PcsTlH5g0et67kdD6g // 2// LCD Vu Meter // 3// By MOHD SOHAIL // 4 5 6#define AUTO_GAIN 1 // auto adjust by volume 7#define VOL_THR 45 // silence threshold (below it there will be no display on the matrix) 8#define LOW_PASS 40 // lower threshold of noise sensitivity (no jumps in the absence of sound) 9#define DEF_GAIN 120 // default maximum threshold 10#define FHT_N 256 // spectrum width x2 11#define LOG_OUT 1 12 13#include <FHT.h> 14#include <EEPROM.h> 15#include <LiquidCrystal.h> 16LiquidCrystal lcd(2, 3, 8, 9, 10, 11);// RS,E,D4,D5,D6,D7 17 18byte posOffset[16] = {2, 3, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30}; 19byte maxValue, maxValue_f,set=1,gain_sp = DEF_GAIN; 20float k = 0.1; 21int i,j,pattern; 22unsigned long gainTimer; 23int buttonPin = 12; 24 25void setup() 26{ 27Serial.begin(9600); 28ADMUX = 0b01100000; ADCSRA = 0b11010100; 29lcd.begin( 16,2 ); 30pinMode(buttonPin, INPUT); 31digitalWrite(buttonPin, LOW); // Initializing 32digitalWrite(buttonPin, HIGH); // button pin is HIGH, so it drops to 0 if pressed 33pattern = EEPROM.read(100); 34} 35 36void loop() 37{ 38if(digitalRead(buttonPin)==LOW){pattern++;EEPROM.update(100,pattern); set=1;if(pattern>5){pattern=0;}delay(300);} 39 40 if(pattern==0&&set==1){ 41 byte v1[8] = {0, 0, 0, 0, 0, 0, 0, 31}; 42 byte v2[8] = {0, 0, 0, 0, 0, 0, 31, 31}; 43 byte v3[8] = {0, 0, 0, 0, 0, 0, 31, 31}; 44 byte v4[8] = {0, 0, 0, 0, 31, 0, 31, 31}; 45 byte v5[8] = {0, 0, 0, 31, 31, 0, 31, 31}; 46 byte v6[8] = {0, 0, 0, 31, 31, 0, 31, 31}; 47 byte v7[8] = {0, 31, 0, 31, 31, 0, 31, 31}; 48 byte v8[8] = {31, 31, 0, 31, 31, 0, 31, 31}; 49 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); 50 set=0;} 51 52 if(pattern==1&&set==1){ 53 byte v1[8] = {0, 0, 0, 0, 0, 0, 0, 27}; 54 byte v2[8] = {0, 0, 0, 0, 0, 0, 27, 27}; 55 byte v3[8] = {0, 0, 0, 0, 0, 0, 27, 27}; 56 byte v4[8] = {0, 0, 0, 0, 27, 0, 27, 27}; 57 byte v5[8] = {0, 0, 0, 27, 27, 0, 27, 27}; 58 byte v6[8] = {0, 0, 0, 27, 27, 0, 27, 27}; 59 byte v7[8] = {0, 27, 0, 27, 27, 0, 27, 27}; 60 byte v8[8] = {27, 27, 0, 27, 27, 0, 27, 27}; 61 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); 62 set=0;} 63 64 if(pattern==2&&set==1){ 65 byte v1[8] = {0, 0, 0, 0, 0, 0, 0, 14}; 66 byte v2[8] = {0, 0, 0, 0, 0, 0, 14, 14}; 67 byte v3[8] = {0, 0, 0, 0, 0, 0, 14, 14}; 68 byte v4[8] = {0, 0, 0, 0, 14, 0, 14, 14}; 69 byte v5[8] = {0, 0, 0, 14, 14, 0, 14, 14}; 70 byte v6[8] = {0, 0, 0, 14, 14, 0, 14, 14}; 71 byte v7[8] = {0, 14, 0, 14, 14, 0, 14, 14}; 72 byte v8[8] = {14, 14, 0, 14, 14, 0, 14, 14}; 73 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); 74 set=0;} 75 76 if(pattern==3&&set==1){ 77 byte v1[8] = {0, 0, 0, 0, 0, 0, 0, 31}; 78 byte v2[8] = {0, 0, 0, 0, 0, 0, 31, 31}; 79 byte v3[8] = {0, 0, 0, 0, 0, 31, 31, 31}; 80 byte v4[8] = {0, 0, 0, 0, 31, 31, 31, 31}; 81 byte v5[8] = {0, 0, 0, 31, 31, 31, 31, 31}; 82 byte v6[8] = {0, 0, 31, 31, 31, 31, 31, 31}; 83 byte v7[8] = {0, 31, 31, 31, 31, 31, 31, 31}; 84 byte v8[8] = {31, 31, 31, 31, 31, 31, 31, 31}; 85 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); 86 set=0;} 87 88 if(pattern==4&&set==1){ 89 byte v1[8] = {0, 0, 0, 0, 0, 0, 0, 27}; 90 byte v2[8] = {0, 0, 0, 0, 0, 0, 27, 27}; 91 byte v3[8] = {0, 0, 0, 0, 0, 27, 27, 27}; 92 byte v4[8] = {0, 0, 0, 0, 27, 27, 27, 27}; 93 byte v5[8] = {0, 0, 0, 27, 27, 27, 27, 27}; 94 byte v6[8] = {0, 0, 27, 27, 27, 27, 27, 27}; 95 byte v7[8] = {0, 27, 27, 27, 27, 27, 27, 27}; 96 byte v8[8] = {27, 27, 27, 27, 27, 27, 27, 27}; 97 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); 98 set=0;} 99 100 if(pattern==5&&set==1){ 101 byte v1[8] = {0, 0, 0, 0, 0, 0, 0, 14}; 102 byte v2[8] = {0, 0, 0, 0, 0, 0, 14, 14}; 103 byte v3[8] = {0, 0, 0, 0, 0, 14, 14, 14}; 104 byte v4[8] = {0, 0, 0, 0, 14, 14, 14, 14}; 105 byte v5[8] = {0, 0, 0, 14, 14, 14, 14, 14}; 106 byte v6[8] = {0, 0, 14, 14, 14, 14, 14, 14}; 107 byte v7[8] = {0, 14, 14, 14, 14, 14, 14, 14}; 108 byte v8[8] = {14, 14, 14, 14, 14, 14, 14, 14}; 109 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); 110 set=0;} 111 112analyzeAudio(); // FHT function, clogs the fht_log_out [] array with values along the spectrum 113 114 for (int pos = 0; pos < 16; pos++) 115 { 116 if (fht_log_out[posOffset[pos]] > maxValue) maxValue = fht_log_out[posOffset[pos]]; 117 lcd.setCursor(pos, 0); 118 int posLevel = map(fht_log_out[posOffset[pos]], LOW_PASS, gain_sp, 0, 15);posLevel = constrain(posLevel, 0, 15); 119 120 while(j<2){j++;delay(2); 121 if (posLevel > 7) {lcd.write((uint8_t)posLevel-8);lcd.setCursor(pos, 1);lcd.write((uint8_t)7);} 122 else {lcd.print(" ");lcd.setCursor(pos, 1);lcd.write((uint8_t)posLevel); }}j=0;} 123 124 if (AUTO_GAIN) { 125 maxValue_f = maxValue * k + maxValue_f * (1 - k); 126 if (millis() - gainTimer > 1500) { 127 if (maxValue_f > VOL_THR) gain_sp = maxValue_f; 128 else gain_sp = 150;gainTimer = millis();} 129 else {gain_sp = DEF_GAIN;}} 130} // loop 131 132 133void analyzeAudio() 134{ 135while(i < FHT_N){i++; 136do{ADCSRA |= (1 << ADSC);} 137while((ADCSRA & (1 << ADIF)) == 0);fht_input[i] = (ADCL|ADCH << 8);}i=0; 138fht_window(); // window the data for better frequency response 139fht_reorder(); // reorder the data before doing the fht 140fht_run(); // process the data in the fht 141fht_mag_log(); // take the output of the fht 142} 143
Downloadable files
Circuit Diagram
Circuit Diagram

Comments
Only logged in users can leave comments