DÍA 102 DE 365

Fase 2: Fundamentos de Hardware y Electrónica

📖 Teoría a Estudiar

Física del Caudalímetro (Flujómetro de Turbina)

Para medir líquido empujado a presión (como el Gas LP o el diésel), la industria utiliza turbinas. Físicamente, el líquido empuja las aspas de una pequeña hélice insertada en la tubería. Dentro de las aspas hay minúsculos imanes de neodimio.

Montado en la carcasa exterior (sin tocar el líquido) se encuentra un Sensor de Efecto Hall. Cada vez que un imán pasa frente a él, el sensor altera su voltaje. El resultado es un tren de pulsos cuadrados (Onda Cuadrada). Si el líquido fluye lento, los pulsos son lentos; si fluye rápido a alta presión, la onda cuadrada puede alcanzar frecuencias de cientos de Hertz (Hz).

El Factor K (Pulsos por Litro)

Todo caudalímetro viene de fábrica con una constante de calibración mecánica llamada Factor K. Te indica exactamente cuántos pulsos eléctricos equivalen a una unidad volumétrica. Por ejemplo: "450 pulsos = 1 Litro". La tarea de nuestro STM32 es atrapar absolutamente cada flanco de subida (Rising Edge) de esa onda cuadrada. Si usamos un bucle `while` para leer el pin, y en ese milisegundo el procesador está actualizando una pantalla LCD, perderemos el pulso. El EXTI es obligatorio.

METROLOGÍA: SENSOR DE EFECTO HALL Y EXTI Flujo Gas LP Hall Sensor Tren de Pulsos Rising Edge STM32 PB1 EXTI1 Hardware Counter Metrología (C) Factor K: 450 Pulsos = 1L Vol = Pulsos / 450

⚙️ Ejercicios Prácticos

Ejercicio 1: Conecta el cable de señal del caudalímetro al pin PB1. Configura el pin y el EXTI para detectar el Flanco de Subida (Rising Edge). A diferencia del botón de emergencia (Prioridad 0), la pérdida de un pulso es crítica financieramente pero no te matará, así que le daremos Prioridad 1.


/**
 * @file main.c
 * @brief Adquisición de Flujo por Pulsos (EXTI Metrológico)
 */

#include "stm32f401xe.h"

// --- 1. DEFINICIONES DE METROLOGÍA ---
#define CAUDALIMETRO_PIN   1        // Conectado al Puerto B, Pin 1 (PB1)
#define FACTOR_K           450.0f   // 450 pulsos equivalen a 1 Litro

// Variable volátil crítica. El CPU la incrementa asíncronamente en la ISR.
volatile uint32_t total_pulsos = 0;

void inicializar_caudalimetro(void) {
    
    // 1. Relojes: Puerto B y Multiplexor SYSCFG
    RCC->AHB1ENR |= RCC_AHB1ENR_GPIOBEN;
    RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN;
    
    // 2. Configurar PB1 como Entrada con Pull-Up
    // El Pull-up es vital porque muchos sensores de flujo son "Open-Collector"
    GPIOB->MODER &= ~(3 << (CAUDALIMETRO_PIN * 2)); // 00: Entrada
    GPIOB->PUPDR &= ~(3 << (CAUDALIMETRO_PIN * 2)); 
    GPIOB->PUPDR |=  (1 << (CAUDALIMETRO_PIN * 2)); // 01: Pull-up
    
    // 3. Enrutar PB1 a la línea EXTI1 en el SYSCFG
    // Limpiamos los 4 bits del bloque EXTI1 y le insertamos el valor del Puerto B (0001)
    SYSCFG->EXTICR[0] &= ~SYSCFG_EXTICR1_EXTI1;
    SYSCFG->EXTICR[0] |= SYSCFG_EXTICR1_EXTI1_PB; 
    
    // 4. Configurar el Controlador EXTI
    EXTI->IMR |= EXTI_IMR_MR1;        // Desenmascarar (habilitar) línea 1
    
    // Esta vez queremos Flanco de Subida (Rising Edge) cuando el imán pasa
    EXTI->RTSR |= EXTI_RTSR_TR1;      // Habilitar Rising Edge
    EXTI->FTSR &= ~EXTI_FTSR_TR1;     // Asegurar que Falling Edge esté apagado
    
    // 5. NVIC: Asignar Prioridad y Encender
    // Prioridad 1: Menos urgente que el Paro de Emergencia (0), pero 
    // más urgente que el SysTick (5) o el RS485 (10).
    NVIC_SetPriority(EXTI1_IRQn, 1);
    NVIC_EnableIRQ(EXTI1_IRQn);
}

// --- VECTOR DE INTERRUPCIÓN ---
void EXTI1_IRQHandler(void) {
    
    // Validar que la interrupción provenga de la Línea 1
    if (EXTI->PR & EXTI_PR_PR1) {
        
        // INCREMENTO ATÓMICO INMEDIATO
        total_pulsos++;
        
        // Limpiar la bandera para permitir el siguiente pulso
        EXTI->PR |= EXTI_PR_PR1; 
    }
}

// Función auxiliar para que el resto del software obtenga los litros
float obtener_litros_despachados(void) {
    // Cálculo seguro con cast a float para mantener decimales
    return (float)total_pulsos / FACTOR_K;
}

int main(void) {
    
    inicializar_caudalimetro();
    
    while(1) {
        // En el super bucle, podemos leer tranquilamente la variable 
        // sin preocuparnos por la velocidad del fluido.
        float litros_actuales = obtener_litros_despachados();
        
        // Lógica: Si litros_actuales >= litros_solicitados -> VALVULA_OFF()
    }
    
    return 0;
}
        

🚀 Avance del Proyecto Tesis: Despachador de Gas LP

Objetivo del día: Adquisición de datos metrológicos sin pérdidas computacionales.

Imagínate despachando a máxima presión. El gas fluye tan rápido que la turbina gira salvajemente enviando 500 pulsos por segundo (500 Hz). Si intentaras leer el pin PB1 usando un if(GPIOB->IDR & ...) en tu bucle `main`, perderías la mitad de los pulsos en cuanto el procesador se distrajera para enviarle un comando a la pantalla LCD. Terminarías despachando 10 litros pero cobrando solo 5.

Al utilizar el EXTI1 y configurarlo con Prioridad 1, le hemos dicho al procesador: "Puedes hacer lo que quieras, pero si el sensor de flujo envía un pulso, lo sueltas todo, sumas 1 a la variable y regresas". El incremento total_pulsos++ le toma al Cortex-M apenas un par de ciclos de reloj. Físicamente es imposible que el fluido se mueva lo suficientemente rápido como para asfixiar a un procesador que corre a 84,000,000 Hz, garantizando una exactitud financiera milimétrica.

📝 Resumen del Día