En el control de fluidos, detener un proceso no es tan simple como igualar dos variables en código (ej. if (litros_actuales == litros_deseados)). Las válvulas mecánicas tienen un tiempo de respuesta (latencia de cierre), y los líquidos presurizados poseen inercia cinética. Si esperas a que el caudalímetro marque exactamente 20 litros para mandar la señal de cierre, terminarás despachando 20.15 litros.
Para evitar regalos de producto o, peor aún, derrames peligrosos, la Barrera de Software debe ser predictiva. El programa debe comparar continuamente el volumen acumulado contra un "Objetivo Virtual" (Objetivo Real - Inercia del Sistema), anticipando el cierre físico para que el volumen final embotellado sea matemáticamente exacto.
GPIO = LOW y el sellado total de la electroválvula.Ejercicio 1: Programa una función que actúe como barrera de volumen utilizando variables enteras sin signo para contar mililitros con precisión, aplicando la anticipación de cierre.
#include <stdint.h>
#include <stdbool.h>
#include <stdio.h>
// --- 1. CONSTANTES DEL SISTEMA FÍSICO ---
// Resolucion del caudalímetro: ej. 10 ml por cada pulso de interrupción
#define ML_POR_PULSO 10
// El volumen que sigue fluyendo mientras la válvula cierra físicamente
// (Calibrado empíricamente en laboratorio)
#define INERCIA_VALVULA_ML 150
// --- 2. VARIABLES GLOBALES DE ESTADO ---
volatile uint32_t pulsos_acumulados = 0;
uint32_t volumen_objetivo_ml = 0;
bool despacho_en_curso = false;
// --- 3. RUTINAS LÓGICAS ---
// ISR simulada: Ocurre asíncronamente cuando gira la turbina del sensor
void EXTI_Caudalimetro_ISR(void) {
if (despacho_en_curso) {
pulsos_acumulados++;
}
}
// Barrera Predictiva llamada desde el Súper Bucle
void evaluar_barrera_volumen(void) {
if (!despacho_en_curso) return;
// Convertir pulsos crudos a unidad física (mililitros)
uint32_t ml_actuales = pulsos_acumulados * ML_POR_PULSO;
// Predicción: Proyectar volumen actual sumando el factor de cierre inevitable
uint32_t volumen_proyectado = ml_actuales + INERCIA_VALVULA_ML;
// Corte incondicional si el proyecto alcanza la barrera
if (volumen_proyectado >= volumen_objetivo_ml) {
despacho_en_curso = false;
// hardware_cerrar_valvulas();
printf("[SISTEMA] Barrera de software superada.\n");
printf("Corte enviado a los: %u ml. Objetivo: %u ml.\n", ml_actuales, volumen_objetivo_ml);
}
}
// --- 4. SÚPER BUCLE ---
int main(void) {
// Cliente solicita 20 Litros (20,000 ml)
volumen_objetivo_ml = 20000;
pulsos_acumulados = 0;
despacho_en_curso = true;
// hardware_abrir_valvulas();
printf("Iniciando despacho de 20.00 Litros...\n");
// Simulación del Súper Bucle procesando
while(despacho_en_curso) {
evaluar_barrera_volumen();
// (En una prueba real, aquí simularíamos la llamada a la ISR)
// EXTI_Caudalimetro_ISR();
}
printf("Despacho finalizado con exito.\n");
return 0;
}
Objetivo del día: Venta Preprogramada y Límite Máximo de Seguridad (Norma de Llenado).
La lógica que escribiste hoy cubre dos requerimientos industriales absolutos para tu tesis de grado. Primero, la Venta Preprogramada: Un operador puede teclear "$500 pesos" o "20 Litros" en el panel. Tu código establecerá volumen_objetivo_ml y, gracias a la inercia compensada, entregará la cantidad exacta al mililitro, cumpliendo con las regulaciones de la Procuraduría Federal del Consumidor (PROFECO) o el ente metrológico de tu país para evitar multas por calibración deficiente.
Segundo, y más crítico, la Seguridad por Sobrepresión: Por física térmica, ningún tanque de Gas LP debe llenarse más allá del 80% al 85% de su capacidad nominal, ya que el líquido necesita espacio para expandirse en estado gaseoso cuando hace calor. Independientemente de lo que pida el cliente, tu barrera de software actúa como un límite absoluto; bloqueando mecánicamente las válvulas mediante el STM32 o el ESP32 si los sensores detectan que el recipiente receptor está alcanzando el umbral físico de peligro.
1. ¿Qué pasaría si la solicitud del cliente es menor que la inercia de la válvula (ej. Pide 100ml pero la inercia es de 150ml)?
Respuesta: Si no controlas este caso borde, el código evaluará (0 + 150) >= 100 de inmediato, y la válvula se abrirá y cerrará en el mismo microsegundo de reloj, posiblemente causando un pulso falso. Como ingeniero de software, debes añadir una validación previa en la interfaz de usuario: if (volumen_objetivo_ml < VOLUMEN_MINIMO_DESPACHO) return ERROR;.
2. ¿Por qué usamos la bandera `despacho_en_curso` en lugar de simplemente apagar el pin de la válvula en la ISR?
Respuesta: Mantener el Desacoplamiento. La rutina de interrupción (ISR) del caudalímetro debe ser lo más corta y rápida posible: sumar un contador y salir (tomando nanosegundos). Hacer comprobaciones complejas o hablar con registros de puertos GPIO externos dentro de una interrupción es una mala práctica que genera inestabilidad de tiempos (Jitter). Las decisiones pesadas siempre deben derivarse al Súper Bucle principal.