DÍA 155 DE 365

Fase 3: Comunicaciones y Redes Industriales

📖 Teoría a Estudiar

El Estrés Térmico y El Inrush Current

Cuando trazas tus esquemáticos en KiCad, colocas capacitores de desacoplo de 100nF y 10uF cerca de cada componente integrado, además de los grandes capacitores electrolíticos para estabilizar los reguladores de voltaje TO-252 que alimentan tu máquina. En el momento $T=0$, cuando el relevador principal se cierra, estos capacitores están vacíos. La fuente de poder los percibe temporalmente como un cable directo a tierra (GND).

Si la pantalla LCD, el módulo Wi-Fi, la EEPROM, la impresora térmica y el chip de RS485 exigen esta corriente simultáneamente, el consumo se dispara a varios amperios durante un par de milisegundos. Esta **Corriente de Irrupción (Inrush Current)** puede superar la capacidad máxima del regulador, hundiendo la línea de 3.3V hacia los 1.8V y provocando que el STM32 lance un Reset de Hardware por caída de voltaje (BOR - Brownout Reset).

Pines "Enable" y Secuencias Asíncronas

Para lograr una arquitectura industrial robusta, los subsistemas en el PCB se alimentan mediante circuitos Load Switch (con MOSFETs) o utilizando el pin EN (Enable) presente en la mayoría de los reguladores modernos o periféricos. Estos pines se conectan a los GPIO del STM32. El procesador arranca aislado, consumiendo muy poca energía, y luego decide **cuándo y en qué orden** habilitar al resto del hardware.

GESTIÓN DE POTENCIA Y CONTROL DE INRUSH CURRENT Arranque Simultáneo (Peligro) mA Límite LDO Inrush Spike Arranque Escalonado (Staggered) mA STM I2C RS485 HMI Distribución Física en el PCB STM32 Boot Master PA1 PA2 PA3 EN_SENSORS (10ms) EN_COMMS (100ms) EN_POWER (500ms) Bus I2C (EEPROM) MAX485 (Modbus) Impresora / Relés Bancos de Capacitores (Cargándose uno a la vez)

⚙️ Ejercicios Prácticos

Ejercicio 1: Reemplazaremos la llamada estática de inicializaciones al principio del `main()`. Crearemos una **Máquina de Estados de Boot No Bloqueante**. El procesador encenderá, levantará el reloj central (PLL), y luego usará la base de tiempo de `millis()` (nuestro contador alimentado por SysTick) para habilitar progresivamente los GPIOs de control de potencia, configurando y esperando que cada dispositivo levante su bandera de "Ready".


/**
 * @file power_sequence.c
 * @brief Máquina de Estados para Arranque Escalonado (Anti-Inrush)
 */

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

// Dependencia de la base de tiempo global (Día 98)
extern volatile uint32_t ms_ticks; 

// Macros para control de pines EN (Enable) en GPIOA
#define EN_SENSORS_ON()   (GPIOA->BSRR = GPIO_BSRR_BS1)
#define EN_COMMS_ON()     (GPIOA->BSRR = GPIO_BSRR_BS2)
#define EN_POWER_ON()     (GPIOA->BSRR = GPIO_BSRR_BS3)

// Estados de la máquina de arranque
typedef enum {
    BOOT_START = 0,
    BOOT_WAIT_SENSORS,
    BOOT_INIT_SENSORS,
    BOOT_WAIT_COMMS,
    BOOT_INIT_COMMS,
    BOOT_WAIT_ACTUATORS,
    BOOT_INIT_ACTUATORS,
    BOOT_COMPLETE
} BootState_t;

static BootState_t estado_boot = BOOT_START;
static uint32_t tiempo_inicio_estado = 0;

// Bandera global para que el Súper Bucle sepa cuándo puede operar
bool sistema_listo = false;

// Dependencias de inicialización de módulos
extern void inicializar_i2c1(void);
extern void inicializar_usart2_modbus(void);
extern void inicializar_pwm_valvula(void);

/**
 * @brief Configura los GPIOs encargados de activar la potencia.
 *        Se llama inmediatamente al iniciar el hardware.
 */
void inicializar_pines_power_sequence(void) {
    RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN;
    
    // Configurar PA1, PA2, PA3 como salidas Push-Pull
    GPIOA->MODER &= ~((3 << 2) | (3 << 4) | (3 << 6));
    GPIOA->MODER |=  ((1 << 2) | (1 << 4) | (1 << 6));
    
    // ESTADO SEGURO INICIAL: Todo APAGADO (BSRR Reset)
    GPIOA->BSRR = GPIO_BSRR_BR1 | GPIO_BSRR_BR2 | GPIO_BSRR_BR3;
}

/**
 * @brief Máquina de estados no bloqueante que despierta al hardware.
 *        Debe llamarse continuamente en el main hasta que retorne true.
 */
void gestor_secuencia_arranque(void) {
    
    switch (estado_boot) {
        case BOOT_START:
            // 1. Dar energía a la sección crítica (EEPROM, Reloj RTC Externo)
            EN_SENSORS_ON(); 
            tiempo_inicio_estado = ms_ticks;
            estado_boot = BOOT_WAIT_SENSORS;
            break;
            
        case BOOT_WAIT_SENSORS:
            // Esperar 50ms para que los capacitores I2C se carguen
            // y los chips hagan su propio Power-On-Reset.
            if ((ms_ticks - tiempo_inicio_estado) >= 50) {
                estado_boot = BOOT_INIT_SENSORS;
            }
            break;
            
        case BOOT_INIT_SENSORS:
            // Ahora sí, configurar el hardware interno del STM32 para usar el I2C
            inicializar_i2c1();
            
            // 2. Dar energía a las telecomunicaciones (MAX485, Módulo Wi-Fi)
            EN_COMMS_ON();
            tiempo_inicio_estado = ms_ticks;
            estado_boot = BOOT_WAIT_COMMS;
            break;
            
        case BOOT_WAIT_COMMS:
            // Esperar 100ms. Los chips de radio frecuencia consumen mucha corriente al prender.
            if ((ms_ticks - tiempo_inicio_estado) >= 100) {
                estado_boot = BOOT_INIT_COMMS;
            }
            break;
            
        case BOOT_INIT_COMMS:
            inicializar_usart2_modbus();
            
            // 3. Dar energía a la potencia brutal (Impresoras, Válvulas)
            EN_POWER_ON();
            tiempo_inicio_estado = ms_ticks;
            estado_boot = BOOT_WAIT_ACTUATORS;
            break;
            
        case BOOT_WAIT_ACTUATORS:
            // Esperar 250ms a que los grandes condensadores electrolíticos se asienten
            if ((ms_ticks - tiempo_inicio_estado) >= 250) {
                estado_boot = BOOT_INIT_ACTUATORS;
            }
            break;
            
        case BOOT_INIT_ACTUATORS:
            inicializar_pwm_valvula();
            
            // Secuencia Finalizada exitosamente
            estado_boot = BOOT_COMPLETE;
            sistema_listo = true;
            break;
            
        case BOOT_COMPLETE:
            // No hacer nada, el sistema ya está arriba.
            break;
    }
}

int main(void) {
    
    // Configuración Base Extrema (Sólo Relojes y SysTick)
    // inicializar_relojes_84mhz();
    // SysTick_Init_1ms();
    
    inicializar_pines_power_sequence();
    
    // Bucle infinito principal
    while(1) {
        
        // Fase 1: El Despertar
        if (!sistema_listo) {
            gestor_secuencia_arranque();
        } 
        // Fase 2: Operación Normal Industrial
        else {
            
            // La máquina de gas funciona normal
            // despachar_gas_controlado();
            // procesar_modbus();
            // lcd_actualizar();
        }
    }
    
    return 0;
}
        

🚀 Avance del Proyecto Tesis: Despachador de Gas LP

Objetivo del día: Control de Transientes de Encendido y Estabilidad Inicial.

Cuando diseñas tu PCB en KiCad, separas cuidadosamente los planos de tierra analógicos y digitales, y colocas docenas de capacitores alrededor del procesador y los integrados para filtrar el ruido. Pero la física es implacable: un capacitor descargado es un cortocircuito eléctrico en el milisegundo cero. Si intentas encender la impresora térmica, las electroválvulas y el módulo de comunicaciones en el mismo momento en que el STM32 arranca, la fuente de 24V sufrirá, y el regulador principal de 3.3V colapsará antes de siquiera estabilizarse.

Al implementar una **Máquina de Estados de Arranque Escalonado (Power Sequence)**, has fusionado tu diseño de hardware (los reguladores con pines EN) con la inteligencia de tu firmware. El procesador despierta en silencio y toma el control absoluto. Enciende la primera zona del PCB, espera a que la corriente se estabilice matemáticamente contando milisegundos con el SysTick, configura los puertos asociados, y pasa a la siguiente fase. Esta delicada coreografía de encendido garantiza que la metrología, la comunicación y el control de potencia inicien siempre sobre una plataforma de voltaje impecable y estable.

📝 Resumen del Día