# DIY Arduino LCD-Keypad Maths Game(Mathopia)

Tutorial:

Watch this step by step tutorial and follow along :

COMPONENTS REQUIRED:

2. Arduino UNO

3. LCD(16X2)

4. BUZZER

5. Potentiometer 10kohm

CIRCUIT DIAGRAM:

Note: This project was made in tinkered. You can copy the file and start playing with it right away(it’s free!)

PROGRAM:

```/*
**************************************************Mathopia**********************************************************
*
*      Created on: May 27, 2020
*      Author:Ankit Negi
*
*      Website: www.eTechnophiles.com
*/

#include <LiquidCrystal.h>//LCD library
LiquidCrystal lcd(6,5,4,3,2,1);//lcd(RS,En,D4,D5,D6,D7)
#include<EEPROM.h>

//A0 pin is used to reset the board
#define PINtoRESET A0// connected to reset pin of Uno
// define inputs
#define ip_1 7
#define ip_2 8
#define ip_3 9
#define ip_4 10
// define outputs
#define op_1 11
#define op_2 12
#define op_3 13
// Buzzer
#define BUZZER A1

// variable to store random number
int randNumber = 0;

unsigned long startMillis;  //time, when a question is given
unsigned long currentMillis;//current time
const unsigned long period = 10000;// time to answer the question

// Array of questions
String problems[20] = {
"3 X 6 + 116 =", "19 - 34 X 61= ", "100 / 25 X 25= ", "99 - 56 X 225/5", "-3 + 2x = 11", "4x + 6 = -10" , "x + 9 = 18 - 2x", "2x + 6 = 4x - 2",
"-x-1 = 221 + 2x" , "15 + 5x = 0", "17x-12 = 114+3x", "2x-10 = 10-3x",  "12x + 60 = 144", "-10x-19 = 19-8x", "6/2 + 7 X 4 =", "4 + 82X(30/5) =",
"3(125-?) = 3", "x% of 5=6% of 40", "616+ ? +333=255", "[6-{4-(8-6+3)}]"
};
//Array of real solutions
int solutions[20] = {
134, -2055, 100, -2421, 7, -4, 3, 4, -74, -3, 9, 4, 7, -19, 31, 496, 124, 48, -694, 7
};

//Array to store the typed solution
char keypad[10] = {1, 10, 10, 10, 10, 10, 10, 10, 10, 10};

//solution counter to be used in various functions
int solcounter = 0;

void setup() {
/*
EEPROM.write(0,0);
EEPROM.write(1,0);*/

// noise will cause the call to randomSeed() to generate
// different seed numbers each time the sketch runs.
// randomSeed() will then shuffle the random function.

pinMode(PINtoRESET, INPUT);    // set A0 pin as input
digitalWrite(PINtoRESET, LOW); // if set high, board will reset

lcd.begin(16, 2);

//set pins as output
for (int i = op_1; i <= op_3; i++)
pinMode(i, OUTPUT);

//set pins as input
pinMode(ip_1, INPUT_PULLUP);
pinMode(ip_2, INPUT_PULLUP);
pinMode(ip_3, INPUT_PULLUP);
pinMode(ip_4, INPUT_PULLUP);

initiate_Game();//  call the function to initiate game
start_Game();// call the function for the first question
}

void loop() {

for (int i = op_1; i <= op_3; i++)
digitalWrite(i, HIGH);

// start checking for the pressed button in each column one by one
column1();

column2();

column3();

// compare the time elapsed since the question is displayed
currentMillis = millis();
if ((currentMillis - startMillis) > period)
{ // if time elapsed is > the period specified
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Out of Time!");
lcd.setCursor(0, 1);
//print the user score
lcd.print(solcounter);
EEPROM.write(0,solcounter);
}

//this code prevents program from printing the "welcoming message" for 10 consecutive resets or shut down
EEPROM.write(1,0);
}else{
EEPROM.write(1,++x);
}

/*
Play this tone sequence when the answer is wrong or player is out of time
*/
tone(BUZZER, 440, 200);
delay(200);
// turn off tone function for pin A2:
noTone(BUZZER);
tone(BUZZER, 494, 500);
delay(500);
// turn off tone function for pin A2:
noTone(BUZZER);
// play a note on pin 8 for 300 ms:
tone(BUZZER, 523, 300);
delay(300);

delay(1000);
lcd.clear();
pinMode(PINtoRESET, OUTPUT);
} else;
}

// function to intiate the game
void initiate_Game()
{

lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Welcome to   ");
lcd.setCursor(3, 1);
lcd.print(" Mathopia");

// scroll 13 positions (string length) to the left
// to move it offscreen left:
for (int positionCounter = 0; positionCounter < 13; positionCounter++) {
// scroll one position left:
lcd.scrollDisplayLeft();
// wait a bit:
delay(200);
}

// scroll 29 positions (string length + display length) to the right
// to move it offscreen right:
for (int positionCounter = 0; positionCounter < 29; positionCounter++) {
// scroll one position right:
lcd.scrollDisplayRight();
// wait a bit:
delay(200);
}

// scroll 16 positions (display length + string length) to the left
// to move it back to center:
for (int positionCounter = 0; positionCounter < 16; positionCounter++) {
// scroll one position left:
lcd.scrollDisplayLeft();
// wait a bit:
delay(200);
}
}

lcd.setCursor(0,0);
lcd.print("High. Score=");
delay(2000);

for (int i = op_1; i <= op_3; i++)
digitalWrite(i, LOW);

int w = 0, x = 0, y = 0, z = 0;
do
{
lcd.setCursor(0, 0);
lcd.print(" Press to Start");
lcd.setCursor(0, 1);
lcd.print("+-*");
lcd.setCursor(13, 1);
lcd.print("-+/");
} while ((w == 1 && x == 1 && y == 1 && z == 1));// continue printing if button is not pressed

// else go back to the loop
delay(500);
}

// function to display the questions
void start_Game()
{

lcd.clear();
// print a random number from 0 to 20
randNumber = random(0, 20);
//lcd.print(problems[solcounter]);
lcd.print(problems[randNumber]);
lcd.setCursor(0, 1);
startMillis = millis();

}

// function to store the typed number in an array(keypad[])
void fill_Array(int x)
{ // check for the empty element in the array
for (int i = 1; i < 10; i++)// element 0 is reserved for the sign
{
{
i = 10;
}
else;
}
}

//this function finds the last element that is stored(typed) in the keypad[] array
void find_Last_Element()
{
int endElement = 0;
for (int i = 1; i < 10; i++)
{
endElement = --i;
i = 10;
}
else;
}

check_Ans(endElement);
}
// this function checks the answer stored in array keypad[] to the real answer stored in solutions array
void check_Ans(int endElement)
{
// for loop to copy the typed answer from typed[] array to the variable answer
for (int i = endElement, x = 1; (i >= 1) && (x <= endElement); i--, x++)
{
if (x == 1) {
}
else {
int tempNum = 1;
for (int y = 1; y < x; y++ )
{
tempNum = tempNum * 10;
}
}
}// end of for loop

// if else conditional statment is used to compare real answer to typed answer
lcd.setCursor(0, 1);
lcd.print("Correct!");

/*
Play this tone sequence when the answer is correct
*/
tone(BUZZER, 523, 300);
delay(300);
// turn off tone function for pin A2:
noTone(BUZZER);
tone(BUZZER, 494, 500);
delay(500);
// turn off tone function for pin A2:
noTone(BUZZER);
tone(BUZZER, 440, 200);
delay(200);

delay(1000);
solcounter++;
if (solcounter == 21) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Congratulations!");
lcd.setCursor(1, 3);
lcd.print("Champion");
/*
Play this tone sequence after the correct answer to the last question
*/
int x = 0;
while (x < 4) {
tone(BUZZER, 523, 300);
delay(300);
// turn off tone function for pin A2:
noTone(BUZZER);
tone(BUZZER, 494, 500);
delay(500);
// turn off tone function for pin A2:
noTone(BUZZER);
tone(BUZZER, 440, 200);
delay(200);
// turn off tone function for pin A2:
noTone(BUZZER);
tone(BUZZER, 494, 500);
delay(500);
// turn off tone function for pin A2:
noTone(BUZZER);
x++;
}
delay(2000);
pinMode(PINtoRESET, OUTPUT);// reset the board
}
for (int i = 1; i < 10; i++)
{
}
start_Game();// call this function to display next question
}
else { //if answer is incorrect

lcd.clear();
lcd.setCursor(0, 0);
lcd.setCursor(0, 1);
//print the user score
lcd.print(solcounter);

//if previous high score is less than current score
EEPROM.write(0,solcounter);
}

//this code prevents program from printing the "welcoming message" for 10 consecutive resets or shut down
EEPROM.write(1,0);
}else{
EEPROM.write(1,++x);
}

/*
Play this tone sequence when the answer is wrong or player is out of time
*/
tone(BUZZER, 440, 200);
delay(200);
// turn off tone function for pin A2:
noTone(BUZZER);
tone(BUZZER, 494, 500);
delay(500);
// turn off tone function for pin A2:
noTone(BUZZER);
// play a note on pin 8 for 300 ms:
tone(BUZZER, 523, 300);
delay(300);

delay(1000);
lcd.clear();
pinMode(PINtoRESET, OUTPUT);// reset the board
}
}

//check for the button pressed in column 1
void column1()
{
digitalWrite(11, LOW);
if (w < 1) {
delay(10);
lcd.print("1");
fill_Array(1);// fill the array
tone(BUZZER, 1906, 200);
delay(500);
} else ;

if (x < 1) {
delay(10);
lcd.print("4");
fill_Array(4);
tone(BUZZER, 1979, 200);
delay(500);
} else ;

if (y < 1) {
delay(10);
lcd.print("7");
fill_Array(7);
tone(BUZZER, 2061, 200);
delay(500);
} else ;

if (z < 1) {
delay(10);
lcd.print("-");
tone(BUZZER, 2150, 200);
delay(500);
} else ;

for (int i = op_1; i <= op_3; i++)
digitalWrite(i, HIGH);
}

//check for the button pressed in column 2
void column2()
{
digitalWrite(12, LOW);
if (w < 1) {
delay(10);
lcd.print("2");
fill_Array(2);
tone(BUZZER, 2033, 200);
delay(500);
} else ;

if (x < 1) {
delay(10);
lcd.print("5");
fill_Array(5);
tone(BUZZER, 2106, 200);
delay(500);
} else ;

if (y < 1) {
delay(10);
lcd.print("8");
fill_Array(8);
tone(BUZZER, 2188, 200);
delay(500);
} else ;

if (z < 1) {
delay(10);
lcd.print("0");
fill_Array(0);
tone(BUZZER, 2277, 200);
delay(500);
} else ;

for (int i = op_1; i <= op_3; i++)
digitalWrite(i, HIGH);
}

//check for the button pressed in column 3
void column3()
{
digitalWrite(13, LOW);
if (w < 1) {
delay(10);
lcd.print("3");
fill_Array(3);
tone(BUZZER, 2174, 200);
delay(500);
} else ;

if (x < 1) {
delay(10);
lcd.print("6");
fill_Array(6);
tone(BUZZER, 2247, 200);
delay(500);
} else ;

if (y < 1) {
delay(10);
lcd.print("9");
fill_Array(9);
tone(BUZZER, 2329, 200);
delay(500);
} else ;