How to use 7-segments display, lcd and keypad?

  arduino, atmega, c++

I created a code for an Arduino MEGA. The scope is to run a bomb game:
You launch the bomb, then 2 7-segment displays show the remaining time (in seconds).
Using a numeric keypad you have to find out the secret code (self-generated).
During the last 10 seconds there is a beep each second.
An LCD screen gives clues about the secret code.

I created a sample of code but I’m not sure if it could work, can you please give me some advices? The compiler gives no errors but unfortunately I can’t try it (I’ve not the material) and I need to delivery it tomorrow.

#include <LiquidCrystal_I2C.h>
#include <Key.h>
#include <Keypad.h>


//SETTINGS

byte countdown = 60; //Change this value to adjust the time before the bomb explode (in seconds). Change between 1 - 250
byte beepStart = 10; //This indicates when the buzzer starts (in seconds). 10 means the beep starts in the last 10 seconds of the game. Change between 1 - 250
byte beepFrequence = 1; //The interval beyween each beep (in seconds). Change between 1 - 250
byte cluesFrequence = 3; //Every how many errors a hint must be given
byte allowedErrors = 3; //How many errors are allowed before the bomb explodes


//DO NOT CHANGE THESE VARIABLES

//Wiring of first digit display
byte firstA = 1;
byte firstB = 2;
byte firstC = 10;
byte firstD = 11;
byte firstE = 12;
byte firstF = 0;
byte firstG = 14;

//Wiring of second digit display
byte secondA = 5;
byte secondB = 6;
byte secondC = 7;
byte secondD = 8;
byte secondE = 9;
byte secondF = 4;
byte secondG = 3;

//Numbers
byte num0 = 0x3F;
byte num1 = 0x6;
byte num2 = 0x5B;
byte num3 = 0x4F;
byte num4 = 0x66;
byte num5 = 0x6D;
byte num6 = 0x7C;
byte num7 = 0x7;
byte num8 = 0x7F;
byte num9 = 0x6F;

//Keypad
const byte ROWS = 4; //four rows
const byte COLS = 3; //three columns
byte keys[ROWS][COLS] = {
    {'1','2','3'},
    {'4','5','6'},
    {'7','8','9'},
    {'0','0','0'}
};
byte rowPins[ROWS] = {41, 43, 45, 47}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {49, 51, 53}; //connect to the column pinouts of the keypad
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

//Wiring of pushbutton
byte pushbutton = 15;

//Wiring of lcd
LiquidCrystal_I2C lcd(0x27,16,2);  // set the LCD address to 0x27 for a 16 chars and 2 line display


//Auxiliaries
bool gameStarted = false;
long int nextSecond = 0;
byte secretCode[6];
byte currentDigit = 0;
byte errors = 0;
byte secretPressed[6];
byte tryes = 0;

void setup() {
  // put your setup code here, to run once:

  Serial.begin(9600);
  lcd.init();
  lcd.backlight();
  lcd.setCursor(5,0);
  lcd.print("THE BOMB");
  
  pinMode(firstA, OUTPUT);
  pinMode(firstB, OUTPUT);
  pinMode(firstC, OUTPUT);
  pinMode(firstD, OUTPUT);
  pinMode(firstE, OUTPUT);
  pinMode(firstF, OUTPUT);
  pinMode(firstG, OUTPUT);

  pinMode(secondA, OUTPUT);
  pinMode(secondB, OUTPUT);
  pinMode(secondC, OUTPUT);
  pinMode(secondD, OUTPUT);
  pinMode(secondE, OUTPUT);
  pinMode(secondF, OUTPUT);
  pinMode(secondG, OUTPUT);

  pinMode(pushbutton, INPUT);

}

void loop() {
  // put your main code here, to run repeatedly:

  if(gameStarted == false) {
    gameStart();
    gameStarted = true;
  }

  if(millis() > nextSecond) {
    countdown--;
    nextSecond = millis() + 1000;
  }

  if(countdown <= 0) {
    loser();
  }

  char key = keypad.getKey();
  
  if (key){

    secretPressed[currentDigit-1] = key;
    printToLCD();
    currentDigit++;

    if(currentDigit > 4) {
      if(verifyCode() == true) {
        //Combination guessed
        winner();
      } else {
        //Combination not guessed

        errors++;

        if(tryes > allowedErrors) {
          loser();
        } else {
          
          if(errors > cluesFrequence) {
            //Clue needed
            byte digit = random(1,5);
            secretPressed[digit] = secretCode[digit];
            tryes++;
          }
          
        }        
        
      }
    }

    delay(200);
    
  }
  
}

bool verifyCode() {

  byte guessed = 0;
  
  for(byte i = 0; i<=4; i++) {
    if(secretPressed[i] == secretCode[i]){
      guessed++;
    }
  }

  if(guessed >= 5) {
    return(true);
  } else {
    return(false);
  }
}

void winner() {
  
  lcd.clear();
  lcd.setCursor(5,0);
  lcd.print("THE BOMB");
  lcd.setCursor(1,1);
  lcd.print("BOMB DISENGAGED");
  
}

void loser() {
  //Bomb exploded

  lcd.clear();
  lcd.setCursor(5,0);
  lcd.print("THE BOMB");
  lcd.setCursor(1,1);
  lcd.print("BOMB EXPLODED!");
  
}

void printToLCD() {
  lcd.clear();
  lcd.setCursor(5,0);
  lcd.print("THE BOMB");

  for(byte i = 0; i <= currentDigit; i++) {
    lcd.setCursor(5+i,0);
    lcd.print(secretPressed[i]);
  }

  for(byte i = currentDigit; i <= 4; i++) {
    lcd.setCursor(5+i, 0);
    lcd.print("X");
  }
  
}

void printTime(byte remaining) {

  byte digit = remaining / 10;

  switch (digit) {

    case 0:
      firstDigitPrint(num0);
      break;

    case 1:
      firstDigitPrint(num1);
      break;

    case 2:
      firstDigitPrint(num2);
      break;

    case 3:
      firstDigitPrint(num3);
      break;

    case 4:
      firstDigitPrint(num4);
      break;

    case 5:
      firstDigitPrint(num5);
      break;

    case 6:
      firstDigitPrint(num6);
      break;

    case 7:
      firstDigitPrint(num7);
      break;

    case 8:
      firstDigitPrint(num8);
      break;

    case 9:
      firstDigitPrint(num9);
      break;

    default:
      firstDigitPrint(num0);
      Serial.println(F("Digits error"));
      break;
    
  }

  digit = remaining % 10;

  switch (digit) {

    case 0:
      secondDigitPrint(num0);
      break;

    case 1:
      secondDigitPrint(num1);
      break;

    case 2:
      secondDigitPrint(num2);
      break;

    case 3:
      secondDigitPrint(num3);
      break;

    case 4:
      secondDigitPrint(num4);
      break;

    case 5:
      secondDigitPrint(num5);
      break;

    case 6:
      secondDigitPrint(num6);
      break;

    case 7:
      secondDigitPrint(num7);
      break;

    case 8:
      secondDigitPrint(num8);
      break;

    case 9:
      secondDigitPrint(num9);
      break;

    default:
      secondDigitPrint(num0);
      Serial.println(F("Digits error"));
      break;
    
  }
  
}

void gameStart() {
  //Game starts
  //Waiting for the user to push the button
  Serial.println(F("Push the button to start..."));

  while(digitalRead(pushbutton)== HIGH) {
    //Wait for the button to be pressed
  }

  Serial.println(F("Game started"));

  //Generate secrete code
  randomSeed(analogRead(A0));
  secretCode[0] = random(0,9);
  secretCode[1] = random(0,9);
  secretCode[2] = random(0,9);
  secretCode[3] = random(0,9);
  secretCode[4] = random(0,9);

  gameStarted = false;
  errors = 0;
  currentDigit = 0;

  for(byte i = 0; i<=4; i++) {
    secretPressed[i]=0;
  }

  //Proceed
}

void firstDigitPrint(byte valore) {

  digitalWrite(firstA, bitRead(valore, 0));
  digitalWrite(firstB, bitRead(valore, 1));
  digitalWrite(firstC, bitRead(valore, 2));
  digitalWrite(firstD, bitRead(valore, 3));
  digitalWrite(firstE, bitRead(valore, 4));
  digitalWrite(firstF, bitRead(valore, 5));
  digitalWrite(firstG, bitRead(valore, 6));
  
}

void secondDigitPrint(byte valore) {

  digitalWrite(secondA, bitRead(valore, 0));
  digitalWrite(secondB, bitRead(valore, 1));
  digitalWrite(secondC, bitRead(valore, 2));
  digitalWrite(secondD, bitRead(valore, 3));
  digitalWrite(secondE, bitRead(valore, 4));
  digitalWrite(secondF, bitRead(valore, 5));
  digitalWrite(secondG, bitRead(valore, 6));
  
}

Connection diagram

Work flow

Source: Windows Questions C++

LEAVE A COMMENT