#include <Keypad.h>


/**************************************
   Variables y constantes globales
***************************************/


// NULL
#define STR_NULL ""

// Claves del sistema
String claves[] = {
                    "12A4",
                    "79BC",
                    "3A4D",
                    "5086",
                    STR_NULL
                  };

// Estados del sistema
#define SOLICITUD_CLAVE 0
#define INGRESO_CLAVE 1
#define VALIDACION 2
#define ACCESO 3
#define NO_ACCESO 4

// clave ingresada
#define TAM 11
char clave_ingresada[TAM];

// Variable que almacena el estado del sistema
int estado; 
int i;
char tecla;    // Tecla ingresada

/**************************************
   Definicion de funciones
***************************************/

bool validar_clave(String clave_ingresada, String claves_sistema[]);
void yellow_light(void);
void green_light(void);
void red_light(void);
void light_off(void);


/**************************************
   Definicion de pines del sistema
***************************************/

#define row1 13
#define row2 12
#define row3 9
#define row4 8

#define col1 7
#define col2 6
#define col3 4
#define col4 2

#define red_pin 11
#define green_pin 10
#define blue_pin 5

const byte ROWS = 4; /* four rows */
const byte COLS = 4; /* four columns */

/* define the symbols on the buttons of the keypads */
char keyMap[ROWS][COLS] = {
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'*','0','#','D'}
};

byte rowPins[ROWS] = {row1, row2, row3, row4}; /* connect to the row pinouts of the keypad */
byte colPins[COLS] = {col1, col2, col3, col4}; /* connect to the column pinouts of the keypad */

/* initialize an instance of class NewKeypad */
Keypad teclado = Keypad( makeKeymap(keyMap), rowPins, colPins, ROWS, COLS); 

/**************************************
   Inicializacion del sistema
***************************************/

void setup() {
  Serial.begin(9600);
  Serial.println("**** Sistema de control de acceso simple ****\n");
  pinMode(red_pin, OUTPUT);
  pinMode(green_pin, OUTPUT);
  pinMode(blue_pin, OUTPUT);
  // Inicializar variables
  i = 0;
  estado = SOLICITUD_CLAVE;
  light_off();
  delay(1000);
}

/**************************************
   Ciclo infinito
***************************************/

void loop() {  
  // Estados del sistema
  switch(estado) {
    case ACCESO:
      green_light();
      Serial.println("<< Acceso concedido >>");
      Serial.println("Abriendo puerta...");
      delay(3000);
      Serial.println("Cerrando puerta...");
      estado = SOLICITUD_CLAVE;
      break;
    case NO_ACCESO:
      red_light();
      Serial.println("<< Acceso denegado >>");
      delay(1000);
      estado = SOLICITUD_CLAVE;
      break;
    case SOLICITUD_CLAVE:
      red_light();
      Serial.print("Digite la clave de acceso: ");
      estado = INGRESO_CLAVE;
      break;
    case INGRESO_CLAVE:
      yellow_light();
      tecla = teclado.getKey();
      // Clave
      if(tecla){
        if(tecla != '#') {
          Serial.print(tecla);
          clave_ingresada[i] = tecla;
          i++;
        }
        else {
          clave_ingresada[i] = '\0';
          Serial.println();
          i = 0;
          estado = VALIDACION;
        }
      }
      break;
    case VALIDACION:
      // Clave
      String clave_str(clave_ingresada);
      if(validar_clave(clave_str, claves)) {
        estado = ACCESO;
      }
      else {
        estado = NO_ACCESO;
      }
      break;    
  }
}

/**************************************
   Definicion de funciones
***************************************/

/* Funcion para la validacion de la clave */

bool validar_clave(String clave_ingresada, String claves_sistema[]) {
  int i = 0;
  // Serial.println(clave_ingresada);
  bool resultado = false;
  while(claves_sistema[i] != NULL) {
    // Serial.println(claves_sistema[i]);
    if(clave_ingresada == claves_sistema[i]) {
      resultado = true;
      break;
    }
    i++;
  }
  // Serial.println(resultado);
  return resultado;
} 

/* Funciones para definir el color de iluminacion del led RGB */

void yellow_light(void) {
  analogWrite(red_pin,0);
  analogWrite(green_pin,0);
  analogWrite(blue_pin,255);
}

void green_light(void) {  
  analogWrite(red_pin,255);
  analogWrite(green_pin,0);
  analogWrite(blue_pin,255);
}

void red_light(void) {
  analogWrite(red_pin,0);
  analogWrite(green_pin,255);
  analogWrite(blue_pin,255);
}

void light_off(void) {
  analogWrite(red_pin,255);
  analogWrite(green_pin,255);
  analogWrite(blue_pin,255);
}
$abcdeabcde151015202530354045505560fghijfghij