DÍA 293 DE 365

Fase 5: Diseño Industrial y Hardware

📖 Teoría a Estudiar

EMI: Interferencia Conducida vs Radiada

Tu máquina puede fallar por EMI (Electromagnetic Interference) de dos maneras:

  1. EMI Conducida: El ruido viaja físicamente a través de los cables de alimentación. Cuando un motor arranca en la gasolinera, la red de 24V oscila, inyectando transitorios rápidos de voltaje (EFT) directamente en tu regulador Buck.
  2. EMI Radiada: El ruido viaja por el aire como ondas de radio. Cualquier cable conectado a tu placa actúa como una antena receptora que captura este campo electromagnético y lo convierte en corrientes parásitas (Common-Mode Noise) que saturan tus entradas digitales.

La Magia Negra de las Ferritas

Un inductor normal bloquea las altas frecuencias reflejándolas de vuelta a la fuente. Un Ferrite Bead (Perla de Ferrita) hace algo mucho más útil: se come las altas frecuencias y las destruye. A bajas frecuencias (como la alimentación DC o señales lentas), la ferrita se comporta como un cable corto. Pero a altas frecuencias (el ruido electromagnético en los MHz), el material magnético se vuelve altamente resistivo. Su impedancia responde a la ecuación $Z = R + j\omega L$, donde a alta frecuencia la parte resistiva ($R$) domina, absorbiendo la energía del pulso de ruido y disipándola como calor microscópico.

ATENUACIÓN DE RUIDO (COMMON-MODE) MEDIANTE FERRITAS CABLE (24V Alimentación / Antena) Ruido EMI Radiado (Ej. Motor Contactor 5HP) Señal Contaminada (Transitorios Alta Frecuencia) FERRITE CHOKE Conversión de RF a Calor (Resistencia Magnética) Señal Limpia (DC / Baja Frecuencia) PCB MAINBOARD Sistema a Salvo Blindaje del Cable (Shield) GND Chassis Regla de Oro EMC: El blindaje del cable (malla metálica) se conecta a Tierra (GND) en UN SOLO EXTREMO para evitar "Ground Loops" de corriente.

⚙️ Estrategias de Implementación de Hardware

Estrategia 1: Ferritas de Abrazadera (Clamp-on Ferrites).
Esta es la solución más rápida. Si ya fabricaste la placa y tienes problemas de ruido cuando la bomba de gas arranca, compras un cilindro de ferrita que se abre por la mitad. Lo abrazas alrededor del cable de poder de 24V y del cable RS-485 lo más cerca posible a la entrada de tu PCB. La ferrita absorberá el "Common-Mode Noise" (Ruido que viaja en la misma dirección por ambos cables) antes de que toque la placa.

Estrategia 2: SMD Ferrite Beads en el PCB (Filtro Pi).
En el diseño de la Fase 5, añadimos un Ferrite Bead SMD (ej. BLM18PG121SN1D) justo en el pin de entrada de VCC del STM32 y de los sensores analógicos. Se combina con dos capacitores cerámicos para formar un Filtro Pi ($\pi$). El ruido de alta frecuencia que logre colarse a la placa será quemado internamente por este diminuto componente antes de afectar el procesador.

Estrategia 3: Cables Apantallados (Shielded Cables) y el Ground Loop.
Utiliza cable con malla trenzada metálica (Shield) para el sensor de 4-20mA. La regla de acero: Conecta la malla a tierra física (Chasis) en un solo extremo (generalmente del lado de tu placa). Si conectas la malla a tierra en la placa y también en el sensor externo a 10 metros, cualquier diferencia de potencial en la tierra de la gasolinera hará que fluyan amperios masivos a través de tu pobre malla (Ground Loop), fundiendo el cable y metiendo más ruido del que intentabas sacar.

💻 Firmware: Filtrado Digital (Debounce / Glitch Filter)

Incluso con ferritas y blindaje, un transitorio rápido (EFT) de varios miles de voltios podría colarse durante un nanosegundo y golpear un pin digital (GPIO) configurado como interrupción para medir el medidor de flujo (Caudalímetro de pulsos). Si el STM32 cuenta ese pulso falso, le cobrarás litros de gas inexistentes al cliente.

Para mitigar esto, implementamos un filtro Anti-Glitch por Software. En lugar de confiar en la interrupción a ciegas, usamos un temporizador y un algoritmo integrador de estados.


/**
 * @file emc_digital_filter.c
 * @brief Filtro digital Anti-Glitch para entradas susceptibles a EMI (Caudalímetro)
 */

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

// Pin del sensor de caudal (Hall Effect / Pulses)
#define FLOW_SENSOR_PORT    GPIOA
#define FLOW_SENSOR_PIN     GPIO_PIN_0

// Parámetros del filtro EMC
#define FILTER_SAMPLES      (5U)   // Necesitamos 5 lecturas consecutivas idénticas
#define FILTER_DELAY_US     (50U)  // Retardo en microsegundos entre lecturas

// Variable global segura
volatile uint32_t Valid_Flow_Pulses = 0;

/**
 * @brief Rutina de Interrupción EXTI (Disparada por el Flanco de Subida)
 * En lugar de sumar el pulso inmediatamente, verificamos si es real o EMI.
 */
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) {
    if (GPIO_Pin == FLOW_SENSOR_PIN) {
        
        // Un pulso EMI inducido por un motor dura nanosegundos o pocos microsegundos.
        // Un pulso mecánico real del caudalímetro dura milisegundos.
        
        uint8_t stable_high_count = 0;
        
        // FILTRO INTEGRADOR: Leemos el pin múltiples veces con retardo
        for (uint8_t i = 0; i < FILTER_SAMPLES; i++) {
            
            // Retardo microscópico (Asumiendo implementación DWT o Timer hardware)
            Delay_Microseconds(FILTER_DELAY_US);
            
            if (HAL_GPIO_ReadPin(FLOW_SENSOR_PORT, FLOW_SENSOR_PIN) == GPIO_PIN_SET) {
                stable_high_count++;
            } else {
                // Si el pin cae a LOW en medio de la verificación, era un Glitch EMI.
                // Rompemos el ciclo inmediatamente para ahorrar CPU.
                break; 
            }
        }
        
        // Si el nivel Alto se mantuvo durante todo el muestreo de verificación:
        if (stable_high_count == FILTER_SAMPLES) {
            // El pulso es mecánicamente real.
            Valid_Flow_Pulses++;
        }
        else {
            // [LOG DE DEPURACIÓN] EMI Spike detectado y suprimido por software.
        }
    }
}

/**
 * @brief Función auxiliar bloqueante para retardos de microsegundos.
 * (Utiliza el Data Watchpoint and Trace (DWT) de ARM Cortex-M)
 */
void Delay_Microseconds(uint32_t us) {
    uint32_t start = DWT->CYCCNT;
    // SystemCoreClock indica los ticks por segundo (Ej. 84000000 para 84MHz)
    uint32_t ticks = us * (SystemCoreClock / 1000000); 
    
    while ((DWT->CYCCNT - start) < ticks) {
        // Espera ocupada microscópica
    }
}
        

🚀 Avance del Proyecto Tesis: Despachador de Gas LP

Objetivo del día: Inmunidad Electromagnética de Campo (Noise Immunity) y Confiabilidad Metrológica.

Las gasolineras son entornos electromagnéticos brutales. Tienes motores de 220V arrancando, inversores de frecuencia variable (VFDs) emitiendo armónicos por la red eléctrica, y técnicos usando radios de dos vías a dos metros de tu máquina. Si no blindas el Despachador de Gas LP, el ruido inducido viajará por el cable de tu caudalímetro o de tu Modbus RS-485. Ese ruido engañará al pin `PA0` de tu STM32, haciéndole creer que pasaron 10 pulsos (1 litro de gas) en un milisegundo. Cobrarás dinero por gas que nunca salió de la tubería, y la autoridad metrológica te revocará la licencia.

Al implementar tácticas híbridas (Hardware + Software), has construido una fortaleza. A nivel hardware, las **Ferritas (Ferrite Beads)** ancladas en los cables de entrada estrangulan físicamente la alta frecuencia, convirtiendo el ruido de radio en calor inofensivo mediante resistencia magnética. A nivel software, tu filtro de **Debounce / Glitch Filtering** en lenguaje C sospecha de cualquier pulso electrónico que sea demasiado rápido para ser humano o mecánico, filtrándolo matemáticamente antes de que incremente la variable del sistema. Tu máquina ahora no solo despacha gas, sino que ignora por completo el ruido atronador del mundo exterior.

📝 Resumen del Día