Components and supplies
Alphanumeric LCD, 16 x 2
Arduino Nano R3
Resistor 100k ohm
Through Hole Resistor, 22 kohm
Capacitor 100 nF
Tools and machines
Soldering iron (generic)
Apps and platforms
Arduino IDE
Project description
Code
Main.cpp.ino
arduino
1/* 2 Arduino based VU meter by KTAudio. 3 Developed by ThomAce (Tamas Kamocsai) based on siemenwauters, theredstonelabz and michiel H's VU meter. 4 5 GNU GPL License v3 6 7 Developer: ThomAce (Tamas Kamocsai) 8 Mail: thomacepcg@gmail.com 9 Version: 1.0 10 Last modification date: 2019.09.24 11 12 Original version: 13 https://www.instructables.com/id/ARDUINO-VU-METER/ 14 15 Original description: 16 VU meter by siemenwauters, theredstonelabz and michiel H don't forget to like and subscribe to support my work. tnx 17*/ 18 19#include <LiquidCrystal.h> 20 21byte Bar[8] = { 22 B11111, 23 B00000, 24 B11111, 25 B11111, 26 B11111, 27 B11111, 28 B00000, 29 B11111 30}; 31 32byte L[8] = { 33 B00111, 34 B01000, 35 B10100, 36 B10100, 37 B10100, 38 B10111, 39 B01000, 40 B00111 41}; 42 43byte R[8] = { 44 B00111, 45 B01000, 46 B10110, 47 B10101, 48 B10110, 49 B10101, 50 B01000, 51 B00111 52}; 53 54byte EndMark[8] = { 55 B10000, 56 B01000, 57 B00100, 58 B00100, 59 B00100, 60 B00100, 61 B01000, 62 B10000 63}; 64 65byte EmptyBar[8] = { 66 B11111, 67 B00000, 68 B00000, 69 B00000, 70 B00000, 71 B00000, 72 B00000, 73 B11111 74}; 75 76byte peakHoldChar[8] = { 77 B11111, 78 B00000, 79 B01110, 80 B01110, 81 B01110, 82 B01110, 83 B00000, 84 B11111 85}; 86 87String main_version = "1.0"; 88int left, right; //Variables to store and calculate the channel levels 89const int numReadings = 5; //Refresh rate. Lower value = higher rate. 5 is the defaul 90int indexL = 0; //Actual channel index 91int totalL = 0; //Total channel data 92int maxL = 0; //Maximal level 93int indexR = 0; 94int totalR = 0; 95int maxR = 0; 96int inputPinL = A1; //Input pin Analog 1 for LEFT channel 97int inputPinR = A0; //Input pin Analog 0 for RIGHT channel 98int volL = 0; 99int volR = 0; 100int rightAvg = 0; 101int leftAvg = 0; 102long peakHoldTime = 1500; //peak hold time in miliseconds 103long peakHold = 0; 104int rightPeak = 0; 105int leftPeak = 0; 106long decayTime = 0; 107long actualMillis = 0; 108 109LiquidCrystal lcd(11, 10, 7, 6, 5, 4); //lcd configuration 110 111void setup() 112{ 113 lcd.begin(40, 2); //Setting up LCD. 16 chars and 2 rows 114 115 lcd.createChar(1, Bar); 116 lcd.createChar(2, L); 117 lcd.createChar(3, R); 118 lcd.createChar(4, EmptyBar); 119 lcd.createChar(5, EndMark); 120 lcd.createChar(6, peakHoldChar); 121 122 //Showing loading message and loading bar 123 124 String KTAudio = "KTaudio project"; 125 126 for (int i = 0; i <= 16; i++) 127 { 128 lcd.setCursor(0, 0); 129 lcd.print(KTAudio.substring(0, i)); 130 delay(50); 131 } 132 133 KTAudio = "VU meter " + main_version; 134 135 for (int i = 0; i <= KTAudio.length(); i++) 136 { 137 lcd.setCursor(0, 1); 138 lcd.print(KTAudio.substring(0, i)); 139 delay(50); 140 } 141 142 delay(500); 143 144 lcd.clear(); 145 lcd.setCursor(0, 0); 146 lcd.print("Loading..."); 147 148 for (int i = 0; i < 16; i++) 149 { 150 lcd.setCursor(i, 1); 151 lcd.write(4); 152 } 153 154 for (int i = 0; i < 16; i++) 155 { 156 lcd.setCursor(i, 1); 157 lcd.write(1); 158 159 delay(50); 160 } 161 162 delay(500); 163 lcd.clear(); 164 165 decayTime = millis(); 166} 167 168void loop() 169{ 170 actualMillis = millis(); 171 172 lcd.setCursor(0, 0); //L channel index 173 lcd.write(2); //L symbol 174 lcd.setCursor(0, 1); //R channel index 175 lcd.write(3); //R symbol 176 lcd.setCursor(15, 0); //closing tag / end mark index 1 177 lcd.write(5); //closing tag / end mark 178 lcd.setCursor(15, 1); //closing tag / end mark index 2 179 lcd.write(5); //closing tag / end mark 180 181 totalL = analogRead(inputPinL) / 4 - 128; //reducing the detected hum and noise 182 183 if(totalL > maxL) 184 { 185 maxL = totalL; 186 } 187 188 indexL++; 189 190 if (indexL >= numReadings) 191 { 192 indexL = 0; 193 left = maxL; 194 maxL = 0; 195 } 196 197 totalR = analogRead(inputPinR) / 4 - 128; //reducing the detected hum and noise 198 199 if(totalR > maxR) 200 { 201 maxR = totalR; 202 } 203 204 indexR++; 205 206 if (indexR >= numReadings) 207 { 208 indexR = 0; 209 right = maxR; 210 maxR = 0; 211 } 212 213 volR = right / 3; 214 215 if(volR > 14) 216 { 217 volR = 14; 218 } 219 220 if (volR < (rightAvg - 2)) 221 { 222 if (decayTime < actualMillis) 223 rightAvg--; 224 225 volR = rightAvg; 226 } 227 else if (volR > (rightAvg + 2)) 228 { 229 volR = (rightAvg + 2); 230 rightAvg = volR; 231 } 232 else 233 { 234 rightAvg = volR; 235 } 236 237 if (volR > rightPeak) 238 { 239 rightPeak = volR; 240 } 241 242 drawBar(volR, rightPeak, 1); 243 244 volL = left / 3; 245 246 if(volL > 14) 247 { 248 volL = 14; 249 } 250 251 if (volL < (leftAvg - 2)) 252 { 253 if (decayTime < actualMillis) 254 leftAvg--; 255 256 volL = leftAvg; 257 } 258 else if (volL > (leftAvg + 2)) 259 { 260 volL = (leftAvg + 2); 261 leftAvg = volL; 262 } 263 else 264 { 265 leftAvg = volL; 266 } 267 268 if (volL > leftPeak) 269 { 270 leftPeak = volL; 271 } 272 273 drawBar(volL, leftPeak, 0); 274 275 if (decayTime < actualMillis) 276 decayTime = (millis() + 50); 277 278 if (peakHold < actualMillis) 279 { 280 peakHold = (millis() + peakHoldTime); 281 rightPeak = -1; 282 leftPeak = -1; 283 } 284} 285 286void drawBar(int data, int peakData, int row) 287{ 288 //If the previous peak data is 1 or 0, then not taking care of the value. 289 if (peakData < 2) 290 { 291 peakData = -1; 292 } 293 294 //First char (idx 0) = R or L 295 //Last (16th) char (idx 15) is the closing mark of the bar. 296 //We have 14 chars to write. 297 for (int col = 1; col < 15; col++) 298 { 299 lcd.setCursor(col, row); 300 301 if (col < data) 302 { 303 lcd.write(1); //write bar element 304 } 305 else if (peakData == col) 306 { 307 lcd.write(6); //write the peak marker 308 } 309 else 310 { 311 lcd.write(4); //write "empty" 312 } 313 } 314} 315
Downloadable files
Wiring diagram
Wiring diagram
Wiring diagram
Wiring diagram
Comments
Only logged in users can leave comments