unuseful project: VU-meter with 16x2 lcd display

hi all
today when play with my new toy, a 16x2 lcd display with HD44780 chipset, i wrote this simple sketch for joke.
it is a stereo vu-meter with peak detect.
it draw 2 orizontal bar with 16*5 = 80 segments.
i will never use this sketch in real application, and i think you too, but it is very nice to see :slight_smile:

/* 
 * Simple 2-channel VU-meter with peak detect - by mira308sw - 2013
 * a crazy sketch for 16x2 lcd display
 */

#include <LiquidCrystal.h>

/* Modify the pin number below to meet your board
 */
#define IN_LEFT    4  // analog input for left channel
#define IN_RIGHT   5  // analog input for right channel

LiquidCrystal lcd( 8,  // RS
                   9,  // E
                   4,  // DB4
                   5,  // DB5
                   6,  // DB6
                   7   // DB7
                   );

/* Other minor configurable value
 */
#define T_REFRESH    100            // msec bar refresh rate
#define T_PEAKHOLD   3*T_REFRESH    // msec peak hold time before return

/* local variable
 */
byte  fill[6]={ 0x20,0x00,0x01,0x02,0x03,0xFF };      // character used to fill (0=empty  5=full)
byte  peak[7]={ 0x20,0x00,0x04,0x05,0x06,0x07,0x20 }; // character used to peak indicator
int   lmax[2];                                        // level max memory
int   dly[2];                                         // delay & speed for peak return

void  bar  ( int row,int lev )
{
  lcd.setCursor( 0,row );
  lcd.write( row ? 'R' : 'L' );
  for( int i=1 ; i<16 ; i++ )
  {
    int f=constrain( lev      -i*5,0,5 );
    int p=constrain( lmax[row]-i*5,0,6 );
    if( f )
      lcd.write( fill[ f ] );
    else
      lcd.write( peak[ p ] );
  }
  if( lev>lmax[row] )
  {
    lmax[row] = lev;
    dly[row]  = -(T_PEAKHOLD)/T_REFRESH;                // Starting delay value. Negative=peak don't move
  }
  else
  {
    if( dly[row]>0 )
      lmax[row] -= dly[row]; 

    if( lmax[row]<0 )
      lmax[row]=0;
    else
      dly[row]++;
  }
}

byte block[8][8]=
{
  { 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10 },  // define character for fill the bar
  { 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18 },
  { 0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C },
  { 0x1E,0x1E,0x1E,0x1E,0x1E,0x1E,0x1E,0x1E },

  { 0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08 },  // define character for peak level
  { 0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04 },
  { 0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02 },
  { 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01 },
};

void  setup  ( void )
{
  lcd.begin( 16,2 );
  for( int i=0 ; i<8 ; i++ )
    lcd.createChar( i,block[i] );
}

long  lastT=0;

void  loop  ( void )
{
  if( millis()<lastT )
    return;
  lastT += T_REFRESH;    
  int anL = map( sqrt( analogRead( IN_LEFT  )*16 ),0,128,0,80 );  // sqrt to have non linear scale (better was log)
  int anR = map( sqrt( analogRead( IN_RIGHT )*16 ),0,128,0,80 );
  bar( 0,anL );
  bar( 1,anR );
}

Not as unusefull as you write , because I'll Use It for future project , and it's work !!

I think that the ground of the audio signal should be wire to the ground of the citcuit , am I right ?

Dj_Garfield:
I think that the ground of the audio signal should be wired to the ground of the circuit?

Always.

Dj_Garfield:
Not as unusefull as you write , because I'll Use It for future project , and it's work !!

I think that the ground of the audio signal should be wire to the ground of the citcuit , am I right ?

Yes, ground of input source connected to arduino ground, and also all you wish to translate you input signal to 0_5v range.
In my test i used a simple wave rectfier, followed by a RC net.

Good :slight_smile: Thank you .

With a lot of good information found here , I learn faster :slight_smile:

( 2 weeks ago I never though I was able to understand and use all those information since I start a dashboard project , arduino based , with LCD , and many shields . )

I think that the ground of the audio signal should be wire to the ground of the citcuit

mira308sw thank you very much for the code, it was really nice to finnally be able to make my Power meter with an average bar graph display, I adapted a bit your code but it works very nicely.

I would like to ask you if you could help me to display the values that the bar graph is moving but also I would also like to show the power peaks and the average power because when just printing on the LCD the measured power, as the power moves continuouslly, one cannot really see the number it is showing.

Thanks so much