The project described here is a digital implementation of “book cricket game” which students normally use to play in their childhood time. The heart of the project is 8 bit MCU from AVR family called ATtiny85. ATtiny85 are small and cheap microcontrollers which are convenient for running simple programs with low footprint. The software used for programming the MCU is Ardunio which is a popular open source IDE.
Steps to play the game
Project Source Code
###
//command bytes for LCD
#define CMD_CLR 0x01
#define CMD_RIGHT 0x1C
#define CMD_LEFT 0x18
#define CMD_HOME 0x02
// bitmasks for control bits on shift register
#define SHIFT_EN B00010000
#define SHIFT_RW B00100000
#define SHIFT_RS B01000000
int dat_pin=1;
int str_pin=2;
int clk_pin=0;
int lcd_lines=2;
const int buttonPin=4; // the pin that the pushbutton is attached to
int buttonState=0; // current state of the button
int lastButtonState=0; // previous state of the button
int data; //stores random value from ADC channel
char* startupmsg1=" Digital";
char* startupmsg2=" Book Cricket";
char* startupmsg3="Dev: Rahul Kar";
char *startupmsg4="yxrkt512@gmail";
int scoreboard[2]; //stores the total runs of 2 players
int overs_set,wickets_set; //stores the calibrated data
int wicket,balls;
void commandWrite(int value){
_pushByte(value, true);
delay(5);
}
//print the given character at the current cursor position. overwrites, doesn't insert.
void print(int value) {
_pushByte(value, false);
}
//print the given string to the LCD at the current cursor position. overwrites, doesn't insert.
//While I don't understand why this was named printIn (PRINT IN?) in the original LiquidCrystal library, I've preserved it here to maintain the interchangeability of the two libraries.
void printIn(char msg[]) {
unsigned int i;
for (i=0;i < strlen(msg);i++){
print(msg[i]);
}
}
void _pushByte(int value, bool command) {
int nibble = 0;
digitalWrite(str_pin,LOW); // set the strobe LOW
nibble = value >> 4; //send the first 4 databits (from 8)
_pushNibble(nibble, command);
delay(1);
nibble = value & 15; // set HByte to zero
_pushNibble(nibble, command);
}
// called twice by each _pushByte
void _pushNibble(int nibble, bool command) {
if (!command) {
nibble |= SHIFT_RS; // set DI HIGH
nibble &= ~SHIFT_RW; // set RW LOW
}
nibble &= ~SHIFT_EN; // set Enable LOW
_pushOut(nibble);
nibble |= SHIFT_EN; // Set Enable HIGH
_pushOut(nibble);
nibble &= ~SHIFT_EN; // set Enable LOW
_pushOut(nibble);
}
// push byte to shift register and on to LCD
void _pushOut(int value) {
shiftOut(dat_pin, clk_pin, LSBFIRST, value);
digitalWrite(str_pin, HIGH);
delayMicroseconds(10);
digitalWrite(str_pin, LOW);
}
//non-core stuff --------------------------------------
//send the clear screen command to the LCD
void clear(){
commandWrite(CMD_CLR);
}
//move the cursor to the given absolute position. line numbers start at 1.
//if this is not a 2-line LCD3Wire instance, will always position on first line.
void cursorTo(int line_num, int x){
//first, put cursor home
commandWrite(CMD_HOME);
//if we are on a 1-line display, set line_num to 1st line, regardless of given
if (lcd_lines==1){
line_num = 1;
}
//offset 40 chars in if second line requested
if (line_num == 2){
x += 40;
}
//advance the cursor to the right according to position. (second line starts at position 40).
for (int i=0; i<x; i++) {
commandWrite(0x14);
}
}
//scroll whole display to left
void leftScroll(int num_chars, int delay_time){
for (int i=0; i<num_chars; i++) {
commandWrite(CMD_LEFT);
delay(delay_time);
}
}
void initialize() {
pinMode(dat_pin,OUTPUT);
pinMode(str_pin,OUTPUT);
pinMode(clk_pin,OUTPUT);
pinMode(3,INPUT);
pinMode(4,INPUT);
delay(100);
commandWrite(0x03); // function set: 4 pin initialization
commandWrite(0x03); // function set: 4 pin initialization
commandWrite(0x03); // function set: 4 pin initialization
commandWrite(0x02); // function set: 4 pin initialization
commandWrite(0x28); // function set: 4-bit interface, 2 display lines, 5x7 font
commandWrite(0x06); // entry mode set:
commandWrite(0x0e); // display control:
commandWrite(0x01); // turn display on, cursor on, no blinking
}
void clean() { //initializes the variables for next set of match
wicket=balls=0;
scoreboard[0]=scoreboard[1]=0;
}
int score_engine(int data,int player) { //converts the random value into runs
int run=data%10;
if(run==0)
{
wicket++;
return -999;
}
else if(run==5||run==7||run==8||run==9)
{
return -1;
}
else
{
scoreboard[player]+=run;
return run;
}
}
void display_engine(int data,int player) { //handles all the display function
char* wick="Wicket!!";
char* dot="Dot Ball...";
char* one="1 Run";
char* two="2 Runs";
char* three="3 Runs";
char* four="FOUR!!!";
char* six="SIX!!!";
char *total="Total: ";
int stat=score_engine(data,player);
if(stat==-999)
printIn(wick);
if(stat==-1)
printIn(dot);
else if(stat!=-1)
{
if(stat==1)
printIn(one);
if(stat==2)
printIn(two);
if(stat==3)
printIn(three);
if(stat==4)
printIn(four);
if(stat==6)
printIn(six);
}
cursorTo(2,0);
printIn(total);
disp_int__module(scoreboard[player]);
printIn("/");
disp_int__module(wicket);
printIn(" ");
disp_int__module(balls);
}
int calibrate_wickets() { //takes input from user fo no. of wickets
char* msg1="Set Wickets...";
char* msg2="Press Hit to set";
char *msg3="Wickets: ";
int counter=0;
clear();
printIn(msg1);
delay(2000);
leftScroll(20,50);
clear();
printIn(msg2);
int start_time=millis();
do
{
buttonState=digitalRead(buttonPin);
if(buttonState!=lastButtonState)
{
clear();
if(buttonState==HIGH)
{
counter++;
printIn(msg3);
disp_int__module(counter);
}
else
{
printIn(msg3);
disp_int__module(counter);
}
}
lastButtonState=buttonState;
}
while(millis()-start_time<10000);
return counter;
}
int calibrate_overs() { //takes input from user fo no. of overs
char* msg1="Set Overs...";
char* msg2="Press Hit to set";
char *msg3="Overs: ";
int counter=0;
clear();
printIn(msg1);
delay(2000);
leftScroll(20,50);
clear();
printIn(msg2);
int start_time=millis();
do
{
buttonState=digitalRead(buttonPin);
if(buttonState!=lastButtonState)
{
clear();
if(buttonState==HIGH)
{
counter++;
printIn(msg3);
disp_int__module(counter);
}
else
{
printIn(msg3);
disp_int__module(counter);
}
}
lastButtonState=buttonState;
}
while(millis()-start_time<10000);
return counter;
}
void disp_int__module(int data) { //converts the integer data to char to display using 3 Wire mode
int digitlength=0;
int reversedata=0;
do
{
reversedata=reversedata*10;
reversedata+=(data%10);
data/=10;
digitlength++;
}
while(data!=0);
for(int i=0;i<digitlength;i++)
{
print((48+reversedata%10));
reversedata/=10;
}
}
void player1() { //player 1 related stuff
char* msg1="Player 1 Batting";
char* msg2="Press Hit";
char* eoo="End of Overs!";
char* allout="All Out!!";
char* tot="Player 1 Total:";
clear();
printIn(msg1);
delay(2000);
leftScroll(20,50);
clear();
printIn(msg2);
wicket=0;
balls=(6*overs_set);
do
{
buttonState=digitalRead(buttonPin);
if(buttonState!=lastButtonState)
{
if(buttonState==LOW)
{
--balls;
clear();
data=analogRead(3);
display_engine(data,0);
}
}
lastButtonState=buttonState;
}
while(balls>0&&wicket<wickets_set);
if(balls<=0)
{
clear();
printIn(eoo);
delay(2000);
leftScroll(20,50);
clear();
}
if(wicket>=wickets_set)
{
clear();
printIn(allout);
delay(2000);
leftScroll(20,50);
clear();
}
printIn(tot);
cursorTo(2,0);
disp_int__module(scoreboard[0]);
printIn("/");
disp_int__module(wicket);
delay(4000);
}
void player2() { //player 2 related stuff
char* msg1="Player 2 Batting";
char* msg2="Press Hit";
char* eoo="End of Overs!";
char* allout="All Out!!";
char* tot="Player 2 Total:";
char* mo="Match Over!!";
clear();
printIn(msg1);
delay(2000);
leftScroll(20,50);
clear();
printIn(msg2);
wicket=0;
balls=(6*overs_set);
do
{
buttonState=digitalRead(buttonPin);
if(buttonState!=lastButtonState)
{
if(buttonState==LOW)
{
--balls;
clear();
data=analogRead(3);
display_engine(data,1);
}
}
lastButtonState=buttonState;
}
while(balls>0&&wicket<wickets_set&&scoreboard[1]<=scoreboard[0]);
if(balls<=0)
{
clear();
printIn(eoo);
delay(2000);
leftScroll(20,50);
clear();
}
if(wicket>=wickets_set)
{
clear();
printIn(allout);
delay(2000);
leftScroll(20,50);
clear();
}
if(scoreboard[1]>scoreboard[0])
{
clear();
printIn(mo);
delay(2000);
leftScroll(20,50);
clear();
}
printIn(tot);
cursorTo(2,0);
disp_int__module(scoreboard[1]);
printIn("/");
disp_int__module(wicket);
delay(4000);
}
void determine_winner() { //calculates the winner
char* msg1="Player 1 Wins!!";
char* msg2="Player 2 Wins!!";
char* msg3="Match Draw!!";
char* won="Won by ";
char* runs=" Runs";
if(scoreboard[0]>scoreboard[1])
{
clear();
printIn(msg1);
cursorTo(2,0);
printIn(won);
disp_int__module(scoreboard[0]-scoreboard[1]);
printIn(runs);
delay(2000);
leftScroll(20,50);
clear();
}
else if(scoreboard[1]>scoreboard[0])
{
clear();
printIn(msg2);
cursorTo(2,0);
printIn(won);
disp_int__module(scoreboard[1]-scoreboard[0]);
printIn(runs);
delay(2000);
leftScroll(20,50);
clear();
}
else if(scoreboard[1]==scoreboard[0])
{
clear();
printIn(msg3);
delay(2000);
leftScroll(20,50);
clear();
}
}
void setup() { //performs all the initial setup
initialize();
printIn(startupmsg1);
cursorTo(2,0);
printIn(startupmsg2);
delay(2000);
leftScroll(20,50);
clear();
printIn(startupmsg3);
cursorTo(2,0);
printIn(startupmsg4);
delay(2000);
leftScroll(20,50);
clear();
wickets_set=calibrate_wickets();
overs_set=calibrate_overs();
}
void loop() {
clean();
Project Video
Filed Under: Electronic Projects
Filed Under: Electronic Projects
Questions related to this article?
👉Ask and discuss on Electro-Tech-Online.com and EDAboard.com forums.
Tell Us What You Think!!
You must be logged in to post a comment.