Actividad. Funcionalidad elemental caja fuerte.

PROGRAMACIÓN EXTENDIDA


Montaje

 

Montaje eléctrico. Conexiones

Para implementar la lógica de una caja fuerte con una combinación de 4 dígitos, utilizaremos el potenciómetro para seleccionar los dígitos, una pantalla LCD para mostrar los dígitos seleccionados, y un pulsador para introducir el dígito. Si el código es correcto, la puerta se abre. 

En esta activada trabajaremos con las funciones en C y el objetivo será poner en común los montajes de las dos actividades anteriores, de manera que logremos obtener una programación básica de la lógica de la caja fuerte.

Si has seguido las dos actividades anteriores correctamente, no deberás realizar ninguna nueva conexión para este montaje; utilizaremos el montaje anterior.

Programación

 

Explicación actividad a programar.

Vamos a partir de los dos códigos realizados anteriormente. Recomendamos seguir los siguientes pasos como guía a la hora de realizar la programación de esta actividad.

  1. Utiliza funciones en c para agrupar los comandos/acciones de apertura y cierre de la caja. Es decir, una función que, al ser llamada, realice la apertura de la compuerta. Y, de la misma manera, una función que nos permita bloquear la puerta.

  2. La cámara comienza en un estado inicial estando bloqueada. Por lo tanto, en el setup() deberás tener esto en cuenta, además de haber configurado las entradas y salidas. 

  3. Se debe mostrar un mensaje estático de bienvenida en la pantalla durante unos breves segundos. Por ejemplo:
    [  Cámara ][   Acorazada]

  4. Como pantalla principal, podrías poner: [Dial: ][ Code: ] En donde el dial es el digito en tiempo real del potenciómetro, y code es el código introducido.

  5. En el bucle principal deberás leer continuamente las entradas a la espera de que el usuario presione el pulsador o mueva el potenciómetro. Deberás  refrescar la pantalla acorde.

  6. Si se pulsa el botón de "Enter"(pulsador), el digito actual del dial analógico se cargará en la posición de miles (ejemplo: 4XXX).  Esto se repetirá para las 4 posiciones (miles, centenas, decenas y unidades). Una vez introducidos los 4 dígitos, se comprobará si el código introducido coincide con el código de desbloqueo. Si es así, se abre la compuerta y se muestra por pantalla "Cámara abierta". Si no coincide el código, se muestra en pantalla "Código erróneo". Tras 2 segundos, el código introducido se borra y se le da la oportunidad al usuario de introducir un nuevo código.


Variables importantes

Se define una variable booleana isBoxOpen para llevar el seguimiento del estado de la caja fuerte (abierta o cerrada), inicializándola como cerrada. También se definen enteredDigit para almacenar el dígito introducido mediante el potenciómetro, enteredCode para almacenar el código introducido por el usuario, y currentDigitIndex para llevar el índice del dígito actual. Además, se define correctCode como el código correcto que debe ser introducido para abrir la caja (en este caso, 1234).


Funciones Auxiliares

Sugerimos la implemtación de las siguientes funciones:

  • updateLCD(): Actualiza la pantalla LCD para mostrar el código introducido.
  • resetCode(): Reinicia el código introducido.
  • checkCode(): Verifica si el código introducido es correcto.
  • openBox(): Abre la caja fuerte, cambiando el estado de los LEDs y moviendo el servomotor.
  • closeBox(): Cierra la caja fuerte, cambiando el estado de los LEDs y moviendo el servomotor.

  • Importar las librerías necesarias  para el servo y la pantalla LCD por i2c. Se realiza la declaración de pines físicos conectados.

    En la función setup, se configuran los pines correspondientes al potenciómetro, los pulsadores, los LEDs y el servo. La pantalla LCD se inicializa y se enciende su retroiluminación El servo se coloca en la posición de bloqueo (90 grados). Se muestra un mensaje inicial de bienvenida en la pantalla LCD y, tras ello, se le indica al usuario puede comenzar a introducir el código.
    Para hacer una programación segura del Puente Levadizo teniendo en cuenta la posición de la plataforma, deberemos utilizar condicionales de múltiples condiciones. Aunque podemos emplear un condicional dentro de otro, es más acertado emplear la concatenación de condiciones. Esto se hace de la siguiente manera:

    if(condición 1 && condición 2) {

    // Líneas a ejecutar si se cumplen ambas condiciones

    }

    donde "condición 1" y "condición 2" están concatenadas con el operador condicional "&&" o "Y". Este condicional ejecuta las líneas encerradas entre los corchetes solamente cuando se cumplan o sean ciertas ambas condiciones "condición 1" y "condición 2".

    Otro operador de este tipo muy común es "||" o "O", que permite ejecutar las líneas próximas si se cumple alguna de las condiciones "condición 1" o "condición 2".
    //Ejemplo de funciones de apertura y cierre.
    void openBox() {
        isBoxOpen = true;
        digitalWrite(ledRedPin, LOW);    // Apagar LED rojo
        digitalWrite(ledGreenPin, HIGH); // Encender LED verde
        digitalWrite(ledBluePin, LOW);   // Apagar LED azul
        myServo.write(0);  // 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(90);  // Mover el servo a la posición de bloqueo
    }
    void resetCode() {
        currentDigitIndex = 0;
        for (int i = 0; i < 4; i++) {
            enteredCode[i] = 0;
        }
    }

    bool checkCode() {
        for (int i = 0; i < 4; i++) {
            if (enteredCode[i] != correctCode[i]) {
            return false;
            }
        }
        return true;
    }
    #include <Wire.h>
    #include <LiquidCrystal_I2C.h>
    #include <Servo.h>

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

    // Definición de pines
    const int potPin = A0;          // Pin del potenciómetro
    const int enterButtonPin = 2;   // Pin del pulsador para introducir dígito
    const int clearButtonPin = 3;   // Pin del pulsador para borrar código
    const int ledRedPin = 9;        // Pin del LED rojo
    const int ledGreenPin = 10;     // Pin del LED verde
    const int ledBluePin = 11;      // Pin del LED azul
    const int servoPin = 6;         // Pin del servomotor

    // Crear objeto Servo
    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] = {1, 2, 3, 4};  // Código correcto (por ejemplo, 1234)

    void setup() {
        // Inicializar pantalla LCD
        lcd.init();
        lcd.backlight();

        // Configuración de pines
        pinMode(potPin, INPUT);
        pinMode(enterButtonPin, INPUT);
        pinMode(clearButtonPin, INPUT);
        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(90); // 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);

        // 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);
        bool clearButtonState = digitalRead(clearButtonPin);

        // 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
        if (currentDigitIndex == 4) {
            if (checkCode()) {
            openBox();
            } else {
            resetCode();
            updateLCD();
            }
        }

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

    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(0);  // 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(90);  // Mover el servo a la posición de bloqueo
    }
    Vistas
    2 Número de vistas
    2 Vistas de miembros
    0 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.