Actividad. Sistema de alarma con zumbador

TEMÁTICAS DE NUESTROS CURSOS


Montaje

 

Montaje eléctrico. Conexiones

En esta actividad utilizaremos el código de la actividad anterior, al cual incorporaremos nuevas funcionalidades. Mantendremos la misma programación y montaje que en la actividad anterior, con los siguientes cambios y mejoras:
Uno de los pulsadores tendrá la función de "enter", que nos servirá para introducir el dígito y otro pulsador con la funcionalidad de "suprimir" para borrar el código introducido. 
Si el código introducido es correcto, la puerta se abre y se mantendrá abierta hasta que se pulsen ambos botones simultáneamente para volver a cerrar la caja.
Añadiremos también un zumbador activo, que nos permitirá implementar un sistema de alarma. Este zumbador se activará si se ingresan demasiados códigos incorrectos consecutivamente.


Programación

 

Explicación actividad a programar.

Partiendo del código funcional elaborado en la actividad anterior, se pide incorporar las siguientes funcionalidades:

  1. Si durante la introducción del código, se pulsa el botón de "BORRAR", el código introducido se borra inmediatamente.

  2. Si ,estando la caja abierta, se presionan ambos botones simultáneamente, ésta se cierra.

  3. Si se introducen 10 códigos incorrectos sucesivamente, se dispara la alarma. Esta alarma consiste en activar el zumbador.

  4. Cada vez que se introduzca un código incorrecto, se mostrará por pantalla "Código incorrecto", seguido de un indicador de numero de "intentos restantes". 

  5. Si se introduce el código correcto, el contador de intentos restantes se reinicia (se permiten 10 intentos).

  6. Cada vez que se detecta una pulsación en cualquier botón, y cada vez que el numero del dial se modifica, el zumbador emite un pitido corto (duración: 50ms)

Variables de importancia

Además de las variables de estado previamente definidas (isBoxOpen, enteredDigit, enteredCode, currentDigitIndex y correctCode), se han añadido attemptsLeft y incorrectAttempts para llevar un registro de los intentos restantes y los intentos incorrectos.

Funciones Auxiliares

Además de las funciones updateLCD(), resetCode(), checkCode(), openBox(), y closeBox(), trabajadas en la actividad anterior, se añaden activateAlarm() para activar la alarma cuando se alcanzan 10 intentos incorrectos y resetAttempts() para reiniciar el contador de intentos.

El zumbador activo se considera un actuador digital, por lo tanto se configurará como una salida digital en la función setup(). Activando en alta dicho pin, el zumbador comenzará a emitir un pitido continuo, muy molesto y que poco recuerda a una alarma. Para generar una secuencia de alarma, lo mas sencillo consiste en crear un bucle infinito y dentro de dicho bucle, activar durante un tiempo y desactivar durante otro cierto tiempo el zumbador. Por ejemplo, un segundo activo y otro segundo apagado. También se pueden crear secuencias mas elaboradas, como tres pitidos cortos seguidos de una pausa larga.
En la función loop, al igual que en la actividad anterioir, se lee el valor del potenciómetro y se convierte en un dígito del 0 al 9, que se muestra en la pantalla LCD. También se leen leen los estados de los dos pulsadores. A continuación, procedemos a realizar todas las comprobaciones pertinentes:  

Si el dígito del dial ha cambiado, o se ha pulsado cualquier boton, emitir un corto pitido a través del zumbador.
Si se ha presionado el botón de introducir dígito, el dígito seleccionado en el dial se almacena en enteredCode y se actualiza la pantalla.
Si se ha presionado el botón de borrar, el código introducido se reinicia y se actualiza la pantalla.
Si se han introducido 4 dígitos, se verifica si el código es correcto. Si es correcto, se abre la caja y se reinicia el contador de intentos restantes. Si no es correcto, se incrementa el contador de intentos incorrectos y se reduce el número de intentos restantes. Se muestra un mensaje en la pantalla LCD indicando que el código es incorrecto y los intentos restantes. Si se alcanzan 10 intentos incorrectos, se activa la alarma.
Si la caja se encuentra abierta, y se pulsan ambos botones, ésta procede a bloquearse
void activateAlarm() {
    for (int i = 0; i < 10; i++) {
        tone(buzzerPin, 1000); // Activar el zumbador
        delay(500);
        noTone(buzzerPin);     // Desactivar el zumbador
        delay(500);
    }
    incorrectAttempts = 0; // Reiniciar el contador de intentos incorrectos después de la alarma
    attemptsLeft = 10;     // Reiniciar los intentos restantes
}

void resetAttempts() {
    incorrectAttempts = 0;
    attemptsLeft = 10;
}
#include <Servo.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>

// Configuración de la pantalla LCD I2C
LiquidCrystal_I2C lcd(0x27, 16, 2);  // Dirección I2C 0x27 para una pantalla LCD de 16x2

// Pines
const int potPin = A0;
const int enterButtonPin = 2;
const int clearButtonPin = 3;
const int ledRedPin = 9;
const int ledGreenPin = 10;
const int ledBluePin = 11;
const int servoPin = 6;
const int buzzerPin = 7;        // Pin del zumbador

Servo myServo;

// Variables de estado
bool isBoxOpen = false;          // Estado de la caja (cerrada por defecto)
int enteredDigit = 0;            // Dígito introducido por el potenciómetro
int enteredCode[4];              // Código introducido por el usuario
int currentDigitIndex = 0;       // Índice del dígito actual
const int correctCode[4] = {6, 6, 6, 6};  // Código correcto (por ejemplo, 1234)
int attemptsLeft = 10;           // Intentos restantes
int incorrectAttempts = 0;       // Contador de intentos incorrectos

void setup() {

    Serial.begin(9600);
  // Inicializar pantalla LCD
    lcd.init();
    lcd.backlight();
    lcd.clear();

    // Configuración de pines
    pinMode(potPin, INPUT);
    pinMode(enterButtonPin, INPUT_PULLUP);
    pinMode(clearButtonPin, INPUT_PULLUP);

    pinMode(ledRedPin, OUTPUT);
    pinMode(ledGreenPin, OUTPUT);
    pinMode(ledBluePin, OUTPUT);
    myServo.attach(servoPin);

    // Inicializar LED y servo
    digitalWrite(ledRedPin, HIGH); // Encender LED rojo
    digitalWrite(ledGreenPin, LOW); // Apagar LED verde
    digitalWrite(ledBluePin, LOW); // Apagar LED azul
    myServo.write(0); // Mover el servo a la posición de bloqueo

    // Mostrar mensaje inicial en LCD
    lcd.setCursor(0, 0);
    lcd.print("Dial:");
    lcd.setCursor(0, 1);
    lcd.print("Code:");
}

void loop() {
    // Leer el valor del potenciómetro
    int potValue = analogRead(potPin);
    enteredDigit = map(potValue, 0, 1023, 0, 9);

    lcd.clear();
    // Mostrar mensaje inicial en LCD
    lcd.setCursor(0, 0);
    lcd.print("Dial:");
    lcd.setCursor(0, 1);
    lcd.print("Code:");
    // Mostrar el dígito en la pantalla LCD
    lcd.setCursor(5, 0); // Colocar el cursor en la columna 5, fila 0
    lcd.print(enteredDigit);

    // Leer los estados de los pulsadores
    bool enterButtonState = digitalRead(enterButtonPin) == LOW;
    bool clearButtonState = digitalRead(clearButtonPin) == LOW;

    // Borrar el código si se presiona el botón de borrar
    if (clearButtonState) {
    resetCode();
    updateLCD();
    delay(300); // Para evitar rebotes
    }


    // Introducir el dígito si se presiona el botón de introducir dígito
    if (enterButtonState && currentDigitIndex < 4) {
        enteredCode[currentDigitIndex] = enteredDigit;
        currentDigitIndex++;
        updateLCD();
        delay(300); // Esperar para evitar lecturas múltiples por rebote
    }

    // Verificar el código si se han introducido 4 dígitos
    // Verificar el código si se han introducido 4 dígitos
    if (currentDigitIndex == 4) {
        if (checkCode()) {
        openBox();
        resetAttempts();
        } else {
        incorrectAttempts++;
        attemptsLeft--;
        lcd.clear();
        lcd.setCursor(0, 1);
        lcd.print("Cod. incorrecto  ");
        delay(1000);
        lcd.clear();
        lcd.setCursor(0, 1);
        lcd.print("Intentos: ");
        lcd.print(attemptsLeft);
        delay(1000);
        resetCode();
        updateLCD();
        if (incorrectAttempts >= 10) {
            activateAlarm();
        }
        }
    }

    // Cerrar la caja si se presionan ambos botones simultáneamente
    if (enterButtonState && clearButtonState) {
        closeBox();
        delay(300); // Esperar para evitar lecturas múltiples por rebote
    }

    // Esperar un poco antes de la siguiente lectura
    delay(200);

}

void resetCode() {
    currentDigitIndex = 0;
    for (int i = 0; i < 4; i++) {
        enteredCode[i] = 0;
    }
}

void updateLCD() {
    lcd.setCursor(5, 1); // Colocar el cursor en la columna 5, fila 1
    for (int i = 0; i < 4; i++) {
        if (i < currentDigitIndex) {
        lcd.print(enteredCode[i]);
        } else {
        lcd.print("_");
        }
    }
}

bool checkCode() {
    for (int i = 0; i < 4; i++) {
        if (enteredCode[i] != correctCode[i]) {
        return false;
        }
    }
    return true;
}

void openBox() {
    isBoxOpen = true;
    digitalWrite(ledRedPin, LOW);    // Apagar LED rojo
    digitalWrite(ledGreenPin, HIGH); // Encender LED verde
    digitalWrite(ledBluePin, LOW);   // Apagar LED azul
    myServo.write(90);  // Mover el servo a la posición de desbloqueo
}

void closeBox() {
    isBoxOpen = false;
    digitalWrite(ledRedPin, HIGH);   // Encender LED rojo
    digitalWrite(ledGreenPin, LOW);  // Apagar LED verde
    digitalWrite(ledBluePin, LOW);   // Apagar LED azul
    myServo.write(0);  // Mover el servo a la posición de bloqueo
}

void activateAlarm() {
    for (int i = 0; i < 10; i++) {
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("ALARMA ACTIVA");
        tone(buzzerPin, 1000); // Activar el zumbador
        delay(500);
        noTone(buzzerPin);     // Desactivar el zumbador
        delay(500);
    }
    incorrectAttempts = 0; // Reiniciar el contador de intentos incorrectos después de la alarma
    attemptsLeft = 10;     // Reiniciar los intentos restantes
}

void resetAttempts() {
    incorrectAttempts = 0;
    attemptsLeft = 10;
}
Vistas
10 Número de vistas
2 Vistas de miembros
8 Vistas públicas
Acciones
0 Gustos
0 No me gusta
0 Comentarios
Compartir en redes sociales
Compartir enlace
Compartir por correo

Por favor iniciar sesión para compartir esto webpage por correo.