El bucle for se utiliza cuando conoces exactamente cuántas veces debe repetirse una acción. Su estructura compacta inicializa la variable, evalúa el límite y aplica el incremento en una sola línea. Es la herramienta principal para procesamiento de señales, como cuando necesitas simular un tren de 100 pulsos matemáticos o leer 10 veces un ADC para sacar un promedio rápido.
El bucle while se ejecuta mientras una condición sea verdadera. En sistemas *Bare-Metal*, lo usamos frecuentemente para el Polling: "Quédate aquí dando vueltas mientras el pin del sensor siga en cero". El problema es que el hardware falla. Un cable se puede cortar. Si usas while(pin_estado == 0); y el sensor se rompe, la CPU jamás saldrá de esa línea. El equipo se congela por completo.
Un ingeniero industrial jamás escribe un while bloqueante sin un límite. Debemos inyectar una variable contadora. Si el contador supera un límite matemático preestablecido $T_{max}$, el bucle se rompe forzosamente usando break y se declara una bandera de error.
Ejercicio 1: Simulador de Flujómetro. Antes de conectar tu MCU a la tubería real, necesitamos generar pulsos matemáticamente usando un bucle for. Luego, crearemos una función de Polling con Timeout para leer un pulso simulado sin bloquear el sistema.
#include <stdint.h>
#include <stdbool.h>
// --- Configuración Cero Floats ---
// Asumimos que 1 pulso = 15 mililitros
#define MILILITROS_POR_PULSO 15
// Variables globales del despachador
uint32_t volumen_acumulado_ml = 0;
uint32_t contador_pulsos = 0;
// Función ficticia que simula leer el pin del sensor Hall
// 1 = Pulso Alto, 0 = Reposo
extern bool leer_pin_flujometro(void);
/**
* @brief Simula la inyección de N pulsos perfectos para pruebas de software.
* Usamos 'for' porque la cantidad de iteraciones es finita y conocida.
*/
void simular_inyeccion_pulsos(uint16_t cantidad_pulsos) {
for (uint16_t i = 0; i < cantidad_pulsos; i++) {
contador_pulsos++;
volumen_acumulado_ml += MILILITROS_POR_PULSO;
}
}
/**
* @brief Espera un flanco de pulso mediante Polling Seguro.
* @return true si detectó el pulso, false si hubo Timeout (falla física).
*/
bool esperar_pulso_seguro(void) {
uint32_t timeout_counter = 0;
const uint32_t MAX_TIMEOUT = 50000; // Limite arbitrario de ciclos
// Bucle while: "Mientra el pin siga en 0 (sin pulso)..."
while (leer_pin_flujometro() == false) {
timeout_counter++;
// El salvavidas: Si el cable se cortó, el contador excederá el máximo
if (timeout_counter >= MAX_TIMEOUT) {
// Rompemos el bucle forzosamente
return false;
}
}
// Si llegamos aquí, el pin subió a 1 antes del timeout.
return true;
}
Hito Logrado: Lectura Segura de Sensores (Safe Polling).
Al implementar el límite `MAX_TIMEOUT`, acabas de vacunar a tu despachador contra fallas mecánicas de los sensores externos. Si un camión arranca el cable del flujómetro de efecto Hall en la planta de gas, la función `esperar_pulso_seguro` no colgará el microcontrolador. En una fracción de segundo, la función devolverá `false`, permitiendo que la máquina de estados del Día 5 active el ESTADO_FALLO_CRITICO y cierre las válvulas instantáneamente.