I tried to cover a ton in this tutorial. I’ll show how to use LCD Panels with Arduino. I then live code Conway’s Game of Life using an Arduino and a LCD Panel. Along the way we’ll create custom characters, convert from binary to base 10, generate random arrays, copy arrays and a whole lot more. I hope these functions will be useful in numerous personal projects you may have.
All of the code and a transcript follows the video below.
If you like videos like this, consider donating $1, or simply turn off Ad Blocking software. Either helps me pay for books and components I use to make these videos.
Code from the Video
// ----- DEMONSTRATES HOW LCD PANELS WORK -----
// Used to work with the LCD display
#include <LiquidCrystal.h>
// Setup the display by designating the pins used
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
// Will draw a heart on the LCD display
// each number represents those leds lit on each row
// 00011 = 3 which means the last 2 leds are on
byte heart[8] = {0, 10, 31, 31, 31, 14, 4, 0};
void setup() {
Serial.begin(9600);
// State that the display has 2 rows with 16
// characters per row
lcd.begin(16, 2);
// Create the heart character
lcd.createChar(0, heart);
// Move the cursor into position on the 1st line
lcd.setCursor(0, 0);
// Print to the LCD
lcd.print("I ");
// Print the heart
lcd.write(byte(0));
lcd.print(" LCDs");
}
void loop() {
}
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
// Size we will use on the LCD panel
const int maxRows = 16;
const int maxCols = 20;
// Equals (maxCols/5) * 2
const int numOfChars = (maxCols/5) * 2;
/* Gameboard generated for 1 character looks like this
0 0 1 0 0
1 1 0 0 0
0 1 1 1 1
1 1 0 0 0
1 0 0 1 0
1 0 0 1 0
0 0 1 1 1
1 0 1 0 1
*/
bool gameBoard[maxRows][maxCols] = {};
/* To print a character to the LCD we pass a number
* that represents each row
* This represents the character above
4, 24, 15, 24, 18, 18, 7, 21
*/
byte golArray[numOfChars][8] = {};
// Will generate the values that go in the golArray
// by adding the values in the binary value while
// converting to base ten by multiplying versus
// these values 16, 8, 4, 2, 1
int GetLEDRowValue(byte ledRow, byte maxColumn){
// Get the 1st columns index using the max as a guide
int minColumn = maxColumn - 4;
// Will hold the 5 digit value which represents which lights
// to turn on for each row which makes up the character
int ledValue = 0;
// Each time through multiply times 1, 2, 4, 8, 16 to convert
// from binary
int multiplier = 1;
// Cycle through each binary value and convert to base 10
for(int i = maxColumn; i >= minColumn; i--){
ledValue += (gameBoard[ledRow][i] * multiplier);
multiplier *= 2;
}
return ledValue;
}
// Generate the 8 values that make up each character for each
// row that will be printed to the LCD display
void GenerateGolArray(){
// The max column is 4 because the indexes go from 0 - 4
// for each 5 digit line
int maxCol = 4;
for(int i = 0; i < numOfChars/2; i++){
for(int j = 0; j < 8; j++){
golArray[i][j] = GetLEDRowValue(j, maxCol);
}
// Jump to the next character to create
maxCol += 5;
}
// Used for the 2nd row of characters to print
maxCol = 4;
for(int i = (numOfChars/2); i < numOfChars; i++){
for(int j = 0; j < 8; j++){
golArray[i][j] = GetLEDRowValue(j+(numOfChars/2), maxCol);
}
maxCol += 5;
}
}
// Create an array of 1s and 0s
void GenerateRandomArray(){
randomSeed(analogRead(0));
for(int a = 0; a < maxRows; a++){
for(int b = 0; b < maxCols; b++){
gameBoard[a][b] = random(0,2);
}
}
}
// Get the character data from the GOL array and print them
// on the LCD panel
void PrintChar(int charNum, int LCDCol, int LCDRow){
// Get pointer to the array holding the character
// data array
byte* temp = golArray[charNum];
// Create character with the character number
// and the character array data
lcd.createChar(charNum, temp);
// Put cursor in the right row and column and print
lcd.setCursor(LCDCol,LCDRow);
lcd.write(byte(charNum));
}
// Cycle through all characters to print on both rows of the LCD
// and print them with PrintChar()
void PrintToLCD(){
int startCol = 0;
for(int i = 0; i < (numOfChars/2); i++){
// Print row 1 on LCD
PrintChar(i, startCol, 0);
// Print row 2 on LCD
PrintChar(i + (numOfChars/2), startCol, 1);
startCol++;
}
}
// Make a copy of the array for updating the board
void CopyArray(bool gameBoard2[maxRows][maxCols]){
for(int a =0; a < maxRows; a++)
{
for(int b = 0; b < maxCols; b++)
{
gameBoard2[a][b] = gameBoard[a][b];
}
}
}
// Any living cell with < 2 neighbores dies
// Any living cell with 2 or 3 neighbores lives
// Any living cell with > 3 neighbores dies
// A dead cell with exactly 3 neighbores is born
void UpdateBoard(){
bool gameBoard2[maxRows][maxCols] = {};
// Make a copy of the array
CopyArray(gameBoard2);
// Cycle through the columns of the array down
for(int a = 0; a < maxRows; a++)
{
// Cycle through the rows of the array across
for(int b = 0; b < maxCols; b++)
{
// We assume the cell is dead
int numOfTrues = 0;
// Used to check the value above and below the cell
for(int c = -1; c < 2; c++)
{
// Used to check the value to the left and right of the cell
for(int d = -1; d < 2; d++)
{
// If we aren't checking the cell itself
if(!(c == 0 && d == 0))
{
// Each time their is a true on the top, bottom,
// right and left of the cell increment numOfTrues
if(gameBoard2[a+c][b+d])
{
++numOfTrues;
}
}
}
}
// If their are less then 2 trues around the cell mark it as dead
if(numOfTrues < 2){gameBoard[a][b] = false;}
// If their is exactly 3 live cells mark it as alive
else if(numOfTrues == 3){gameBoard[a][b] = true;}
// If their are more then 3 live cells mark it as dead
else if(numOfTrues > 3){gameBoard[a][b] = false;}
}
}
}
void setup() {
Serial.begin(9600);
lcd.begin(16, 2);
GenerateRandomArray();
GenerateGolArray();
PrintToLCD();
}
void loop() {
delay(500);
UpdateBoard();
GenerateGolArray();
PrintToLCD();
}