Math Trainig with Arduino , LCD,and 4X4 Keypad
What training is about `
Hi,
Most of us need training for Math , this #arduinouno system help you to train your mind a little bit.
We can use 3 different levels :
A: for level 1 : just +,- operation amd randomly generated number less than 10.
B for level 2 : here we add multiple × .
C for level 3 : here we are Mode % , and nummber upp to 99 per operation!
All numbers and operation generated randomly at every question
The game can be played in many times each match is 10 questions!
Timer : Not added yet. into this Vedio!
Player get the results after every match and just know the level!
Player can pass the question and get -10 as score!
see example https://youtu.be/rgLFKGn_i_I
Image Not Showing
Possible Reasons
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →
Connecting and Wiring?
Step 1: The LCD
I connected LCD with potentiomete to Arduino as next :
rs = A0, en = A1, d4 =A2, d5 = A3, d6 = A4, d7 = A5;
Image Not Showing
Possible Reasons
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →
This how to connect the LCD with **potentiometer ** to adjust contrast
Image Not Showing
Possible Reasons
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →
Then i installed librar :
#include <LiquidCrystal.h>
Image Not Showing
Possible Reasons
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →
Step 2: Connecting 4X4 Kepad
4X4 KeyPad har 8 Pins , first 4 for Rows and 4 for columns as this pic.
Image Not Showing
Possible Reasons
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →
in my code u can find how i connect it :
byte rowPins[ROWS] = {2, 3, 4, 5};
byte colPins[COLS] = {6, 7, 9, 10};
and related Library : #include <Keypad.h>
Step 3: Piezo and Leds ( Red, Yellow, Green)!
I connect the Leds with Resistor to arduino as defined in the code :
Image Not Showing
Possible Reasons
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →
// LEDS
const byte GLed = 11;
const byte YLed = 12;
const byte RLed = 13;
and we Buzzer with
// Buzzer
const byte Buzzer = 8;
As Usual Sharing is caring!
//Hi,
//Most of us need training for Math , this #arduinouno system help you to
//train your mind a little bit.
//We can use 3 different levels :
//A: for level 1 : just +,- operation amd randomly generated number less than 10.
//B for level 2 : here we add multiple × .
//C for level 3 : here we are Mode % , and nummber upp to 99 per operation!
//All numbers and operation generated randomly at every question
//The game can be played in many times each match is 10 questions!
//Timer : Not added yet. into this Vedio!
//Player get the results after every match and just know the level!
//Player can pass the question and get -10 as score!
//https://youtu.be/rgLFKGn_i_I
//--------------------------------------------------------------------------
// Autor : Ammar Alnahhas
// Date : 2020-11-27
// for more info about code inbox me in : eng.ammar.alnahas@gmail.com
//--------------------------------------------------------------------------
#include <Keypad.h>
#include <LiquidCrystal.h>
// My Melodies
#define NOTE_Player_Wins 523
#define NOTE_Player_Lose 587
// How Many Question per match
#define Questions 10
// Waiting Times
#define Waiting_Time_Lv1 180000
#define Waiting_Time_Lv2 120000
#define Waiting_Time_Lv3 60000
// initialize the library by associating any needed LCD interface pin
// with the arduino pin number it is connected to
const int rs = A0, en = A1, d4 =A2, d5 = A3, d6 = A4, d7 = A5;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
// The Key pad
const byte ROWS = 4;
const byte COLS = 4;
char hexaKeys[ROWS][COLS] = {
{'1', '2', '3', 'A'},
{'4', '5', '6', 'B'},
{'7', '8', '9', 'C'},
{'*', '0', '#', 'D'}
};
byte rowPins[ROWS] = {2, 3, 4, 5};
byte colPins[COLS] = {6, 7, 9, 10};
// Buzzer
const byte Buzzer = 8;
// LEDS
const byte GLed = 11;
const byte YLed = 12;
const byte RLed = 13;
Keypad customKeypad = Keypad(makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS);
// Results storage
int Resault[Questions]={0,0,0,0,0,0,0,0,0};
// Rerun Controler
bool rRun = true;
void setup() {
// Serial
Serial.begin(9600);
// Buzzer and Lights
pinMode(Buzzer,OUTPUT);
pinMode(GLed,OUTPUT);
pinMode(YLed,OUTPUT);
pinMode(RLed,OUTPUT);
// set up the LCD's number of columns and rows:
lcd.begin(16, 2);
// Print a message to the LCD.
lcd.setCursor(0,0);
lcd.print(" HELLO GENIUS ");
delay(2000);
for (int i=0; i<=15;i++)
{lcd.setCursor(i,1);
lcd.print("DSNA");
delay(1000);
/*lcd.setCursor(i,1);
lcd.print("DSNA");
delay(1000);*/}
}
void loop() {
if (rRun){
byte Choose = Menu();
Match(Choose);
rRun=rerun();
}
else
{
lcd.clear();
lcd.setCursor(0,0);
lcd.print(" GOOD BYE ");
lcd.setCursor(0,1);
lcd.print("Plz Switch off");
rRun=false;
delay(5000);
}
}
///////////////////////////////////////////////////////////////
bool rerun()
{
char My_input;
// the Menu on the screen
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Training again");
lcd.setCursor(0,1);
lcd.print(" A=YES B= NO ");
delay(4000);
lcd.clear();
lcd.setCursor(0,0);
lcd.print(" A=YES B= NO ");
lcd.setCursor(0,1);
//Reading input
while (1){
// Read from Keypad
My_input = customKeypad.getKey();
if (My_input){
lcd.setCursor(0,1);
lcd.blink();
switch(My_input){
case 'A' : // To train again
lcd.print("YES");
delay(2000);
tone(Buzzer,NOTE_Player_Wins );
digitalWrite(GLed,HIGH);
delay(200);
noTone(Buzzer);
digitalWrite(GLed,LOW);
return true;
case 'B' : // Not intrested
lcd.print("NO");
delay(2000);
tone(Buzzer,NOTE_Player_Lose );
digitalWrite(RLed,HIGH);
delay(200);
noTone(Buzzer);
digitalWrite(RLed,LOW);
return false;
default :
lcd.print('*');
tone(Buzzer,NOTE_Player_Lose );
digitalWrite(RLed,HIGH);
delay(200);
noTone(Buzzer);
digitalWrite(RLed,LOW);
break;
}
}
}
}
///////////////////////////////////////////////////////////////
byte Menu(){ // The input menu of the Program
char My_input;
lcd.clear();
lcd.setCursor(0,0);
lcd.print(" Select ur Level");
lcd.setCursor(0,1);
lcd.print("A=LV1 B=LV2 C=L3");
delay(5000);
// Prpare to enter the Choice
lcd.clear();
lcd.setCursor(0,0);
lcd.print("A=LV1 B=LV2 C=L3");
lcd.setCursor(0,1);
//Reading input
while (1){
// Read from Keypad
My_input = customKeypad.getKey();
if (My_input){
lcd.setCursor(0,1);
lcd.blink();
switch(My_input){
case 'A' : // LEVEL 1
lcd.print("LEVEL 1");
delay(2000);
tone(Buzzer,NOTE_Player_Wins );
digitalWrite(GLed,HIGH);
delay(200);
noTone(Buzzer);
digitalWrite(GLed,LOW);
return 1;
case 'B' : // LEVEL 2
lcd.print("LEVEL 2" );
delay(2000);
tone(Buzzer,NOTE_Player_Wins );
digitalWrite(YLed,HIGH);
delay(200);
noTone(Buzzer);
digitalWrite(YLed,LOW);
return 2;
case 'C' : // LEVEL 3
lcd.print("LEVEL 3");
tone(Buzzer,NOTE_Player_Lose );
digitalWrite(RLed,HIGH);
delay(200);
noTone(Buzzer);
digitalWrite(RLed,LOW);
return 3;
default : // Wrong input
lcd.print('*');
delay(2000);
tone(Buzzer,NOTE_Player_Lose );
digitalWrite(RLed,HIGH);
delay(200);
noTone(Buzzer);
digitalWrite(RLed,LOW);
break;
}
}
}
}
//////////////////////////////////////////////////////////////
int Rand_Number(byte Level) // Number genrator per Level
{ if ((Level==1) || (Level==2))
return (rand()%10) ;
else if (Level >2)
return (rand()%100);
}
//////////////////////////////////////////////////
char Rand_operator(byte Level) // Operator genrator per LEVEL
{
if (Level==1){
int Op= rand()%2;
if (Op==0) return '+';
else if ( Op==1) return '-';
}
else if (Level==2){
int Op= rand()%3;
if (Op==0) return '+';
else if ( Op==1) return '-';
else if ( Op==2) return 'X';
}
else if (Level> 2){
int Op= rand()%4;
if (Op==0) return '+';
else if ( Op==1) return '-';
else if ( Op==2) return 'X';
else if ( Op==3) return '%';
}
}
//////////////////////////////////////////////////
int reading_Digit(char input) // Compile chare from KeyPad to Numbers
{ switch (input){
case '1' :
return 1;
break;
case '2' :
return 2;
break;
case '3' :
return 3;
break;
case '4' :
return 4;
break;
case '5' :
return 5;
break;
case '6' :
return 6;
break;
case '7' :
return 7;
break;
case '8' :
return 8;
break;
case '9' :
return 9;
break;
case '0' :
return 0;
break;
case 'A' :
return 11;
break;
case 'B' :
return 12;
break;
case 'C' :
return 13;
break;
case 'D' :
return 14;
break;
case '*' :
return 15;
break;
case '#' :
return 16;
break;
}
}
//////////////////////////////////////////////////
long Reading_Num()
{
char My_input ;
long My_return = 0;
int i = 0;
long dec = 100000;
int My_digit;
while (1){
// Read from Keypad
My_input = customKeypad.getKey();
if (My_input){
lcd.setCursor(i,1);
lcd.blink();
// convert to digit
My_digit = reading_Digit(My_input);
// discuss digit cases
if (My_digit ==15){ // * to pass to next Question
lcd.print("Pass to Next");
delay(1000);
tone(Buzzer,NOTE_Player_Lose );
digitalWrite(YLed,HIGH);
delay(200);
noTone(Buzzer);
digitalWrite(YLed,LOW);
return -1;
}
else if (( My_digit >9)&& (My_digit !=14)){ // Not a number or command
lcd.print('*');
tone(Buzzer,NOTE_Player_Lose );
digitalWrite(RLed,HIGH);
delay(200);
noTone(Buzzer);
digitalWrite(RLed,LOW);
}
else if (My_digit<=9) // is an acceptable input
{
lcd.print(My_digit);
My_return+= My_digit*dec;
//My_output[i] = My_digit; // save it into our array
dec/=10;
i++;
//Serial.print( "My_i= ");
//Serial.println( i);
//Serial.print( "My_dec= ");
//Serial.println( dec);
//Serial.print( "My_digit= ");
//Serial.println( My_digit);
//Serial.print( "My_return= ");
//Serial.println(My_return);
delay(500);//wait to write next digit before jumping to next!
}
else if (My_digit == 14) // Enter the number
{
lcd.noBlink();
break;
}
}
}
My_return /= dec*10;
return My_return;
}
/////////////////////////////////////////////////////////////////////////////////
long Generate_Question(byte level){ // Question genrator
int F_Number;
char Operator;
int S_Number;
if ((level==1) || (level==2)){ // First Level
while (1){ // Garanti no Negative result for '-' operation
F_Number = Rand_Number(level);
Operator = Rand_operator(level);
S_Number = Rand_Number(level);
if (F_Number>=S_Number) break;
}
lcd.clear();
lcd.setCursor(0,0);
lcd.print(F_Number );
lcd.setCursor(3,0);
lcd.print( Operator);
lcd.setCursor(5,0);
lcd.print(S_Number );
lcd.setCursor(8,0);
lcd.print('=' );
// Returning the Results
switch (Operator){
case '+' :
return F_Number+S_Number;
case '-':
return F_Number-S_Number;
case 'X':
return F_Number*S_Number;
//case '%' :
// return F_Number%S_Number;
}
}
else if (level>2){
while (1){ // Garanti no Negative result for '-' operation
F_Number = Rand_Number(level);
Operator = Rand_operator(level);
S_Number = Rand_Number(level);
if ((F_Number>=S_Number)) break;
}
lcd.clear();
lcd.setCursor(0,0);
lcd.print(F_Number );
lcd.setCursor(3,0);
lcd.print( Operator);
lcd.setCursor(5,0);
lcd.print(S_Number );
lcd.setCursor(8,0);
lcd.print('=' );
// REturning the Results
switch (Operator){
case '+' :
return F_Number+S_Number;
case '-':
return F_Number-S_Number;
case 'X':
return F_Number*S_Number;
case '%' :
return F_Number%S_Number;
}
}
}
///////////////////////////////////////////////////////////////////////////
void Match(byte level){ // the Ten Questions MAtch
byte q_counter =1;
long solution=0;
long Answer =0;
int M_results=0;
while (q_counter<=Questions){
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Question# ");
lcd.setCursor(11,0);
lcd.print(q_counter);
delay(3000); // show for 3 Seconds
solution = Generate_Question(level); // Generate Question and get the resualt of formula
Answer = Reading_Num(); // REad User input
q_counter++;
if (Answer== -1){ // User pass the Question
tone(Buzzer,NOTE_Player_Lose );
digitalWrite(YLed,HIGH);
delay(200);
noTone(Buzzer);
digitalWrite(YLed,LOW);
Resault[q_counter-2]= -1;
//DEbuging
Serial.print("PASS :: ");
Serial.print(" The Result of :");
Serial.print(q_counter-2);
Serial.print(" is :");
Serial.println(Resault[q_counter-2]);
}
else if (Answer ==solution){ //Right Answer
tone(Buzzer,NOTE_Player_Wins );
digitalWrite(GLed,HIGH);
delay(400);
noTone(Buzzer);
digitalWrite(GLed,LOW);
Resault[q_counter-2]=1;
//Debuging
Serial.print("RIGHT ^^ ");
Serial.print(" The Result of Q# :");
Serial.print(q_counter-2);
Serial.print(" is :");
Serial.println(Resault[q_counter-2]);
}
else if (Answer !=solution){ //Right Answer
tone(Buzzer,NOTE_Player_Lose );
digitalWrite(RLed,HIGH);
delay(200);
noTone(Buzzer);
digitalWrite(RLed,LOW);
Resault[q_counter-2]=0;
//DEbuging
Serial.print("Wrong VV ");
Serial.print(" The Result of Q# :");
Serial.print(q_counter-2);
Serial.print(" is :");
Serial.println(Resault[q_counter-2]);
}
}
// Calculating results
for(int i=0;i<Questions;i++)
{ M_results+=Resault[i]*10;
Serial.print(" The Result@ ") ;
Serial.print(i);
Serial.print( "is :");
Serial.println(Resault[i]*10);
Serial.print(" The M_Result is : ") ;
Serial.println(M_results);
}
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Score is : ");
lcd.setCursor(12,0);
lcd.print(M_results);
lcd.setCursor(0,1);
if (M_results <50 ) {lcd.print(" NOT SO GOOD ");}
else if ((M_results>51 ) && (M_results <85 )) { lcd.print("NOT BAD : SO--SO");}
else if (M_results > 85 ) {lcd.print(" JUST PERFECT ");}
Serial.print(" The Scour is :");
Serial.print(M_results);
delay(5000);
}
//////////////////////////////////////////////////////////////////////
Image Not Showing
Possible Reasons
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →
DSNA22 OTHER Projects :
Last but not least Thanks :
Thanks for Thomas Berggren for all knowledge and experience that looks clearly in backscenes of this project!