DÍA 264 DE 365

Fase 5: Diseño Industrial y Proyecto Final

📖 Teoría a Estudiar

El Teorema de Nyquist y CMSIS-DSP

Si la bomba de Gas LP empieza a cavitar (crear burbujas destructivas por presión), el impacto mecánico genera ondas de vibración agudas, digamos a 400 Hz. Si lees tu acelerómetro 100 veces por segundo (100 Hz), jamás verás esa anomalía. Según el Teorema de Nyquist-Shannon, para digitalizar una señal de 400 Hz sin destruirla (Aliasing), debes muestrearla por lo menos al doble de su velocidad: >800 Hz.

Leer el bus SPI a 1000 Hz, almacenar 1024 muestras y multiplicar matrices consumiría el 100% de un Arduino, congelando todo. Pero nosotros no usamos Arduinos. El núcleo de ARM que elegiste (Cortex-M4F) cuenta con el motor CMSIS-DSP (Cortex Microcontroller Software Interface Standard - Digital Signal Processing).

Dominio del Tiempo vs Dominio de la Frecuencia (FFT)

Una señal en el Dominio del Tiempo es simplemente un electrocardiograma (amplitud a lo largo del tiempo). Se ve ruidosa, incomprensible. La FFT toma esa gráfica y la "gira" 90 grados para mostrarte el Dominio de la Frecuencia: una gráfica de barras (Espectro) donde cada barra representa "cuánta energía hay en los 10 Hz, cuánta en los 50 Hz, cuánta en los 400 Hz". Si el rodamiento se rompe, la barra de los 400 Hz se disparará hacia arriba como un rascacielos. Ese es el "Feature" (Característica) perfecto para alimentar a una Inteligencia Artificial (TinyML).

TRANSFORMADA RÁPIDA DE FOURIER (FFT) EN CMSIS-DSP DOMINIO DEL TIEMPO (Vibración Cruda) Tiempo (1s) G (m/s²) Un arreglo de 1024 floats (Array) Para la Inteligencia Artificial, esto es inútil. FPU / FFT CMSIS-DSP DOMINIO FRECUENCIA (Espectro) Freq (Hz) Magnitud 50 Hz (Rotación Motor) 400 Hz (Cavitación / Falla!) Un arreglo de 512 Magnitudes (Bins de 0.97Hz) La TinyML (IA) ama estos picos limpios. FLUJO DE PROCESAMIENTO C/C++ EN RTOS IMU SPI (DMA) Lee 1024 datos XYZ Hanning Window Suaviza bordes de array arm_rfft_fast_f32() Calcula Espectro (FPU) arm_cmplx_mag_f32 Obtiene Módulo abs TinyML Clasificación

⚙️ Ejercicios Prácticos

El Hardware IMU: Si usas un acelerómetro de alto rendimiento (ej. IIS3DWB diseñado para vibración industrial), lo leeremos por SPI a 1 kHz. Una FFT de 1024 muestras requiere que capturemos ~1 segundo de datos reales.

Ejercicio 1: La Magia de CMSIS-DSP. En un entorno MISRA-C estricto, no escribimos nuestra propia matemática de Fourier llena de bucles `for` y `senos` que tomaría segundos en ejecutarse. STMicroelectronics e Intel-ARM nos proveen una librería acelerada por hardware de grado militar. Usaremos `arm_math.h`.


/**
 * @file dsp_vibration_fft.c
 * @brief Extracción de Espectro (FFT) para Mantenimiento Predictivo usando FPU de ARM Cortex-M4
 */

#include "stm32f401xe.h"
#include "cmsis_os2.h"

// 1. INCLUIR LA LIBRERÍA DE PROCESAMIENTO DE SEÑALES DE ARM
#define ARM_MATH_CM4
#include "arm_math.h"
#include <stdint.h>

// =========================================================================
// DEFINICIONES DE LA FFT
// =========================================================================
#define FFT_SAMPLES         1024U    // Debe ser potencia de 2 (256, 512, 1024...)
#define FREQ_SAMPLING_HZ    1000.0F  // Leemos la IMU 1000 veces por segundo

// La FFT Real toma 1024 floats de tiempo y devuelve 1024 floats mezclados 
// (512 reales y 512 imaginarios). La Magnitud resultante serán 512 "Bins" (Barras).
float32_t tiempo_crudo_buffer[FFT_SAMPLES];
float32_t fft_output_complex[FFT_SAMPLES];
float32_t fft_magnitud_bins[FFT_SAMPLES / 2U];

// Objeto Instancia para la FFT de ARM
arm_rfft_fast_instance_f32 fft_handler;

extern void IMU_Capturar_Ventana_DMA(float32_t* buffer, uint16_t size);

// =========================================================================
// INICIALIZACIÓN DEL SISTEMA DSP
// =========================================================================
void DSP_Vibracion_Init(void) {
    // Inicializa la estructura interna, tablas de senos/cosenos pre-calculados
    // para una FFT de 1024 puntos. Esto evita calcular trigonometría en tiempo real.
    arm_rfft_fast_init_f32(&fft_handler, FFT_SAMPLES);
}

// =========================================================================
// TAREA RTOS DE MANTENIMIENTO PREDICTIVO
// =========================================================================
void Task_Vibration_Analysis(void *argument) {
    
    DSP_Vibracion_Init();
    
    for(;;) {
        // 1. ADQUISICIÓN DE DATOS (Bloquea la tarea 1 segundo sin usar CPU)
        // El SPI DMA llena el arreglo 'tiempo_crudo_buffer' en background.
        IMU_Capturar_Ventana_DMA(tiempo_crudo_buffer, FFT_SAMPLES);
        
        // --- 2. EL PODER DE LA UNIDAD DE PUNTO FLOTANTE (FPU) ---
        // A) Remoción de componente DC (Gravedad terrestre)
        float32_t valor_medio = 0.0f;
        arm_mean_f32(tiempo_crudo_buffer, FFT_SAMPLES, &valor_medio);
        arm_offset_f32(tiempo_crudo_buffer, -valor_medio, tiempo_crudo_buffer, FFT_SAMPLES);
        
        // B) Aplicar Transformada Rápida de Fourier (Dominio Tiempo -> Complejo)
        // Esta función se ejecuta en una fracción microscópica de segundo.
        arm_rfft_fast_f32(&fft_handler, tiempo_crudo_buffer, fft_output_complex, 0);
        
        // C) Calcular la Magnitud (Las "Barras" de energía) de los números complejos
        // RaizCuadrada(Real^2 + Imaginario^2)
        arm_cmplx_mag_f32(fft_output_complex, fft_magnitud_bins, FFT_SAMPLES / 2U);
        
        // --- 3. EXTRACCIÓN BÁSICA DE ANOMALÍAS (El Pre-TinyML) ---
        // Buscamos la frecuencia donde haya mayor energía de vibración.
        float32_t max_energia = 0.0f;
        uint32_t index_max_energia = 0U;
        
        arm_max_f32(fft_magnitud_bins, FFT_SAMPLES / 2U, &max_energia, &index_max_energia);
        
        // Matemática: Resolución de la gráfica = Freq_Muestreo / Muestras (1000 / 1024 = ~0.97 Hz por Bin)
        float32_t freq_dominante_hz = (float32_t)index_max_energia * (FREQ_SAMPLING_HZ / (float32_t)FFT_SAMPLES);
        
        // LÓGICA DE ALARMA INDUSTRIAL
        // Si el motor normalmente vibra a 50Hz, y detectamos un pico masivo > 350Hz:
        if (freq_dominante_hz > 350.0f && max_energia > 50.0f) {
            // ¡ALERTA DE CAVITACIÓN O FALLA DE RODAMIENTO!
            // En un sistema real, aquí llamaríamos a la Red Neuronal (Día 263) 
            // pasándole 'fft_magnitud_bins' como Input, pero esta matemática 
            // base ya es superior al 90% de los PLCs del mercado.
            
            // FSM_Disparar_Alarma_Mantenimiento();
        }
        
        // Dormir para ahorrar recursos (Ej. Analizar la bomba 1 vez por hora)
        osDelay(pdMS_TO_TICKS(60000U * 60U)); 
    }
}
        

🚀 Avance del Proyecto Tesis: Despachador de Gas LP

Objetivo del día: Extracción de Características Espectrales (DSP) en el Borde para el Internet Industrial de las Cosas (IIoT).

Enviar datos puros a un servidor en la Nube es como enviarle a tu contador cada recibo de chicle que compraste en el año. La infraestructura se asfixiará. El mantenimiento predictivo moderno exige que la máquina "digerir" la información localmente.

Al implementar la Cortex Microcontroller Software Interface Standard (CMSIS-DSP), has despertado a la bestia matemática de tu procesador (la FPU del Cortex-M4). En lugar de quemar milisegundos valiosos, tu chip ejecuta una Transformada Rápida de Fourier (FFT) de 1024 puntos apoyada directamente en los transistores del hardware en menos tiempo del que tarda el humano en parpadear. Has condensado 1024 lecturas caóticas de un acelerómetro en un "Espectro Vibracional" limpio, listo para ser ingerido por una Red Neuronal o evaluado por heurística. El Despachador ya no solo cuenta los litros de Gas LP; ahora "siente" la salud de los cojinetes de sus motores de bombeo, previniendo paros técnicos letales y garantizando un Retorno de Inversión (ROI) sin precedentes para la gasolinera.

📝 Resumen del Día