Hackster is hosting Hackster Holidays, Ep. 7: Livestream & Giveaway Drawing. Watch previous episodes or stream live on Friday!Stream Hackster Holidays, Ep. 7 on Friday!
Mirko Pavleski
Published © GPL3+

DIY Arduino VFD display 20x2 VU (Volume Unit) Meter

How to make a VU meter with 38 bars per channel on a modified 20x2 VFD display.

BeginnerFull instructions provided5,605
DIY Arduino VFD display 20x2 VU (Volume Unit) Meter

Things used in this project

Hardware components

Arduino Nano R3
Arduino Nano R3
×1
VFM202MDA1 type VFD Display
×1
Rotary potentiometer (generic)
Rotary potentiometer (generic)
×2
Capacitor 10 µF
Capacitor 10 µF
×2
Resistor 100k ohm
Resistor 100k ohm
×2
1N4007 – High Voltage, High Current Rated Diode
1N4007 – High Voltage, High Current Rated Diode
×2

Software apps and online services

Arduino IDE
Arduino IDE

Hand tools and fabrication machines

Soldering iron (generic)
Soldering iron (generic)
Solder Wire, Lead Free
Solder Wire, Lead Free

Story

Read more

Schematics

Schematic diagram

Code

Arduino code

C/C++
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);// RS,E,D4,D5,D6,D7
byte a1[8]={ 
  0b00000,0b11011,0b11011,0b11011,0b11011,0b11011,0b11011,0b11011};
byte a2[8]={ 
  0b00000,0b11000,0b11000,0b11000,0b11000,0b11000,0b11000,0b11000};
byte a3[8]={
  0b00000,0b00011,0b00011,0b00011,0b00011,0b00011,0b00011,0b00011};
byte znak_r[8]={ // R
  B00000,
  B11100,
  B10010,
  B10010,
  B11100,
  B11000,
  B10100,
  B10010};
byte znak_l[8]={ // L
  B00000,
  B10000,
  B10000,
  B10000,
  B10000,
  B10000,
  B10000,
  B11110};
int u_r,u_l,i=1,x,u_maxr,u_maxl,z,z1,u_r0[19],u_l0[19];
unsigned long time1; 
long decayTime = 0;
void setup(){  
  analogReference(INTERNAL);
  lcd.begin(16, 2);// LCD 16X2
  lcd.createChar(0,a1); 
  lcd.createChar(1,a2); 
  lcd.createChar(2,znak_r); 
  lcd.createChar(3,znak_l);
  lcd.createChar(4,a3); 
  pinMode(A0,INPUT);
  pinMode(A2,INPUT);
    String main_version = "1.2";
    String mircemk = "* mircemk *";  
  
  for (int i = 0; i <= 20; i++)
  {    
    lcd.setCursor(4, 0); 
    lcd.print(mircemk.substring(0, i));
    delay(100);
  }  

  mircemk = "    VU meter " + main_version;
  
  for (int i = 0; i <= mircemk.length(); i++)
  {    
    lcd.setCursor(0, 1);
    lcd.print(mircemk.substring(0, i));
    delay(100);
  }

  delay(500);
  
  lcd.clear();
  lcd.setCursor(5, 0); 
  lcd.print("Loading...");
  
  for (int i = 0; i < 20; i++)
  {
    lcd.setCursor(i, 1); 
    lcd.write(1);

    delay(100);
  }  
    
  delay(5);
  lcd.clear();

  decayTime = millis();
}


void loop(){  
  lcd.setCursor(0,0);// R 
  lcd.write((uint8_t)2);
  lcd.setCursor(0,1);
  lcd.write((uint8_t)3);// L

  u_r = analogRead(A0); // измерение R
  u_l = analogRead(A2); // измерение L

  for(int z=1,z1=0,z2=30;z<=19;z++,z1=z1+30,z2=z2+30){ // l+r
    if(u_l>z1){
      lcd.setCursor(z,1);
      lcd.write((uint8_t)1);
    } 
    if(u_r>z1){
      lcd.setCursor(z,0);
      lcd.write((uint8_t)1);
    } 
    if(u_l>z2){
      lcd.setCursor(z,1);
      lcd.write((uint8_t)0);
    } 
    if(u_r>z2){
      lcd.setCursor(z,0);
      lcd.write((uint8_t)0);
    } 
  }

  i++;
  if(i<=19){
    u_l0[i]=u_l;
    u_r0[i]=u_r;
  }
  else{
    i=1;
  }
  if(i==19){
    u_maxr=0;
    u_maxl=0;
    for(x=1;x<=19;x++){
      u_maxl=max(u_maxl,u_l0[x]);
      u_maxr=max(u_maxr,u_r0[x]);
    }
  }

  if(u_maxl<=u_l){
    u_maxl=u_l;
  } 
  if(u_maxr<=u_r){
    u_maxr=u_r;
  }

  for(z=1,z1=0;z<=19;z++,z1=z1+30){
    if(u_maxl > z1 && u_maxl <= z1+19){
      lcd.setCursor(z,1);
      lcd.write((uint8_t)1);
    }
    if(u_maxl > z1+19 && u_maxl <= z1+30){
      lcd.setCursor(z,1);
      lcd.write((uint8_t)4);
    }

    if(u_maxr > z1 && u_maxr <= z1+19){
      lcd.setCursor(z,0);
      lcd.write((uint8_t)1);
    }
    if(u_maxr > z1+19 && u_maxr <= z1+30){
      lcd.setCursor(z,0);
      lcd.write((uint8_t)4);
    }
  } 
  delay(30);
  lcd.clear();
}

Credits

Mirko Pavleski
154 projects • 1304 followers

Comments