DÍA 248 DE 365

Fase 5: Diseño Industrial y Proyecto Final

📖 Teoría a Estudiar

El Estándar Visual Andon (Poka-Yoke Visual)

En el sector industrial, no puedes inventar tus propios códigos de colores. Tienes que seguir los estándares universales de las plantas (OSHA / Andon) para que cualquier técnico que vea tu máquina, sepa su estado inmediatamente.

Aislamiento Galvánico (Evitando explosiones en la PCB)

Una baliza LED industrial suele alimentarse con la fuente principal de 24V de la gasolinera. Tu STM32F401 es de 3.3V. Si el cable de la baliza sufre un cortocircuito allá arriba en el techo, los 24V regresarán por el cable directo hacia el pin de tu microcontrolador. El procesador explotará literalmente.

Para evitarlo, interponemos un Optoacoplador (ej. PC817). El STM32 solo enciende un pequeño LED infrarrojo encapsulado. La luz infrarroja cruza un vacío de plástico y excita un fototransistor del lado de los 24V, el cual activa un Relé o un MOSFET de potencia. Si los 24V hacen corto, quemarán el fototransistor, pero la luz no conduce electricidad hacia atrás: tu STM32 estará 100% a salvo.

ARQUITECTURA VISUAL: AISLAMIENTO GALVÁNICO Y BALIZAS (ANDON) ZONA SEGURA (3.3V) STM32 MCU PA5 Verde PA6 Ámbar PA7 Rojo AISLAMIENTO ÓPTICO GND Digital ZONA DE POTENCIA (24V DC) Relé G Relé Y Relé R GND Potencia (Chasis) Paro Emergencia Aviso / Mantenim. Reposo / Despacho

⚙️ Ejercicios Prácticos

Desacoplando el Software: Si colocas HAL_GPIO_WritePin directamente dentro de tus rutinas de metrología o seguridad, tu código se volverá un desastre acoplado ("Código Espagueti"). Según MISRA-C y las buenas prácticas de Ingeniería de Software, debe existir un solo lugar (una sola tarea) encargada de las luces. Esa tarea "observará" el estado global de la máquina y decidirá cómo parpadear.

Ejercicio 1: La Máquina de Estados Visual no bloqueante. Programaremos la Tarea Task_Balizas_Andon. Utilizaremos el reloj interno del sistema (Ticks) para generar un parpadeo de 500 milisegundos sin congelar el RTOS.


/**
 * @file balizas_andon.c
 * @brief Lógica visual de Estado de Máquina (Torre de Luces IP67)
 *        Control No Bloqueante - Cumplimiento MISRA-C
 */

#include "stm32f401xe.h"
#include "cmsis_os2.h"
#include <stdint.h>
#include <stdbool.h>

// =========================================================================
// DEFINICIONES DE HARDWARE (Mapeo a la etapa de Optoaislamiento)
// =========================================================================
#define PORT_BALIZAS            GPIOA
#define PIN_BALIZA_VERDE        GPIO_PIN_5
#define PIN_BALIZA_AMBAR        GPIO_PIN_6
#define PIN_BALIZA_ROJA         GPIO_PIN_7

// Frecuencia de parpadeo (500 ms encendido, 500 ms apagado = 1 Hz)
#define FRECUENCIA_BLINK_MS     (500U)

// =========================================================================
// ESTADOS GLOBALES DE LA MÁQUINA (Importados de FSM Principal)
// =========================================================================
typedef enum {
    ESTADO_INICIALIZANDO  = 0U,
    ESTADO_REPOSO         = 1U,
    ESTADO_DESPACHANDO    = 2U,
    ESTADO_MANTENIMIENTO  = 3U,
    ESTADO_EMERGENCIA     = 4U
} FSM_Estado_t;

// Variable global asíncrona actualizada por el Core de la aplicación
extern volatile FSM_Estado_t estado_maquina_actual;

// =========================================================================
// FUNCIONES AUXILIARES DE HARDWARE
// =========================================================================
/**
 * @brief Apaga todos los LEDs de la torre simultáneamente para evitar 
 *        mezclas de colores extrañas (Ghosting visual).
 */
static void Balizas_Apagar_Todas(void) {
    HAL_GPIO_WritePin(PORT_BALIZAS, PIN_BALIZA_VERDE, GPIO_PIN_RESET);
    HAL_GPIO_WritePin(PORT_BALIZAS, PIN_BALIZA_AMBAR, GPIO_PIN_RESET);
    HAL_GPIO_WritePin(PORT_BALIZAS, PIN_BALIZA_ROJA,  GPIO_PIN_RESET);
}

// =========================================================================
// TAREA RTOS: MANEJADOR VISUAL (HMI)
// =========================================================================
void Task_Balizas_Andon(void *argument) {
    
    // Variables de control de parpadeo (Toggle)
    bool toggle_blink = false;
    uint32_t ultimo_tick_blink = osKernelGetTickCount();
    
    // Asegurar apagado inicial al encender la máquina
    Balizas_Apagar_Todas();
    
    for(;;) {
        // 1. Gestión del Reloj de Parpadeo (Generador de Señal Cuadrada Lógica)
        uint32_t tick_actual = osKernelGetTickCount();
        if ((tick_actual - ultimo_tick_blink) >= FRECUENCIA_BLINK_MS) {
            toggle_blink = !toggle_blink;        // Invertir el booleano
            ultimo_tick_blink = tick_actual;     // Resetear cronómetro
        }
        
        // 2. Extraer el estado actual del núcleo de la aplicación de forma atómica
        taskENTER_CRITICAL();
        FSM_Estado_t estado_gas = estado_maquina_actual;
        taskEXIT_CRITICAL();
        
        // 3. Evaluar y Traducir Lógica a Luz (Patrones Andon)
        switch (estado_gas) {
            
            case ESTADO_INICIALIZANDO:
                // Prender todas para probar los focos (Self-Test)
                HAL_GPIO_WritePin(PORT_BALIZAS, PIN_BALIZA_VERDE, GPIO_PIN_SET);
                HAL_GPIO_WritePin(PORT_BALIZAS, PIN_BALIZA_AMBAR, GPIO_PIN_SET);
                HAL_GPIO_WritePin(PORT_BALIZAS, PIN_BALIZA_ROJA,  GPIO_PIN_SET);
                break;
                
            case ESTADO_REPOSO:
                Balizas_Apagar_Todas();
                // Verde Sólido = Listo para venta
                HAL_GPIO_WritePin(PORT_BALIZAS, PIN_BALIZA_VERDE, GPIO_PIN_SET);
                break;
                
            case ESTADO_DESPACHANDO:
                Balizas_Apagar_Todas();
                // Verde Parpadeante = Operación en curso
                if (toggle_blink) {
                    HAL_GPIO_WritePin(PORT_BALIZAS, PIN_BALIZA_VERDE, GPIO_PIN_SET);
                } else {
                    HAL_GPIO_WritePin(PORT_BALIZAS, PIN_BALIZA_VERDE, GPIO_PIN_RESET);
                }
                break;
                
            case ESTADO_MANTENIMIENTO:
                Balizas_Apagar_Todas();
                // Ámbar Sólido = Falla de conectividad o humedad detectada
                HAL_GPIO_WritePin(PORT_BALIZAS, PIN_BALIZA_AMBAR, GPIO_PIN_SET);
                break;
                
            case ESTADO_EMERGENCIA:
                Balizas_Apagar_Todas();
                // Rojo Parpadeante = Peligro letal (Fuga / Sabotaje)
                if (toggle_blink) {
                    HAL_GPIO_WritePin(PORT_BALIZAS, PIN_BALIZA_ROJA, GPIO_PIN_SET);
                } else {
                    HAL_GPIO_WritePin(PORT_BALIZAS, PIN_BALIZA_ROJA, GPIO_PIN_RESET);
                }
                break;
                
            default:
                // MISRA-C: Falla de Software (Corrupción de Memoria)
                Balizas_Apagar_Todas();
                HAL_GPIO_WritePin(PORT_BALIZAS, PIN_BALIZA_ROJA, GPIO_PIN_SET);
                break;
        }
        
        // Ciclo de evaluación súper rápido. El parpadeo se controla por el 'toggle_blink'
        // no por este delay, por lo que la baliza es sumamente responsiva a cambios de estado.
        osDelay(pdMS_TO_TICKS(50U)); 
    }
}
        

🚀 Avance del Proyecto Tesis: Despachador de Gas LP

Objetivo del día: Ergonomía Industrial (Poka-Yoke) y Seguridad Galvánica.

Un despachador de gas comete errores humanos. Si cree que la máquina terminó de despachar pero aún hay presión remanente, desconectará la manguera y liberará gas inflamable al ambiente. En la industria manufacturera japonesa inventaron el concepto **Poka-Yoke (A prueba de errores)**. Al vincular el parpadeo de la baliza verde directamente al estado de la válvula (`ESTADO_DESPACHANDO`), le estás gritando visualmente al operador: *"Mientras la luz parpadee, no toques la manguera"*.

A nivel de hardware, tu diseño brilló por la inclusión del **Aislamiento Óptico (Optoacopladores)**. En un entorno real, un camión puede golpear la torre de luces, arrancando los cables y juntando los 24V de potencia con las líneas de datos. Si tuvieras una conexión directa o por transistores simples, tu cerebro electrónico (STM32) quedaría frito en microsegundos, borrando las ventas no enviadas a AWS. Gracias a la barrera galvánica del fototransistor, la placa de control jamás toca los electrones de la calle. Tu STM32 sigue con vida, registra el incidente de hardware y transmite la bitácora de auditoría a la nube. Una obra maestra de la resiliencia.

📝 Resumen del Día