El Factor-K es un coeficiente lineal que representa el número de pulsos eléctricos generados por el medidor volumétrico para desplazar exactamente una unidad de volumen estándar. Su fórmula matemática pura es: $$ K = \frac{P_{generados}}{V_{real}} $$ Donde $P$ son los pulsos y $V$ son los litros que realmente salieron a la atmósfera. Si el fabricante dice que tu flujómetro es de 1000 pulsos/L, ese es tu $K$ teórico.
Para calcular el volumen que se está entregando al cliente, despejamos la ecuación:
$$ Volumen = \frac{Pulsos}{K} $$
El problema en sistemas embebidos de grado industrial es que no podemos dividir un número y quedarnos con un resultado float, ya que destrozaría la eficiencia de los procesadores ARM Cortex-M o NXP. La solución Bare-Metal es multiplicar primero los pulsos por un factor de escala (ej. 1000 para pasar de Litros a Mililitros) y luego realizar la división de números enteros.
Cuando un inspector revisa el despachador con un recipiente patrón de 20 Litros, si la pantalla marca 20L pero el recipiente físico rebosa a 20.2L, debemos ajustar el Factor-K en la memoria. La nueva calibración se obtiene leyendo la cantidad cruda de pulsos que generó ese despacho y dividiéndola entre el volumen físico real ingresado por el teclado.
Ejercicio 1: Construiremos las funciones core para el motor metrológico. Una función traducirá los pulsos entrantes a mililitros en tiempo real, y otra recalculará el Factor-K cuando el operador lo ordene en el menú LCD.
#include <stdint.h>
// --- 1. MEMORIA RAM Y EEPROM ---
// Variable volátil modificada por la Interrupción del Caudalímetro
extern volatile uint32_t pulsos_acumulados_isr;
// Variable global cargada desde la EEPROM al arrancar la placa
// Representa cuántos pulsos equivale a 1 Litro real.
uint32_t factor_k_sistema = 1000;
// --- 2. CÁLCULO DE VOLUMEN (TIEMPO REAL) ---
/**
* @brief Convierte los pulsos eléctricos a volumen usando Punto Fijo.
* @param pulsos La cantidad cruda leída del hardware.
* @return El volumen exacto en mililitros.
*/
uint32_t Metrologia_Calcular_Mililitros(uint32_t pulsos) {
// RED DE SEGURIDAD: Prevenir un reinicio de CPU por "Divide by Zero"
// Si la EEPROM se corrompió y cargó un 0, forzamos un valor seguro por defecto.
if (factor_k_sistema == 0) {
factor_k_sistema = 1000;
}
// Matemática pura: Multiplicamos primero para subir de Litros a Mililitros.
// Soporta hasta ~2,147 Litros antes de desbordar un int32 con signo.
return (pulsos * 1000) / factor_k_sistema;
}
// --- 3. RE-CALIBRACIÓN DESDE HMI ---
/**
* @brief Recalcula y actualiza la constante volumétrica de la máquina.
* @param litros_patron_teclado Los litros exactos ingresados por el operador.
*/
void Metrologia_Ajustar_FactorK(uint32_t litros_patron_teclado) {
// Validar que el operador no ingrese 0 litros y quiebre las matemáticas.
if (litros_patron_teclado == 0) return;
// Guardamos momentáneamente los pulsos crudos totales que se generaron en la prueba.
uint32_t pulsos_prueba = pulsos_acumulados_isr;
// K = Pulsos / Litros
uint32_t nuevo_k = pulsos_prueba / litros_patron_teclado;
// Límite de seguridad industrial:
// Rechazar calibraciones absurdas provocadas por un error de tipeo.
if (nuevo_k > 500 && nuevo_k < 2000) {
factor_k_sistema = nuevo_k;
// Aquí se mandaría la orden por I2C (Día 37) para grabar 'factor_k_sistema' en EEPROM
// EEPROM_Write_Word(ADDR_FACTOR_K, factor_k_sistema);
}
}
Objetivo del día: Certificación Metrológica Dinámica.
Las autoridades exigen que un despachador de gas LP tenga un margen de error mínimo (generalmente inferior al 1%). Dado que estás utilizando componentes de hardware que se desgastan (las aspas o medidores másicos del flujómetro), tu software necesita flexibilidad. Al aislar la lógica del Factor-K en memoria EEPROM y proteger las divisiones por cero, garantizas que la placa electrónica base pueda ser instalada en cualquier tipo de tubería o marca de flujómetro de la industria, calibrándose por teclado durante la instalación sin tener que alterar el código en C de tu microcontrolador.
x1000) y multiplicaciones tempranas para conservar la precisión decimal sin usar variables float.(/) que utilice variables configurables por el usuario o extraídas de una EEPROM debe poseer una condición Anti-Cero previa. Si una EEPROM borrada entrega `0`, el procesador lanzará una excepción fatal (HardFault) y la máquina colapsará.