Try   HackMD

Math Trainig with Arduino , LCD,and 4X4 Keypad

tags: Math Trainig LCD 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);
}

//////////////////////////////////////////////////////////////////////





  • Embed YouTube Videos

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!