#include <LiquidCrystal.h>
//make 5 custom characters that fill in a character space from left to right
//to give more progressive bar graph
// encodes numbers from 0 to 255
unsigned char bars[][8] =
{
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, //_____
{ 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10 }, //|____
{ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18 }, //||___
{ 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c }, //|||__
{ 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e }, //||||_
{ 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f } //|||||
};
int Vpin = A0; // defines input pin A0
int
nReading,
nlastReading;
float V; // this data type allows the analog number with decimal point, V, to be accurately approximated
//internal representation of the bar
byte
grBar[16];
const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2; //these values cannot be changed, follows scope rules
LiquidCrystal lcd(rs, en, d4, d5, d6, d7); // sets the LCD address display (must be before void setup)
void setup()
{
// first, set dimensions of LCD, in setup() as lcd.begin(columns, rows)
lcd.begin(16, 2);
//using the arrays above to create 5 custom characters representing fractional fills for the bar graph
for( int i=0; i<6; i++ )
lcd.createChar( i, bars[i] );
lcd.setCursor(0,0); //col,row
lcd.print("Voltage= ");
//Serial.begin(9600); //debug/dev opens serial port, sets data rate to 9600 bps
nlastReading = 0;
}//setup
void loop()
{
static unsigned long
timeUpdate = 0;
unsigned long
timeNow;
timeNow = millis();
if( timeNow - timeUpdate >= 100 ) //update frequently (10 times a second) for smooth bar graph
{
timeUpdate = timeNow;
nReading = analogRead( Vpin ); // reads the input pin, A0
//only update if current reading not the same as last
//Compares the variable on the left with the value or variable on the right of the operator. Returns true when the two operands are not equal.
if( nReading != nlastReading )
{
nlastReading = nReading;
V = (float)nReading*5.0/1024.0;
lcd.setCursor( 8, 0 );
lcd.print( V, 2 );
//Serial.println( V ); //debug/dev
//draw the bar graph
UpdateBar( V );
}//if
}//if
}//loop
void UpdateBar( float volts )
{
int
i,
numBlanking,
numfullbars;
float
fnumSubBars;
//draw the bar graph in its entirety
//assume that full scale voltage reading is 3.7V and that this equates to 15 full bars
// if volts = 0.45
// # of full bars = (int)(0.45 * 13.6364) = (int)(6.136) = 6
//
// The remainder will be used to fractionally fill the next bar
// Our character set allows up to 5 "sub-bars"
// the remainder of the # full bars calc
// multiplier: 0.9 * x = 5; x = 5.5
// 5.5 * ((volts * 13.6364) - numfullbars )
// 5.5 * (6.136 - 6)
// 5.5 * 0.136 = 0.750 (int = 4)
//
//
if( volts > 1.1 )
volts = 1.1;
numfullbars = (int)(volts * 13.6364); //number of "full" bars (custom char #5)
fnumSubBars = 5.5 * ((volts * 13.6364) - numfullbars ); //last char is 0-5, custom char for partial fill of last bar
if( numfullbars < 15 )
numBlanking = 15 - numfullbars - 1;
else
numBlanking = 0;
//erase the array representing the bar by setting custom char 0 (blank)
memset( grBar, 0, sizeof( grBar ) );
//draw in the number of full bars using character 5
for( i=0; i<numfullbars; i++ )
grBar[i] = 5;
//in the last active bar, add the sub-bar value
grBar[i] = (byte)fnumSubBars;
//draw the bar to the LCD
lcd.setCursor( 0, 1 );
for( i=0; i<sizeof( grBar ); i++ )
{
lcd.write( grBar[i] );
//Serial.print( grBar[i] ); //debug/dev
}//for
//Serial.println(); //debug/dev
}//DoBar