A bit OT, I know, but...
I wrote some code to display a "progress bar" with pixel resolution rather than character resolution. It uses 5 custom chars.
Here's an example sketch that includes the function and different display styles.
How did you implement your "bars" ?
/*
* Simple "graphical" bar on 5x8 lcd display.
*
* Author: Marcello Romani mromani@ottotecnica.com
*
* Hardware requirements:
* - Arduino 2009 board
* - Nuelectrocnics display shield:
* http://www.nuelectronics.com/estore/index.php?main_page=product_info&cPath=1&products_id=2
* - A standard LCD shield can be used as well, provided you correct the LiquidCrystal pin assignments
*
* Usage:
* - Connect two potentiometers to analog inputs 1 and 2.
* - select the display style by uncommenting the desired display funcion in loop()
*
*/
#include <LiquidCrystal.h>
// pin assignments are for nuelectronics' lcd+keypad shield;
// adjust for other lcd shields
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
// lcd size
const int LCD_NUM_COLS = 16;
const int LCD_NUM_ROWS = 2;
// analog channels to read and display
// change to taste
#define ANALOG_CHANNEL_1 1
#define ANALOG_CHANNEL_2 2
const int ANALOG_POLL_TIME = 100; // unit: ms
const int NUM_VALUES = LCD_NUM_ROWS;
const int MAX_VALUE = 1023;
const int MIN_VALUE = 0;
int value[NUM_VALUES];
const int channels[NUM_VALUES] = { ANALOG_CHANNEL_1, ANALOG_CHANNEL_2 };
// custom characters for progress bar generation
byte graph0[8] = {
B00000,
B00000,
B00000,
B00000,
B00000,
B00000,
B00000,
B00000,
};
byte graph1[8] = {
B10000,
B10000,
B10000,
B10000,
B10000,
B10000,
B10000,
B10000,
};
byte graph2[8] = {
B11000,
B11000,
B11000,
B11000,
B11000,
B11000,
B11000,
B11000,
};
byte graph3[8] = {
B11100,
B11100,
B11100,
B11100,
B11100,
B11100,
B11100,
B11100,
};
byte graph4[8] = {
B11110,
B11110,
B11110,
B11110,
B11110,
B11110,
B11110,
B11110,
};
byte graph5[8] = {
B11111,
B11111,
B11111,
B11111,
B11111,
B11111,
B11111,
B11111,
};
void createCustomChars() {
lcd.createChar(0, graph0);
lcd.createChar(1, graph1);
lcd.createChar(2, graph2);
lcd.createChar(3, graph3);
lcd.createChar(4, graph4);
lcd.createChar(5, graph5);
}
//
// draw a horizontal bar on the display
// using custom chars 0..4
//
// row = number of row to draw to (0 or 1)
// maxChars = maximum bar lenght, in number of display characters
// value = raw value to display
// minValue, maxValue = minimum and maximum value for the value parameter
//
void drawBar(LiquidCrystal* lcdObj, int col, int row, int maxChars, int value, int minValue, int maxValue) {
// character width in number of pixels
static const int pixelsPerChar = 5;
// maximum bar width in pixels
int maxPixels;
// calculated actual bar width
int numPixels;
// number of full chars to draw
int q;
// number of pixels in the last char
int r;
// counter
int i;
maxPixels = maxChars * pixelsPerChar;
numPixels = map(value, minValue, maxValue, 0, maxPixels);
q = numPixels / pixelsPerChar;
r = numPixels % pixelsPerChar;
/*
// debug over serial line
Serial.println("----");
Serial.println(value);
Serial.println(maxPixels);
Serial.println(numPixels);
Serial.println(q);
Serial.println(r);
*/
lcdObj->setCursor(col, row);
// always redraw the full bar to erase the previous one
for (i = 0; i < maxChars; i++) {
if (i < q) {
lcdObj->write(5); // full char
}
else if (i == q) {
lcdObj->write(r); // last char
}
else {
lcdObj->write(0); // erase any previous chars
}
}
}
// read the analog channels
void updateValues() {
int i;
for (i = 0; i < NUM_VALUES; i++) {
value[i] = analogRead(channels[i]);
}
}
// two orizontal bars
void updateDisplay0() {
int i;
for (i = 0; i < NUM_VALUES; i++) {
drawBar(&lcd, 0, i, LCD_NUM_COLS, value[i], MIN_VALUE, MAX_VALUE);
}
}
// two horizontal bars with raw analog values on the right
void updateDisplay1() {
static char buf[10];
int i;
for (i = 0; i < NUM_VALUES; i++) {
drawBar(&lcd, 0, i, LCD_NUM_COLS - 4, value[i], MIN_VALUE, MAX_VALUE);
sprintf(buf, "%4d", value[i]);
lcd.setCursor(LCD_NUM_COLS - 4, i);
lcd.print(buf);
}
}
// two horizontal bars with raw analog values on the left
void updateDisplay2() {
static char buf[10];
int i;
for (i = 0; i < NUM_VALUES; i++) {
drawBar(&lcd, 4, i, LCD_NUM_COLS - 4, value[i], MIN_VALUE, MAX_VALUE);
sprintf(buf, "%4d", value[i]);
lcd.setCursor(0, i);
lcd.print(buf);
}
}
// two horitonal bars with raw analog values beneath them
void updateDisplay3() {
static char buf[10];
int i;
for (i = 0; i < NUM_VALUES; i++) {
drawBar(&lcd, i*(LCD_NUM_COLS/2), 0, LCD_NUM_COLS/2, value[i], MIN_VALUE, MAX_VALUE);
sprintf(buf, "%8d", value[i]); // NOTE: field width must be equal to LCD_NUM_COLS/2
lcd.setCursor(i*(LCD_NUM_COLS/2), 1);
lcd.print(buf);
}
}
void setup() {
// this is required only for debug
//Serial.begin(115200);
// initialize lcd library
lcd.begin(LCD_NUM_COLS, LCD_NUM_ROWS);
// create required custom chars
createCustomChars();
}
void loop() {
// read the analog values
updateValues();
// uncomment only one of these:
//updateDisplay0();
//updateDisplay1();
//updateDisplay2();
updateDisplay3();
// don't write too fast to the lcd...
delay(ANALOG_POLL_TIME);
}