El período de muestreo (Δt o Ts) es el tiempo que pasa entre dos ejecuciones consecutivas del control en un sistema digital.
Al dar el salto del papel al silicio, abandonamos el cómodo mundo de las matemáticas continuas (donde el tiempo fluye de forma ininterrumpida) para entrar en el mundo discreto. Aquí, nuestro microcontrolador (ya sea un Arduino, un ESP32 o un PLC industrial) es como una cámara de cine tomando fotografías de la realidad.
La pregunta del millón que todo programador se hace cuando implementa un PID es: ¿a qué velocidad tiene que ir mi bucle? La respuesta instintiva suele ser: “¡Lo más rápido que pueda el procesador!”. Y esa es una de las peores decisiones de diseño que podrias tomar.
El mito de «cuanto más rápido, mejor»
Si metemos la lectura del sensor analógico y el cálculo de nuestro control digital directamente en un loop() salvaje sin restricciones de tiempo, la ejecución irá a la velocidad máxima del reloj de la CPU (quizás miles de veces por segundo).
Esto puede presentar tres problemas en el mundo real:
- Ahogamos la CPU: Si el microcontrolador pasa el 99% de su tiempo recalculando un PID para un motor que ni siquiera ha tenido tiempo físico de moverse un milímetro, estamos desperdiciando ciclos de reloj. Nos quedamos sin recursos para leer el puerto serie, actualizar una pantalla OLED o mantener una conexión WiFi.
- Ruido en la Derivada: Como vimos de pasada en artículos anteriores, la acción derivativa calcula la pendiente dividiendo por
. Si el período de muestreo es enano ( s), cualquier ínfimo ruido eléctrico del sensor se dividirá por ese número enano, creando un pico de control gigantesco e inestable. - Inconsistencia matemática: Si dejamos el bucle “libre”, en una iteración puede tardar
ms, pero si de repente llega un paquete por Serial, la siguiente iteración tardará ms. Esto destruye la validez de nuestras integrales y derivadas, que asumen un paso de tiempo constante para no falsear las áreas bajo la curva.
Por tanto, necesitamos fijar un tiempo de muestreo constante. Pero, ¿cómo de rápido tiene que ser? Si vamos muy rápido malgastamos recursos, pero si vamos muy lento, nos volvemos ciegos.
El límite: teorema de Nyquist-Shannon
Para saber cuál es la velocidad mínima a la que podemos leer un sensor sin perder información importante, recurrimos a uno de los teoremas más conocidos de la teoría de la información, formulado por Harry Nyquist y Claude Shannon.
El Teorema de Nyquist-Shannon establece que, para poder reconstruir una señal continua limitada en banda a partir de muestras ideales, la frecuencia de muestreo debe ser mayor que el doble de la frecuencia máxima contenida en la señal.
Si estamos intentando controlar una máquina que vibra a
El aliasing
Imagina la rueda de un coche en movimiento grabada por una cámara de vídeo a 24 frames por segundo. A veces, la rueda parece que gira hacia atrás, aunque el coche va hacia adelante. Eso es el Aliasing: la cámara está tomando fotos más lento que la velocidad a la que giran los radios de la rueda, engañando a nuestro cerebro.
En electrónica pasa exactamente lo mismo. Si la planta física se mueve más rápido que la velocidad a la que tú la lees, tu microcontrolador unirá los puntos y “verá” una señal fantasma de baja frecuencia que no existe en la realidad. Si tu PID intenta corregir esa señal fantasma, el sistema colapsará.
Simulador interactivo de aliasing
Para ver lo peligroso que es muestrear demasiado lento, he preparado este simulador del teorema de Nyquist.
En el simulador, la onda azul es la realidad física (nuestra planta oscilando a 1Hz). Baja la frecuencia de muestreo a 1.1Hz y verás cómo la señal reconstruida parece una onda larguísima y lentísima. Tu Arduino está alucinando.
Después súbela a 2.0Hz (el límite de Nyquist) y finalmente a 10Hz. Ahora sí, los puntos capturan mucho mejor la silueta real.
De la teoría a la práctica
El teorema de Nyquist nos dice la velocidad mínima para no perder información. Pero en ingeniería de control, solo leer la información no es suficiente; tenemos que reaccionar a tiempo y corregirla.
Si muestreas justo al límite de Nyquist (
Por este motivo, en la industria de la automatización existe una regla empírica fundamental:
Regla práctica del muestreo en control:
La frecuencia de ejecución del bucle de control (
Si tienes un horno industrial enorme que tarda minutos en calentarse (Dinámica lenta, ancho de banda de
Si tienes un dron de carreras que reacciona a los golpes de viento en milisegundos (Dinámica rápida, ancho de banda de
Implementando el muestreo determinista en C++
Para lograr esto en nuestro código sin bloquear la ejecución de otros procesos, usamos estructuras de temporización no bloqueantes.
La forma básica para un Arduino o ESP32 consiste en evaluar el paso del tiempo con millis() o micros(). No elimina por completo el jitter, pero evita que la frecuencia dependa directamente de la duración de cada vuelta de loop().
// Definimos el tiempo de muestreo deseado (Ts = 10ms -> fs = 100Hz)
const unsigned long TIEMPO_MUESTREO_MS = 10;
unsigned long tiempo_anterior = 0;
void setup() {
// Configuración inicial
tiempo_anterior = millis();
}
void loop() {
unsigned long tiempo_actual = millis();
// Evaluamos si ha pasado al menos el tiempo de muestreo
if (tiempo_actual - tiempo_anterior >= TIEMPO_MUESTREO_MS) {
// --- 1. Leer sensores ---
float pv = leer_sensor();
// --- 2. Ejecutar algoritmo de control (PID, discretización, etc) ---
// Aquí sabemos matemáticamente que dt = 0.01 segundos
float dt = TIEMPO_MUESTREO_MS / 1000.0;
float salida = calcular_pid(pv, dt);
// --- 3. Actuar sobre la planta ---
escribir_actuador(salida);
// Avanzar la planificación sin acumular deriva temporal
tiempo_anterior += TIEMPO_MUESTREO_MS;
}
// ¡FUERA DEL IF!
// Aquí el microcontrolador es libre de hacer cosas rápidas
// sin que le afecte el letargo del PID.
atender_peticiones_wifi();
refrescar_pantalla();
}Cuando el jitter no sea tolerable, podemos usar un temporizador de hardware o una tarea periódica de tiempo real. La ISR debería limitarse a registrar el instante o despertar una tarea; leer sensores, calcular el PID o acceder a comunicaciones dentro de una interrupción puede introducir nuevos problemas.