DÍA 357 DE 365

Fase 5: Diseño Industrial y Hardware

📖 Teoría a Estudiar

El Entorno Hostil y la Carga Cognitiva

En el desarrollo de software web o móvil, asumes que el usuario está sentado, prestando atención y en un entorno con clima controlado. En sistemas embebidos industriales, debes diseñar para el "Peor Escenario". El operador de la gasera puede estar lidiando con ruido extremo, fatiga, prisa y reflejos solares cegadores. Si la pantalla muestra mucha información simultánea, aumenta la Carga Cognitiva. El cerebro tarda más en procesar qué botón presionar, aumentando exponencialmente la tasa de error.

El Problema del "Fat Finger" y la Confirmación Lógica

Los botones táctiles capacitivos son excelentes para una cocina moderna, pero son inútiles en una planta de gas. El operador lleva guantes de cuero grueso. Necesitas botones mecánicos con Feedback Táctil (que hagan un "clic" fuerte). Además, el espaciado físico debe ser de al menos 20 mm entre botones para evitar presionar dos a la vez (El efecto "Fat Finger"). A nivel de firmware, las acciones irreversibles (como iniciar el despacho o borrar los totales del día) jamás deben ejecutarse con un solo clic accidental; exigen el patrón Hold-to-Confirm (Mantener presionado para confirmar).

ARQUITECTURA DE UI/UX PARA ENTORNOS INDUSTRIALES HOSTILES VOLUMEN A DESPACHAR 100.0 L MANTENER BOTÓN START 2s START DISPLAY TRANSFLECTIVO Fondo claro y píxeles oscuros. La luz solar directa MEJORA el contraste en lugar de cegarlo. LEY DE FITTS (VISUAL) El dato crítico (Litros) ocupa el 60% de la pantalla para lectura rápida a 2 metros. AISLAMIENTO FÍSICO Separación > 30mm. Imposible presionar dos botones a la vez, incluso con guantes. HOLD-TO-CONFIRM Acción protegida por Timer. Evita arranques de bomba por golpes accidentales.

⚙️ Procedimiento Práctico: Implementando Protecciones Lógicas

Paso 1: Elección de Pantalla (Hardware).
En la electrónica moderna es tentador usar pantallas OLED. El problema es que el OLED emite luz; bajo el sol radiante de Jalisco a mediodía, un OLED es ilegible. Para un Despachador de Gas exterior, la única opción ergonómicamente responsable es una pantalla LCD Transflectiva Monocromática. Esta tecnología tiene un espejo semitransparente detrás de los píxeles. Cuanta más luz solar recibe, más se refleja y más nítido se vuelve el texto oscuro.

Paso 2: La Barrera de Tiempo (Software).
Para la Tarea de Interfaz en nuestro código Bare-Metal, no leemos el GPIO del botón directamente para arrancar el motor. Usamos una Máquina de Estados que mida cuánto tiempo ha estado en estado BAJO (presionado) el botón. Si el tiempo es menor a 2,000 ms, se considera un toque accidental y el contador de seguridad se reinicia.

💻 Firmware C: State Machine de Confirmación (Hold-to-Confirm)

El siguiente código demuestra cómo implementar un mecanismo de seguridad ergonómica sin usar retardos bloqueantes (HAL_Delay()), permitiendo que la máquina siga midiendo gas y atendiendo la red mientras el operador decide si iniciar el proceso.


/**
 * @file hmi_ergonomics.c
 * @brief Implementación de UI de Misión Crítica: Barreras de Confirmación de Tiempo
 */

#include "stm32f4xx_hal.h"
#include <stdbool.h>

// Estados de la Interfaz HMI
typedef enum {
    UI_STATE_IDLE,
    UI_STATE_WAITING_CONFIRMATION,
    UI_STATE_PUMP_RUNNING
} UI_State_t;

UI_State_t current_ui_state = UI_STATE_IDLE;
uint32_t button_press_start_time = 0;

// Constante de Ergonomía Cognitiva: 2 segundos de confirmación
#define HOLD_CONFIRM_TIME_MS 2000 

// =========================================================================
// MÁQUINA DE ESTADOS DE LA INTERFAZ DE USUARIO (No bloqueante)
// =========================================================================
/**
 * @brief Se invoca en el Super Loop principal. Gestiona la lógica de botones
 * mitigando pulsaciones accidentales o golpes físicos.
 */
void HMI_Process_Critical_Action(void) {
    
    // Leemos el botón de START (Físicamente Pull-Up, presionar baja a GND)
    bool is_button_pressed = (HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_13) == GPIO_PIN_RESET);

    switch (current_ui_state) {
        
        case UI_STATE_IDLE:
            if (is_button_pressed) {
                // El operador acaba de tocar el botón. Registramos el inicio del tiempo.
                button_press_start_time = HAL_GetTick();
                current_ui_state = UI_STATE_WAITING_CONFIRMATION;
                
                // Feedback visual inmediato: Iniciar barra de progreso en LCD
                LCD_Draw_Progress_Bar(0); 
            }
            break;

        case UI_STATE_WAITING_CONFIRMATION:
            if (is_button_pressed) {
                // El operador sigue manteniendo el botón.
                uint32_t elapsed_time = HAL_GetTick() - button_press_start_time;
                
                // Actualizar UI para indicarle al operador que el sistema está respondiendo
                uint8_t progress_percent = (elapsed_time * 100) / HOLD_CONFIRM_TIME_MS;
                LCD_Draw_Progress_Bar(progress_percent);

                // ¿Alcanzó la barrera de seguridad?
                if (elapsed_time >= HOLD_CONFIRM_TIME_MS) {
                    // CONFIRMACIÓN EXITOSA. Acción Intencional verificada.
                    current_ui_state = UI_STATE_PUMP_RUNNING;
                    LCD_Clear();
                    LCD_Print_String("DESPACHO INICIADO");
                    
                    // Disparar actuador de hardware
                    HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_SET); // Válvula ON
                }
            } else {
                // El operador soltó el botón ANTES de los 2 segundos.
                // Se asume pulsación accidental (Fat Finger) o cambio de decisión.
                current_ui_state = UI_STATE_IDLE;
                LCD_Clear_Progress_Bar();
            }
            break;

        case UI_STATE_PUMP_RUNNING:
            // Lógica de paro gestionada en otro bloque o por interrupción de emergencia
            break;
    }
}
        

🚀 Avance del Proyecto Tesis: Defensa del Factor Humano

Objetivo del día: Demostrar que el diseño comprende el contexto de uso final de la máquina.

Una tesis universitaria clásica asume usuarios esféricos en el vacío. Muestras una pantalla TFT a color, pones 10 botones táctiles minúsculos y el jurado aplaude porque se ve "moderno". Pero cuando lleves ese producto a una planta envasadora real, la humedad arruinará el panel táctil, el sol dejará la pantalla a oscuras y el operador, harto de equivocarse, terminará golpeando la máquina con una llave inglesa.

Al documentar la **Ergonomía de Interfaz** como parte de tu Arquitectura de Software, le demuestras al comité de evaluación que posees Madurez Industrial. Justificar por qué evitaste pantallas OLED y elegiste *Transflectivas*, y documentar la máquina de estados de *Hold-to-Confirm* para purgar el "Fat Finger" del operador, posiciona a tu diseño no como un experimento, sino como un producto endurecido (Ruggedized) listo para fabricación masiva.

📝 Resumen del Día