#include <Wire.h> // libreria para bus I2C
#include <Adafruit_GFX.h> // libreria para pantallas graficas
#include <Adafruit_SSD1306.h> // libreria para controlador SSD1306
#include <Keypad.h> // importa libreria Keypad
#include <Servo.h> // incluye libreria de Servo
#define trigPin A0
#define echoPin A1
#define buzzerPin A2
#define servoPin A3
#define button1Pin 9
#define button2Pin 10
#define button3Pin 11
#define ANCHO 128 // reemplaza ocurrencia de ANCHO por 128
#define ALTO 64 // reemplaza ocurrencia de ALTO por 64
#define UMBRAL_DISTANCIA 30 // en cm
const byte FILAS = 4; // define numero de filas
const byte COLUMNAS = 4; // define numero de columnas
char keys[FILAS][COLUMNAS] = { // define la distribucion de teclas
{ '1', '2', '3', 'A' },
{ '4', '5', '6', 'B' },
{ '7', '8', '9', 'C' },
{ '*', '0', '#', 'D' }
};
byte pinesFilas[FILAS] = { 8, 7, 6, 5 }; // pines correspondientes a las filas
byte pinesColumnas[COLUMNAS] = { 4, 3, 2, 1 }; // pines correspondientes a las columnas
#define OLED_RESET 4 // necesario por la libreria pero no usado
Adafruit_SSD1306 oled(ANCHO, ALTO, &Wire, OLED_RESET); // crea objeto
Keypad teclado = Keypad(makeKeymap(keys), pinesFilas, pinesColumnas, FILAS, COLUMNAS); // crea objeto
Servo servo1; // crea objeto
char TECLA; // almacena la tecla presionada
char CLAVE[5]; // almacena en un array 6 digitos ingresados
char CLAVE_MAESTRA[5] = "2002"; // almacena en un array la contraseña maestra
byte INDICE = 0; // indice del array
void setup() {
Wire.begin(); // inicializa bus I2C
oled.begin(SSD1306_SWITCHCAPVCC, 0x3C); // inicializa pantalla con direccion 0x3C
servo1.attach(servoPin); // inicializacion de servo
servo1.write(0); // Establece el ángulo inicial del servo
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
pinMode(buzzerPin, OUTPUT);
pinMode(button1Pin, INPUT_PULLUP);
pinMode(button2Pin, INPUT_PULLUP);
pinMode(button3Pin, INPUT_PULLUP);
digitalWrite(trigPin, OUTPUT);
noTone(buzzerPin);
// Muestra mensaje de bievenida en la pantalla
oled.clearDisplay(); // limpia pantalla
oled.setTextColor(WHITE); // establece color al unico disponible (pantalla monocromo)
oled.setCursor(50, 20); // ubica cursor en coordenas especificadas
oled.setTextSize(1); // establece tamaño de texto en 1
oled.print("PUERTA"); // escribe el texto
oled.setCursor(35, 30); // ubica cursor en coordenas especificadas
oled.setTextSize(1); // establece tamaño de texto en 1
oled.print("INTELIGENTE"); // escribe el texto
oled.setCursor(35, 40); // ubica cursor en coordenas especificadas
oled.setTextSize(1); // establece tamaño de texto en 1
oled.print("CON ARDUINO"); // escribe el texto
oled.display(); // muestra en pantalla todo lo establecido anteriormente
delay(1500);
oled.clearDisplay(); // limpia pantalla
}
void loop() {
oled.setTextColor(WHITE); // establece color al unico disponible (pantalla monocromo)
oled.setCursor(0, 0); // ubica cursor en coordenas especificadas
oled.setTextSize(1); // establece tamaño de texto en 1
oled.print("Ingrese Clave:"); // escribe el texto
oled.setCursor(0, 40); // ubica cursor en coordenas especificadas
oled.setTextSize(1); // establece tamaño de texto en 1
oled.print("Acerque su UID:"); // escribe el texto
oled.display(); // muestra en pantalla todo lo establecido anteriormente
acceso_teclado();
acceso_rfid();
}
void acceso_teclado() {
TECLA = teclado.getKey(); // obtiene tecla presionada y asigna a variable
if (TECLA) {
if (TECLA == '#') {
// Si se presiona '#', retrocede un paso en el índice
if (INDICE > 0) {
INDICE--;
CLAVE[INDICE] = '\0'; // Borra el dígito anterior
}
}
else {
// Almacena la tecla presionada en el array CLAVE
CLAVE[INDICE] = TECLA;
INDICE++;
}
oled.clearDisplay(); // Limpia la pantalla antes de mostrar las teclas
// Mostrar todas las teclas almacenadas
for (int i = 0; i < INDICE; i++) {
oled.setCursor(i * 8, 10); // Ajusta las coordenadas según sea necesario
oled.setTextSize(1);
oled.print("*");
oled.display();
}
}
if (INDICE == 4) // si ya se almacenaron los 4 digitos
{
if (!strcmp(CLAVE, CLAVE_MAESTRA)){ // compara clave ingresada con clave maestra
oled.setTextColor(WHITE); // establece color al unico disponible (pantalla monocromo)
oled.setCursor(0, 20); // ubica cursor en coordenas especificadas
oled.setTextSize(1); // establece tamaño de texto en 1
oled.print("Clave correcta"); // escribe el texto
oled.display();
control_acceso();
}
else{
oled.setTextColor(WHITE); // establece color al unico disponible (pantalla monocromo)
oled.setCursor(0, 20); // ubica cursor en coordenas especificadas
oled.setTextSize(1); // establece tamaño de texto en 1
oled.print("Clave incorrecta"); // escribe el texto
}
INDICE = 0;
}
}
void acceso_rfid(){
if (digitalRead(button1Pin) == LOW){
oled.setTextColor(WHITE); // establece color al unico disponible (pantalla monocromo)
oled.setCursor(0, 50); // ubica cursor en coordenas especificadas
oled.setTextSize(1); // establece tamaño de texto en 1
oled.print("Bienvenido, JHON TAPIERO"); // escribe el texto
oled.display();
control_acceso();
}
else if (digitalRead(button2Pin) == LOW){
oled.setTextColor(WHITE); // establece color al unico disponible (pantalla monocromo)
oled.setCursor(0, 50); // ubica cursor en coordenas especificadas
oled.setTextSize(1); // establece tamaño de texto en 1
oled.print("Bienvenido, usuario 2"); // escribe el texto
oled.display();
control_acceso();
}
else if (digitalRead(button3Pin) == LOW){
oled.setTextColor(WHITE); // establece color al unico disponible (pantalla monocromo)
oled.setCursor(0, 50); // ubica cursor en coordenas especificadas
oled.setTextSize(1); // establece tamaño de texto en 1
oled.print("Usuario desconocido"); // escribe el texto
}
}
/************************* Función para calcular la distancia en cm *********************************/
float calcularDistancia() {
// Declaración de variables locales
long duracion, distancia_calc;
// Genera un pulso ultrasónico
digitalWrite(trigPin, HIGH); // Establece el pin Trigger en estado alto
delayMicroseconds(10); // Pausa de 10 microsegundos
digitalWrite(trigPin, LOW); // Establece el pin Trigger en estado bajo
duracion = pulseIn(echoPin, HIGH); // Mide el tiempo de retorno del eco
// Cálculo de la distancia del objeto en cm
distancia_calc = (duracion / 2) / 29.1; // La velocidad del sonido es 343 m/s o 29.1 us/cm
return distancia_calc; // Devuelve el valor de la variable distancia
}
void control_acceso(){
servo1.write(90); // Establece el ángulo del servo
delay(10000);
long distancia;
distancia = calcularDistancia();
if (distancia > UMBRAL_DISTANCIA){
servo1.write(0); // Establece el ángulo del servo
oled.clearDisplay(); // Limpia la pantalla
}
else if (distancia > 2 and distancia <= UMBRAL_DISTANCIA){
while(1){
tone(buzzerPin, 300); // Se emite sonido través del buzzer
delay(10000);
noTone(buzzerPin);
long distancia;
distancia = calcularDistancia();
if (distancia > UMBRAL_DISTANCIA){
servo1.write(0); // Establece el ángulo del servo
oled.clearDisplay(); // Limpia la pantalla
break;
}
}
}
}