Overview:
In our first tutorial about 128 X 64 LCD module, we used a 10k potentiometer to adjust its contrast, displayed text, and even flashed our favorite cartoon character images.
In this tutorial, we will be adding tactile push button switches to our project so we can play the iconic and classic SNAKE GAME that many 90's kids enjoyed. This tutorial shows the versatility of the 128 X 64 LCD module. Yes! It is used in many devices to display data and controls, but it can also be used in recreational activities.
Hardware:
Arduino Uno x 1
128 x 64 Graphical LCD x 1
Tactile Push Button x 5
10k Resistors x 1
10k Potentiometer x 1
Breadboard x1
Connecting wires
Software:
Arduino IDE
Application Discussion:
In the first project, we have used a potentiometer where a knob is turned clockwise or anti-clockwise, and the LCD’s contrast changed. For our second tutorial, we're going to take advantage of the size of the ST7920 128X64 GLCD by playing one of the classic 90s childhood games, a basic SNAKE GAME.
We will use five tactile push button switches, the first four buttons will be used to control the movement of the snake: UP, DOWN, LEFT, RIGHT. The remaining one will be used to reset the game once you have touched the four edges of the screen or the snake itself.
Tactile Push Button Switch
Tactile push button essentially completes an electric circuit once you press or click on it. These are usually built as metal or thermoplastic.
When it's on, a small metal spring inside makes contact with two wires, allowing electricity to flow in the system.
There are types of push button switches, namely momentary and non-momentary.
Momentary switches only work as long as you push them, like buttons on phone, keyboard, or buzzer.
Non-momentary switches take one push to turn on, another to turn off like on/off button from tv remote control or from your cellphones. They kind of latch from the previous state.
If you want to learn more applications of the push button, click here!
ST7920 128X64 GLCD
128 x 64 LCD is a display device that can be used in embedded systems for displaying data, image, custom characters and even play games!
There are 20 pins in the 128 X 64 GLCD. Here are the following symbol and description with its function.
Symbol |
Description |
Function |
VSS |
Ground |
0V |
VDD |
Power Supply for Logic Circuit |
+5V |
VO |
LCD Contrast Adjustment |
Contrast Control |
RS |
Instruction/Data Register Selection |
RS = 0: Instruction Register RS = 1: Data Register |
R/W |
Read/Write Selection |
R/W = 0: Write R/W = 0: Read |
E |
Enable Signal |
|
DB0–DB7 |
Data Input/output Lines |
8 – Bit |
CS1 |
Chip (Seg. Driver) Selection |
CS1 = 1: Select Chip1 |
CS2 |
Chip (Seg. Driver) Selection |
CS2 = 1: Select Chip2 |
RST |
Reset Signal |
RST = 0: Display OFF, Display from Line 0 |
VEE |
Negative Voltage for LCD Driving |
-10 V |
LED+ |
Supply Voltage forLed+ |
+5V |
LED- |
Supply Voltage for Led- |
0V |
If you want to make a project by using this type of LCD you can purchase it at CreateLabz Store, where you can choose from 2 available colors: GREEN AND BLUE.
Hardware Set-up:
Software Set-up:
Open your Arduino IDE and upload this code to a new sketch.
You can copy the Arduino code found on our Github here.
There are quick explanation in every segment of the code. We have also used this library by Olikarus. This is primarily used in most projects involving the 128 x 64 LCD.
#include "U8glib.h"
Pin 13 is for enable,
Pin 11 is for the Read/Write
Pin 10 is for the Data or Instruction.
U8GLIB_ST7920_128X64 u8g(13, 11, 10);
4 pins for 4 buttons, the reset button can
be easily be connected to the RST on the Arduino.
const int BLEFT = 2;
const int BUP = 3;
const int BDOWN = 4;
const int BRIGHT = 5;
is 6x6 in size all through out the game. you can make it
larger or smaller depending on your preference.
int foodX = 6;
int foodY= 6;
int maxSnakeLength = 200;
int snakeLength = 6;
int snakeX[maxSnakeLength];
int snakeY[maxSnakeLength];
Strings are used to store text. They can be used to display text on an LCD
String command;
String Createlabz;
String cons;
in this case, all the buttons are false, false is defined as zero
meaning when the system is on, all buttons have to be pressed so
it will work according to their designated directions.
bool MLEFT = false;
bool MRIGHT = false;
bool MUP = false;
bool MDOWN = false;
bool Start = false;
bool Stop = false;
bool arduinoControl = true;
u8g.nextPage basically moves into another text display.
clearLCD rebuild the picture after some delay.
void setup() {
Serial.begin(115200);
Serial.println("Snake");
pinMode(BLEFT, INPUT);
pinMode(BUP, INPUT);
pinMode(BDOWN, INPUT);
pinMode(BRIGHT, INPUT);
u8g.firstPage();
do { first();
}
while( u8g.nextPage() );
delay(2000);
clearlcd();
u8g.firstPage();
do { second();
}
while( u8g.nextPage() );
delay(2000);
clearlcd();
randomSeed(analogRead(0));
snakeX[0] = 20;
snakeY[0] = 20;
drawSnake();
drawFood();
}
void first() and void second() functions will be the first thingthat you will see once the game is running. It will display the
"CreateLabz Tutorials" and "Classic Snake Game" Texts.
u8g.drawStr is to set characters or text on the LCD.
void first()
{ u8g.setFont(u8g_font_unifont);
u8g.drawStr( 20, 35, "CreateLabz");
u8g.drawStr( 17, 52, "Tutorials"); }
void second()
{ u8g.setFont(u8g_font_unifont);
u8g.drawStr( 12, 15, "C L A S S I C");
u8g.drawStr( 25, 35, "S N A K E");
u8g.drawStr( 30, 55, "G A M E"); }
void clearlcd(){ u8g.firstPage();
do { }
while( u8g.nextPage() );
}
Next void Control() is for controlling the snake direction and synchronizing it to the buttons. The -1 and +1 is for the direction of the snake, for examplesnakeX[0] = snakeX[0] - 1 will turn to the negative side
of the x-axis which is going to the LEFT.
snakeY[0] = snakeY[0] +1 will turn to the positive side
of the y-axis which is going UP.
void Control()
{ for(int i = snakeLength; i > 0; i--)
{ snakeX[i] = snakeX[i-1];
snakeY[i] = snakeY[i-1];
}
if (MLEFT == true)
{ snakeX[0] = snakeX[0] - 1;
}
else if (MUP == true)
{ snakeY[0] = snakeY[0] + 1;
}
else if (MDOWN == true)
{ snakeY[0] = snakeY[0] - 1;
}
else if (MRIGHT == true)
{ snakeX[0] = snakeX[0] + 1;
}
}
bool IsSnake(int x, int y)
{ for (int i = 0; i < snakeLength - 1; i++)
{ if ((x == snakeX[i]) && (y == snakeY[i]))
{ return true;
}
else { return false; }
}
}
Once the buttons are pressed (either of the four) the snake will turn or move in its designated movement with the
delay of 2 milliseconds.
void Buttons()
{ if (arduinoControl == true)
{ if ((digitalRead(BLEFT)) == HIGH && MRIGHT != true && MLEFT != true)
{ delay(200);
if ((digitalRead(BLEFT)) == LOW) {
MLEFT = true;
MUP = false;
MDOWN = false;
MRIGHT = false;
Serial.println("Left");
}
}
if ((digitalRead(BUP)) == HIGH && MDOWN != true && MUP != true) {
delay(200);
if ((digitalRead(BUP)) == LOW)
{ MLEFT = false;
MUP = true;
MDOWN = false;
MRIGHT = false;
Serial.println("Up");
}
} if ((digitalRead(BDOWN)) == HIGH && MUP != true && MDOWN != true)
{ delay(200); if ((digitalRead(BDOWN)) == LOW)
{ MLEFT = false;
MUP = false;
MDOWN = true;
MRIGHT = false;
Serial.println("Down"); } }
if ((digitalRead(BRIGHT)) == HIGH && MLEFT != true && MRIGHT != true) {
delay(200); if ((digitalRead(BRIGHT)) == LOW)
{MLEFT = false;
MUP = false;
MDOWN = false;
MRIGHT = true;
Serial.println("Right"); } } } }
In the function void DrawSnake(), the initial snake size is the same as the food size (6x6). The for loop statement indicates that the more food the snake eats, the longer it gets.
void DrawSnake()
{ for (int i = 0; i < snakeLength; i++)
{ u8g.drawBox(snakeX[i], snakeY[i], 6, 6);
}
void DrawFood()
{ if (OnScreen(foodX, foodY)
)
{ u8g.drawBox(foodX, foodY);
}
} bool OnScreen(int x, int y)
{ if (x >= 0 && x < 128 && y >= 0 && y < 64)
{ return true; }
else
{ return false; }
}
void GiveFood() would randomly place another 'food' on the screen.128 and 64 have been subtracted by 6 so that the 6x6 'food'
can be fully seen on the screen.
void GiveFood() {
foodX = random(6, 122);
foodY = random(6, 58);
}
void Eat() {
if (snakeX[0] == foodX && snakeY[0] == foodY)
{ if(snakeLength < maxSnakeLength)
{ snakeLength++;
u8g.drawBox(snakeX[0], snakeY[0], 6, 6);
}
return true; }
else {
return false;
}
}
Once the snake touches the screen borders, the void TouchedItSelf() function will be called and the game will restart once the restart button is pressed.were satisfied, it will not go back to the void first() and void second()
but rather it will tell you if you are ready to play again.
the Dead() will ask if you are ready to play again.
void loop() {
if (OnScreen(snakeX[0], snakeY[0])){
drawSnake();
drawFood();
if (Eat()) {
GiveFood();
Buttons();
Control();
}
else {
Buttons();
Control();
}
if (OnScreen(snakeX[0], snakeY[0]))
{ TouchedItSelf();
u8g.firstPage();
do {
drawSnake();
drawFood();
}
while (
u8g.nextPage() );
}
else {
Dead();
}
}
For visual explanation about the system, you can refer to this flow chart.
Output:
Upon uploading the code in your Arduino, you will be welcomed by three texts and the game will start once you have pressed any of the four buttons.
Conclusion:
GLCDs are very versatile, from displaying data and control, to even play games for fun. Stay tuned for the next tutorial as we are going to use a sensor to view its data.
Reference:
16*2 LCD Tester - Snake (My 1st Arduino Project) : 4 Steps - Instructables