0% found this document useful (0 votes)
102 views

Arduino VU Meter

This Arduino code implements a VU meter to visualize audio levels from two input channels. It reads analog audio signals, calculates signal levels over time, and draws bar graphs on an LCD display to represent the real-time and peak levels for each channel. Character maps are defined for the graphical elements and the meter is initialized by displaying a loading screen. The main loop continuously updates the level calculations and redraws the bars.

Uploaded by

Mano Ohanian
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
102 views

Arduino VU Meter

This Arduino code implements a VU meter to visualize audio levels from two input channels. It reads analog audio signals, calculates signal levels over time, and draws bar graphs on an LCD display to represent the real-time and peak levels for each channel. Character maps are defined for the graphical elements and the meter is initialized by displaying a loading screen. The main loop continuously updates the level calculations and redraws the bars.

Uploaded by

Mano Ohanian
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 7

/*

Arduino based VU meter by KTAudio.


Developed by ThomAce (Tamas Kamocsai) based on siemenwauters,
theredstonelabz and michiel H's VU meter.

GNU GPL License v3

Developer: ThomAce (Tamas Kamocsai)


Mail: [email protected]
Version: 1.0
Last modification date: 2019.09.24

Original version:
https://www.instructables.com/id/ARDUINO-VU-METER/

Original description:
VU meter by siemenwauters, theredstonelabz and michiel H don't
forget to like and subscribe to support my work. tnx
*/

#include <LiquidCrystal.h>

byte Bar[8] = {
B11111,
B00000,
B11111,
B11111,
B11111,
B11111,
B00000,
B11111
};

byte L[8] = {
B00111,
B01000,
B10100,
B10100,
B10100,
B10111,
B01000,
B00111
};

byte R[8] = {
B00111,
B01000,
B10110,
B10101,
B10110,
B10101,
B01000,
B00111
};

byte EndMark[8] = {
B10000,
B01000,
B00100,
B00100,
B00100,
B00100,
B01000,
B10000
};

byte EmptyBar[8] = {
B11111,
B00000,
B00000,
B00000,
B00000,
B00000,
B00000,
B11111
};

byte peakHoldChar[8] = {
B11111,
B00000,
B01110,
B01110,
B01110,
B01110,
B00000,
B11111
};

String main_version = "1.0";


int left, right; //Variables to store and
calculate the channel levels
const int numReadings = 5; //Refresh rate. Lower value
= higher rate. 5 is the defaul
int indexL = 0; //Actual channel index
int totalL = 0; //Total channel data
int maxL = 0; //Maximal level
int indexR = 0;
int totalR = 0;
int maxR = 0;
int inputPinL = A1; //Input pin Analog 1 for
LEFT channel
int inputPinR = A0; //Input pin Analog 0 for
RIGHT channel
int volL = 0;
int volR = 0;
int rightAvg = 0;
int leftAvg = 0;
long peakHoldTime = 1500; //peak hold time in
miliseconds
long peakHold = 0;
int rightPeak = 0;
int leftPeak = 0;
long decayTime = 0;
long actualMillis = 0;

LiquidCrystal lcd(11, 10, 7, 6, 5, 4); //lcd configuration

void setup()
{
lcd.begin(40, 2); //Setting up LCD. 16 chars and 2 rows

lcd.createChar(1, Bar);
lcd.createChar(2, L);
lcd.createChar(3, R);
lcd.createChar(4, EmptyBar);
lcd.createChar(5, EndMark);
lcd.createChar(6, peakHoldChar);

//Showing loading message and loading bar

String KTAudio = "KTaudio project";

for (int i = 0; i <= 16; i++)


{
lcd.setCursor(0, 0);
lcd.print(KTAudio.substring(0, i));
delay(50);
}

KTAudio = "VU meter " + main_version;

for (int i = 0; i <= KTAudio.length(); i++)


{
lcd.setCursor(0, 1);
lcd.print(KTAudio.substring(0, i));
delay(50);
}

delay(500);

lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Loading...");

for (int i = 0; i < 16; i++)


{
lcd.setCursor(i, 1);
lcd.write(4);
}

for (int i = 0; i < 16; i++)


{
lcd.setCursor(i, 1);
lcd.write(1);

delay(50);
}

delay(500);
lcd.clear();

decayTime = millis();
}

void loop()
{
actualMillis = millis();

lcd.setCursor(0, 0); //L channel index


lcd.write(2); //L symbol
lcd.setCursor(0, 1); //R channel index
lcd.write(3); //R symbol
lcd.setCursor(15, 0); //closing tag / end mark index 1
lcd.write(5); //closing tag / end mark
lcd.setCursor(15, 1); //closing tag / end mark index 2
lcd.write(5); //closing tag / end mark

totalL = analogRead(inputPinL) / 4 - 128; //reducing the detected


hum and noise

if(totalL > maxL)


{
maxL = totalL;
}

indexL++;

if (indexL >= numReadings)


{
indexL = 0;
left = maxL;
maxL = 0;
}

totalR = analogRead(inputPinR) / 4 - 128; //reducing the detected


hum and noise

if(totalR > maxR)


{
maxR = totalR;
}

indexR++;

if (indexR >= numReadings)


{
indexR = 0;
right = maxR;
maxR = 0;
}

volR = right / 3;

if(volR > 14)


{
volR = 14;
}

if (volR < (rightAvg - 2))


{
if (decayTime < actualMillis)
rightAvg--;

volR = rightAvg;
}
else if (volR > (rightAvg + 2))
{
volR = (rightAvg + 2);
rightAvg = volR;
}
else
{
rightAvg = volR;
}

if (volR > rightPeak)


{
rightPeak = volR;
}

drawBar(volR, rightPeak, 1);

volL = left / 3;

if(volL > 14)


{
volL = 14;
}

if (volL < (leftAvg - 2))


{
if (decayTime < actualMillis)
leftAvg--;

volL = leftAvg;
}
else if (volL > (leftAvg + 2))
{
volL = (leftAvg + 2);
leftAvg = volL;
}
else
{
leftAvg = volL;
}
if (volL > leftPeak)
{
leftPeak = volL;
}

drawBar(volL, leftPeak, 0);

if (decayTime < actualMillis)


decayTime

You might also like