marcocroce
Published © GPL3+

"Mechanical" VU Meter

A simple VU meter realized with only mechanical typical items, as screws or nuts, but powered by Arduino!

BeginnerFull instructions provided4,439
"Mechanical" VU Meter

Things used in this project

Hardware components

Arduino UNO
Arduino UNO
×1
RGB LCD Shield Kit, 16x2 Character Display
RGB LCD Shield Kit, 16x2 Character Display
×1
Breadboard (generic)
Breadboard (generic)
×1
Resistor 330 ohm
Resistor 330 ohm
×1
Rotary potentiometer (generic)
Rotary potentiometer (generic)
×1
Machine Screw, M2.5
Machine Screw, M2.5
×12
Connector Accessory, Hex Nut
Connector Accessory, Hex Nut
×2
Male/Female Jumper Wires
Male/Female Jumper Wires
×15
Male/Male Jumper Wires
×2
Jumper wires (generic)
Jumper wires (generic)
×3

Software apps and online services

Arduino IDE
Arduino IDE

Hand tools and fabrication machines

Multitool, Screwdriver
Multitool, Screwdriver

Story

Read more

Custom parts and enclosures

Case with cover (AutoCAD project)

Schematics

Schematics and circuit diagrams of Mechanical VUMETER - PDF

Code

VU.ino

Arduino
/*
   Mechanical VU meter
   Author: Marco Croce
   Version: 1.0 - 09/2021
*/

// library used for the LCD display
#include <LiquidCrystal.h>

/*
   Bit / Pixel Mapping to create the letters
   and the symbols to show on the display
*/

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

byte c1[8] = {
  B11111,
  B00000,
  B10000,
  B10000,
  B10000,
  B10000,
  B00000,
  B11111
};

byte c2[8] = {
  B11111,
  B00000,
  B11000,
  B11000,
  B11000,
  B11000,
  B00000,
  B11111
};

byte c3[8] = {
  B11111,
  B00000,
  B11100,
  B11100,
  B11100,
  B11100,
  B00000,
  B11111
};

byte c4[8] = {
  B11111,
  B00000,
  B11110,
  B11110,
  B11110,
  B11110,
  B00000,
  B11111
};

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

byte C[8] = {
  B11100,
  B11110,
  B11111,
  B11111,
  B11111,
  B11111,
  B11110,
  B11100
};

byte R[8] = {
  B00000,
  B11110,
  B10001,
  B10001,
  B11110,
  B10100,
  B10010,
  B10001
};

byte L[8] = {
  B00000,
  B10000,
  B10000,
  B10000,
  B10000,
  B10000,
  B10000,
  B11111
};

// Set the LCD's pin number through the constructor
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
// Range of dB values
int valori[] = {-75, -50, -40, -30, -20, 0, 5, 10};

/*
   Variables:
   - valore -> The value of volts read using Arduino
   - i -> A simple counter
   - dbVU -> The value of dbVU obtained by valore
   - livello -> A counter for the rectangles of the VU Meter
 */
int valore = 0, i = 0;
double dbVU;
int livello;

void setup()
{
// set up the LCD's number of columns and rows
  lcd.begin(16, 2);
// set up the pin from which to read the value
  pinMode(A1, INPUT);

/*
   Creation of the custom characters to be used
   on the display
*/
  lcd.createChar(1, c1);
  lcd.createChar(2, c2);
  lcd.createChar(3, c3);
  lcd.createChar(4, c4);
  lcd.createChar(5, c5);
  lcd.createChar(6, c0);
  lcd.createChar(7, C);
  lcd.createChar(8, L);
  lcd.createChar(9, R);

// Loading initial screen
  lcd.setCursor(0, 0);
  lcd.print("    VU METER    ");
  delay(500);

// Loading line
  for ( livello = 0; livello < 16; livello++ )
  {
    lcd.setCursor(livello, 1);
    lcd.write(5);
    delay(100);
  }

  delay(500);

  lcd.clear();
  
  delay(500);

}

void loop()
{
// Letter L - LEFT
  lcd.setCursor(0,0);
  lcd.write(8);
// Letter R - RIGHT
  lcd.setCursor(0,1);
  lcd.write(9);

// Delimitation symbol C
  lcd.setCursor(15,0);
  lcd.write(7);
  lcd.setCursor(15,1);
  lcd.write(7);

  delay(100);

// Voltage reading from the pin A1
  do
  {
    valore = analogRead(A1);
  } while ( valore <= 5 );

/*
   1) valore*0.0049 -> Arduino reads 4.9 mV to unit, so this is 
   the conversion to volt
   More info at: https://www.arduino.cc/reference/it/language/functions/analog-io/analogread/
   2) valore*0.0049/1.2 -> 1.2 represents the value of SOL ( Standard Operative Level ), used
   to indicate the maximum level to avoid the saturation, for VU Meter is 1.2 Volt
   3) 20*log( valore*0.0049/1.2 ) -> This is the formula to converts values from volt to 
   db for VU Meter, dbVU
 */
  dbVU = (log10((double)valore*0.0049/1.2))*20;

  // Setting the new rectangles
  for (int i = 0, livello = 1; i < 7; i++) {
    if (valori[i] < dbVU) {
      lcd.setCursor(livello, 0);
      lcd.write(5);
      lcd.setCursor(livello++, 1);
      lcd.write(5);
      delay(50);
      lcd.setCursor(livello, 0);
      lcd.write(5);
      lcd.setCursor(livello++, 1);
      lcd.write(5);
    }
  }

  // Removing the old rectangles
  for (int i = 7, livello = 14; i > 0; i--) {
    if (valori[i] > dbVU) {
      lcd.setCursor(livello, 0);
      lcd.write(6);
      lcd.setCursor(livello--, 1);
      lcd.write(6);
      delay(50);
      lcd.setCursor(livello, 0);
      lcd.write(6);
      lcd.setCursor(livello--, 1);
      lcd.write(6);
    }
  }

  delay(100);

}

Github Repository - VU_Meter

Credits

marcocroce

marcocroce

1 project • 3 followers

Comments