// Show progress bar with the full display width.
// 
// Possible update:
//   Only one custom character would be enough,
//   if it was created in the sketch every time.
//

#include <Wire.h>
#include <LiquidCrystal_I2C.h>

#define LCD_WIDTH 16
LiquidCrystal_I2C lcd( 0x27, LCD_WIDTH, 2);

const int sensorPin = A0;

const byte zero[] = 
{
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000,
  0b00000000
};

const byte one[] = 
{
  0b00010000,
  0b00010000,
  0b00010000,
  0b00010000,
  0b00010000,
  0b00010000,
  0b00010000,
  0b00010000
};

const byte two[] = 
{
  0b00011000,
  0b00011000,
  0b00011000,
  0b00011000,
  0b00011000,
  0b00011000,
  0b00011000,
  0b00011000
};

const byte three[] = 
{
  0b00011100,
  0b00011100,
  0b00011100,
  0b00011100,
  0b00011100,
  0b00011100,
  0b00011100,
  0b00011100
};

const byte four[] = 
{
  0b00011110,
  0b00011110,
  0b00011110,
  0b00011110,
  0b00011110,
  0b00011110,
  0b00011110,
  0b00011110
};

const byte five[] = 
{
  0b00011111,
  0b00011111,
  0b00011111,
  0b00011111,
  0b00011111,
  0b00011111,
  0b00011111,
  0b00011111
};

void setup() 
{
  lcd.init();
  lcd.backlight();
  lcd.createChar( 0, zero);
  lcd.createChar( 1, one);
  lcd.createChar( 2, two);
  lcd.createChar( 3, three);
  lcd.createChar( 4, four);
  lcd.createChar( 5, five);
}


void loop() 
{
  int rawADC = analogRead( sensorPin);
  int progress = map( rawADC, 0, 1023, 0, 100);

  lcd.setCursor( 0, 0);
  lcd.print( progress);          // A number, 0...100
  lcd.print( "  ");              // clear previous text with spaces
 
  updateprogress( progress, 1);  // The first parameter should be a percentage

  delay( 100);                   // 10Hz update rate
}


void updateprogress( int percentage, int lineToPrintOn)
{
  // Total number of pixel horizontal is 16 * 5 (16 characters, 5 per character)
  // When the number of pixels is known, the number of full blocks and
  // the remaining is easy to calculate.
  int pixels = (int) round( float( percentage) / 100.0 * 5 * LCD_WIDTH);
  int fullBlocks = pixels / 5;       // number of characters that are full block
  int remainder = pixels % 5;        // number of pixels within character

  lcd.setCursor( 0, 1);              // second row
  for( int i = 0; i < fullBlocks; i++)
    lcd.write( '\5');                // full block

  lcd.write( remainder);             // write the remaining columns within character

  // Overwrite the rest with spaces to clear previous text
  // The number that is already written are the full blocks plus the remainder
  for( int i = fullBlocks + 1; i < LCD_WIDTH; i++)
    lcd.write( ' ');
}