Código de la Bomba para gamificación

Como han solicitado el código que he realizado para hacer el proyecto, lo comparto en esta entrada. He cogido como base el código de Alexander Brevig para controlar una matriz de pulsadores y he añadido el código para controlar el LCD, el zumbador y el led.

/* 
** @version 1.0
** @author Roberto Suárez
**
** @description
** Programa que controla un lcd, zumbador y led, por medio de la entrada de datos de una teclado en matriz.
*/
#include <Keypad.h>
#include <LiquidCrystal_I2C.h>
#define CARACTERES 16


LiquidCrystal_I2C lcd(0x3F,CARACTERES,2); 

const byte ROWS = 4; //four rows
const byte COLS = 3; //three columns
char keys[ROWS][COLS] = {
  {'1','2','3'},
  {'4','5','6'},
  {'7','8','9'},
  {'*','0','#'}
};
byte rowPins[ROWS] = {3, 4, 5, 6}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {7, 8, 9}; //connect to the column pinouts of the keypad

Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

const int pinBuzzer=2;
const int pinLedR=11;
const int pinLedG=10;
const int PULSE= 500;
const int ALARM= 1000;
String clave="";
String pass="";
byte lengPass=4;
byte para=0;
unsigned long currentTime,finalTime, tempo, timeSound;
int timeSoundBoom=1000;

bool charIsNumber(char character){
    return (character>47 && character<58);
}
void keySound(){
  tone(pinBuzzer,PULSE, 50);
}
void alarmSound(){
  //digitalWrite(pinLedR,(!digitalRead(pinLedR)));
  tone(pinBuzzer,ALARM, 30);
  //if (timeSoundBoom<1000){tone(pinBuzzer,ALARM, 30);}
  digitalWrite(pinLedR,(!digitalRead(pinLedR)));
}

void clearLine(int line){
  lcd.setCursor(0,line);
  lcd.print("                ");
}

void centerPrint(String text, int line){
  int pos;
  pos=(CARACTERES-text.length())/2;
  lcd.setCursor(pos,line);
  lcd.print(text);
}

void centerPrintPass(String text, int line){
  int pos;
  int i;
  pos=(CARACTERES-text.length())/2;
  lcd.setCursor(pos,line);
  for (i=1; i<text.length();i++){
    lcd.print('*');
  }
  lcd.print(text[i-1]);
}

void inicioClave(){
  clearLine(1);
  lcd.setCursor(0,1);
  lcd.print("Clave: ");
}

void printTime(){
  long int t;
  int i=0;
  String timeText="";
  char buf[3]=" ";
  char* format="%02d";
  
    
  t=finalTime-currentTime;
  if (tempo>=3600){
    i=t/3600; // Calculo las horas
    sprintf(buf,format,(char) i);
    timeText=buf;
    timeText+=":";
  }
  i=((t-i*3600))/60; // Calculo los minutos restando las horas
  if (i>60){i=0;} //Verifico que no está a 60, esto significa que debe estar a 0 porque la unidad superior está completa
  sprintf(buf,format,(char) i);
  timeText+=buf;
  timeText+=":";
  i=t % 60; //Calculo los segundos
  //if (i>60){i=0;} //Verifico que no está a 60
  sprintf(buf,format,(char) i);
  timeText+=buf;
  centerPrint(timeText,0); //Imprimo el texto centrado en la línea 0
}

void solicitaClave(){
   char tecla;
   String aux="";
   lcd.clear();
   centerPrint("Introduce clave",0);
   tecla= keypad.getKey();
   lcd.cursor();
   while (tecla!='#'){
    /*Serial.print("La tecla es: ");
    Serial.print((byte)tecla);
    Serial.println(aux.length());*/
    if (tecla=='*'){
      keySound();
      aux="";
      clearLine(1);
    }
    else{
      
      if (aux.length()<4 && tecla>47 && tecla<58){
        keySound();
        aux+=tecla;
        centerPrintPass(aux,1);
      }
    }
   tecla= keypad.getKey();
  }
  keySound();
  lcd.noCursor();
  pass=aux;
}

void solicitaTiempo(){
   char tecla;
   char aux[6];
   int i; 
   
   for (i=0;i<6;i++){aux[i]='0';}
   i=1;
   lcd.clear();
   centerPrint("Introduce tiempo",0);
   centerPrint("00:00:00",1);
   lcd.setCursor(5,1);
   lcd.cursor();
   tecla= keypad.getKey();
   while (tecla!='#'){
    if (tecla=='*'){
       keySound();
       for (i=0;i<6;i++){aux[i]='0';}
       i=1;
       centerPrint("00:00:00",1);
       lcd.setCursor(5,1);
    }
    else{
      
      if (i<6 && tecla>47 && tecla<58){
        keySound();
        if (!(i%2)){if (tecla-48>5){tecla='5';}}  //No se puede poner números superiores al 5 en la segunda cifra de segundos y minutos
        aux[i]=tecla;
        lcd.print(aux[i]);       
        if (i==1){lcd.setCursor(7,1);}   //Si el indice es 1 o 3 tengo que reubicar el cursor
        else if (i==3){lcd.setCursor(10,1);}
        i++;
        //clearLine(1);
      }
    }
   tecla= keypad.getKey();
  }
  lcd.noCursor();
  tempo=((aux[0]-48)*10+(aux[1]-48))*3600+((aux[2]-48)*10+(aux[3]-48))*60+(aux[4]-48)*10+(aux[5]-48);
  keySound();
}
void setup(){
  Serial.begin(115200);

  pinMode(pinLedG, OUTPUT);
  pinMode(pinLedR, OUTPUT);
  digitalWrite(pinLedR,HIGH);
  delay(200);
  digitalWrite(pinLedR,LOW);
  digitalWrite(pinLedG,HIGH);
  lcd.init();                      // initialize the lcd 
  // Print a message to the LCD.
  lcd.backlight();
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("Bomba gamificada");
  lcd.setCursor(0,1);
  lcd.print("ROBERTO J.SUAREZ");
  delay(2000);
  solicitaTiempo();
  Serial.print("El tiempo fijado es: ");
  Serial.println(tempo);
  solicitaClave();
  Serial.println("La clave es: "+pass);
  currentTime=millis()/1000; 
  finalTime=currentTime+tempo;
  lcd.clear();
  timeSound=millis()+timeSoundBoom;
  digitalWrite(pinLedG,LOW);
}
  
void loop(){
  char key = keypad.getKey();
  if (!para){
    if (finalTime-currentTime<21){timeSoundBoom=400;}
    if (finalTime-currentTime<11){timeSoundBoom=300;}
    currentTime=millis();     //No lo divido por 1000 aún para utilizarlo en las lineas siguientes
    if (currentTime>timeSound){
      timeSound=currentTime+timeSoundBoom;
      alarmSound();
    }
    currentTime/=1000; //Guardo el inicio en segundos.
    printTime();
    if (finalTime<=currentTime){ //Se acabo el tiempo
      digitalWrite(pinLedR,HIGH);   //Dejo fijo el color rojo en el led
      para=1; // Se acaba el juego, perdiendo el jugador
      //Secuencia de exploción
    }
    
    if (key){
      if (charIsNumber(key)){
        if (clave==""){
          inicioClave();
        }
        keySound();
        clave+=key;
        lcd.setCursor(7,1);
        lcd.print(clave);
        if (clave.length()==lengPass){
         delay(500); 
         if (clave==pass){
            para=2;// Se acaba el juego, ganando el jugador
            digitalWrite(pinLedR,LOW);
            digitalWrite(pinLedG,HIGH);
         }
         else {
          clave="";
          clearLine(1);
          centerPrint("Clave incorrecta",1); //Imprimo en la línea 1 la frase centrada
          delay(500);
          inicioClave();
         }   
        }
      }
    }
  }
  else{
    lcd.clear();
    delay(500);
    //if (tempo>3600){centerPrint("00:00:00",0);}
    //else {centerPrint("00:00",0);}
    if (para==1){
      centerPrint("JUEGO FINALIZADO",0);
      centerPrint("BOMBA DETONADA",1);  
    }
    else{
      centerPrint("BOMBA",0);
      centerPrint("DESACTIVADA",1);
      delay(2000);
    }
    delay(1000);
  }
}

```