So you have been using an LCD for sometime and now have the need to create a custom character / symbol... How do you do it?
(Please check this before proceeding -
)
Before getting onto it, lets understand how an LCD displays characters. If you notice, each character on a LCD display typically is inside a small 5 Rows x 8 Columns array of dots. Depending upon the character to be displayed, the required dots are turned On / Off. Most LCD's come pre-configured to display standard characters. Each character has a definition matrix, which defines which dots are to be On and which dots are to be Off.
Here's an image that will help you understand better. Here's a Custom Smiley and its corresponding Binary definition
Here's how we will define a BYTE variable to hold the definition for the above Character. If you look at it the first row above is stored in the 0th index of the array mySmiley.
byte mySmiley[8] = {
0b00000,
0b01010,
0b01010,
0b01010,
0b00000,
0b10001,
0b01110,
0b00000
};
if Binary is not your game, you can use the below image, to find the decimal equivalent. (both images are using different characters - so use your common sense ;) )
So we can rewrite the definition in decimal as follows
byte mySmiley[8] = { 0, 10,10,10,0,17,14,0};
Here's a simple program to display the Smiley on your LCD
Here's the Program
/* Induino R3 User Guide - Program 20.0 - LCD Interfacing - Creating Custom Characters on a 16x2 LCD using the Induino R3 */
/* This program uses the Simple Labs LCD Shield, 16x2 LCD from Simple Labs and the Induino R3 Board. Change the pin numbers according your own hardware */
#include <LiquidCrystal.h> //Include the LCD Header
// initialize the lcd
LiquidCrystal lcd(8, 9,10, 11, 12,13);
byte mySmiley[8] = {0,10,10,10,0,17,14,0}; // Define the Smiley Character
void setup()
{
// add the mySmiley Character to the 0th Location of the LCD's CGRAM
// 0-7 are possible values here
lcd.createChar(0, mySmiley);
// set up number of columns and rows
lcd.begin(16, 2);
// Write out Smiley Character.
// Type casting is required as we are directly mentioning a value
lcd.write((uint8_t)0);
}
void loop()
{
}
Now lets play around by creating a set of 8 Characters, each representing a line at a different height (see the output to get a clear understanding)
byte line_0[8] = { 0,0,0,0,0,0,0,31};
byte line_1[8] = { 0,0,0,0,0,0,31,0};
byte line_2[8] = { 0,0,0,0,0,31,0,0};
byte line_3[8] = { 0,0,0,0,31,0,0,0};
byte line_4[8] = { 0,0,0,31,0,0,0,0};
byte line_5[8] = { 0,0,31,0,0,0,0,0};
byte line_6[8] = { 0,31,0,0,0,0,0,0};
byte line_7[8] = { 31,0,0,0,0,0,0,0};
Now the above definition can be optimized by making it an array, so we can redefine it as
byte line[8][8]={
{ 0,0,0,0,0,0,0,31},
{ 0,0,0,0,0,0,31,0},
{ 0,0,0,0,0,31,0,0},
{ 0,0,0,0,31,0,0,0},
{ 0,0,0,31,0,0,0,0},
{ 0,0,31,0,0,0,0,0},
{ 0,31,0,0,0,0,0,0},
{ 31,0,0,0,0,0,0,0}
};
Here's the Program
/* Induino R3 User Guide - Program 20.1 - LCD Interfacing - Creating Custom Characters on a 16x2 LCD using the Induino R3 */
/* This program uses the Simple Labs LCD Shield, 16x2 LCD from Simple Labs and the Induino R3 Board. Change the pin numbers according your own hardware */
#include <LiquidCrystal.h> //Include the LCD Header
// initialize the lcd
LiquidCrystal lcd(8, 9,10, 11, 12,13);
byte mySmiley[8] = {0,10,10,10,0,17,14,0}; // Define the Smiley Character
void setup()
{
// add the custom characters to the LCD's CGRAM
lcd.createChar(0, mySmiley);
// set up number of columns and rows
lcd.begin(16, 2);
// Write out the custom Characters
// Type casting is required as we are directly mentioning a value
lcd.write((uint8_t)0);
}
void loop()
{
}
First we redefine the Character Array
byte line[8][8]={
{ 0,0,0,0,0,0,0,31}, // Level 1
{ 0,0,0,0,0,0,31,31}, // Level 2
{ 0,0,0,0,0,31,31,31}, // Level 3
{ 0,0,0,0,31,31,31,31}, // Level 4
{ 0,0,0,31,31,31,31,31}, // Level 5
{ 0,0,31,31,31,31,31,31}, // Level 6
{ 0,31,31,31,31,31,31,31}, // Level 7
{ 31,31,31,31,31,31,31,31} // Level 8
};
Here's the Program
/* Induino R3 User Guide - Program 20.2 - LCD Interfacing - Creating Custom Characters on a 16x2 LCD using the Induino R3 */
/* This program creates a series of Bar Graph Characters- an experimentation with custom characters */
#include <LiquidCrystal.h> //Include the LCD Header
// initialize the lcd
LiquidCrystal lcd(8, 9,10, 11, 12,13);
// Define the Characters for creating a Bar Graph with Various Levels
byte line[8][8]={
{ 0,0,0,0,0,0,0,31}, // Level 1
{ 0,0,0,0,0,0,31,31}, // Level 2
{ 0,0,0,0,0,31,31,31}, // Level 3
{ 0,0,0,0,31,31,31,31}, // Level 4
{ 0,0,0,31,31,31,31,31}, // Level 5
{ 0,0,31,31,31,31,31,31}, // Level 6
{ 0,31,31,31,31,31,31,31}, // Level 7
{ 31,31,31,31,31,31,31,31} // Level 8
};
void setup()
{
// add the custom characters to the LCD's CGRAM
for(int i =0; i <8; i++)
{
lcd.createChar(i, line[i]);
}
// set up number of columns and rows
lcd.begin(16, 2);
}
void loop()
{
// Show the Bar Graph Characters as increasing
for(int i =0; i <8; i++)
{
// Print the Bar Graph Character on the First Line
lcd.setCursor(i,0);
lcd.write(i);
// Print the Corresponding value on the Second Line
lcd.setCursor(i,1);
lcd.print(i);
delay(1000);
}
delay(1000);
// Clear the display
lcd.clear();
}
Here's the Program
/* Induino R3 User Guide - Program 20.3 - LCD Interfacing Custom Characters- Displaying the LDR Value as a Single Bar Graph Character Induino R3 */
/* This program creates a series of Bar Graph Characters- an experimentation with custom characters */
#include <LiquidCrystal.h> //Include the LCD Header
// initialize the lcd
LiquidCrystal lcd(8, 9,10, 11, 12,13);
// Define the Characters for creating a Bar Graph with Various Levels
byte line[8][8]={
{ 0,0,0,0,0,0,0,31}, // Level 1
{ 0,0,0,0,0,0,31,31}, // Level 2
{ 0,0,0,0,0,31,31,31}, // Level 3
{ 0,0,0,0,31,31,31,31}, // Level 4
{ 0,0,0,31,31,31,31,31}, // Level 5
{ 0,0,31,31,31,31,31,31}, // Level 6
{ 0,31,31,31,31,31,31,31}, // Level 7
{ 31,31,31,31,31,31,31,31} // Level 8
};
void setup()
{
// add the custom characters to the LCD's CGRAM
for(int i =0; i <8; i++)
{
lcd.createChar(i, line[i]);
}
// set up number of columns and rows
lcd.begin(16, 2);
}
void loop()
{
// Read the LDR Value and store it in a variable
int val = analogRead(3);
// Map the analog value from the sensor to a scale of 0 to 7 (8 Levels)
val = map(val, 0, 1023, 0, 7);
// Print the numerical value to the LCD
lcd.setCursor(0,1);
lcd.print(val);
//set the cursor
lcd.setCursor(0,0);
// Write the Bar Graph Level Value corresponding to the Value of the LDR
lcd.write(val);
delay(100);
lcd.clear();
}
Now Having a static Bar is not much fun, lets convert this into a realtime BAR graph. A Running Bar Graph based on the last 16 values of the sensor. 16 Values as we can display only 16 characters per line.
/* Induino R3 User Guide - Program 20.4 - LCD Interfacing Custom Characters- Displaying the LDR Value as a Running Bar Graph using the Induino R3 */ /* This program creates a series of Bar Graph Characters- an experimentation with custom characters */ #include <LiquidCrystal.h> //Include the LCD Header // initialize the lcd LiquidCrystal lcd(8, 9,10, 11, 12,13); // Define the Characters for creating a Bar Graph with Various Levels byte line[8][8]={ { 0,0,0,0,0,0,0,31}, // Level 1 { 0,0,0,0,0,0,31,31}, // Level 2 { 0,0,0,0,0,31,31,31}, // Level 3 { 0,0,0,0,31,31,31,31}, // Level 4 { 0,0,0,31,31,31,31,31}, // Level 5 { 0,0,31,31,31,31,31,31}, // Level 6 { 0,31,31,31,31,31,31,31}, // Level 7 { 31,31,31,31,31,31,31,31} // Level 8 }; // a variable array to store the last 16 values of the sensor int hist_val[16]; // to count the first 16 values int cnt = 0; void setup() { // add the custom characters to the LCD's CGRAM for(int i =0; i <8; i++) { lcd.createChar(i, line[i]); } // set up number of columns and rows lcd.begin(16, 2); } void loop() { // Read the LDR Value and store it in a variable int val = analogRead(3); // Map the analog value from the sensor to a scale of 0 to 7 (8 Levels) val = map(val, 0, 1023, 0, 7); lcd.setCursor(0,0); lcd.print(val); // Check if cnt is less than 16, if it is less than 16, we need to increment it // we also need to store the values of the sensor for the first 16 counts if(cnt<16) { hist_val[cnt] = val; // Increment cnt cnt++; } else // if count is greater than 16, we need to push out the oldest of the values and add the latest value to the set of 16 values. // the oldest value will be stored in the 0th array index and the latest value in the 15th array index // in addition, we also need to move up all other historic values by one position { // do the moving up of the historic values for(int j=0; j<15;j++) hist_val[j] = hist_val[j+1]; // store the latest value in the last position hist_val[15] = val; } // Displaying the Values as a Running Bar Graph for(int i=0; i<cnt; i++) { lcd.setCursor(i,0); lcd.write(hist_val[i]); /* lcd.setCursor(i,1); lcd.print(hist_val[i]); */ delay(10); } }
Thats It For This Part! Enjoy... and feel free to drop us an email with questions you might have -> info@simplelabs.co.in
Visit www.simplelabs.co.in for more interesting products
Visit www.simplelabs.co.in for more interesting products