Introducción al PID y su implementación en Arduino
Introducción
El controlador PID es probablemente uno de los algoritmos de control más utilizados en la industria. Podemos encontrarlo regulando temperaturas, presiones, caudales, velocidades, posiciones y prácticamente cualquier variable que podamos medir y sobre la que tengamos alguna forma de actuar. A pesar de ello, su funcionamiento básico es relativamente sencillo y podemos implementarlo sin demasiadas dificultades en un Arduino.
En este artículo vamos a entender qué hace realmente un PID y cómo llevarlo a código, simplificando todo lo posible la parte matemática. Sin embargo, lo que no vamos a hacer es probar valores de las constantes de sintonía al azar hasta conseguir una gráfica que parezca aceptable. Programar el controlador es solo una parte del problema. Para utilizarlo correctamente necesitaremos conocer cómo responde nuestro proceso y, a partir de esa información, obtener unos parámetros de sintonía apropiados.
El recorrido completo de esta serie será entender el PID, implementarlo, identificar el proceso, calcular una sintonía y finalmente comprobarla y refinarla. En esta primera parte nos centraremos en las dos primeras etapas. La identificación y la sintonía calculada quedarán para los siguientes artículos.
Un ejemplo sencillo: control de temperatura
Vamos a utilizar como ejemplo un proceso de control de temperatura. Imaginemos una pequeña cámara térmica en la que queremos mantener 50 °C. Disponemos de una sonda para medir la temperatura y de una resistencia de calentamiento cuya potencia podemos modificar mediante una salida PWM de Arduino y la electrónica de potencia correspondiente.
Podríamos resolver el problema con un control todo/nada, si estamos por debajo de 50°C conectamos la resistencia y, si estamos por encima, la desconectamos. Para muchas aplicaciones puede ser suficiente, pero la temperatura tenderá a oscilar alrededor de la consigna. Un PID permite actuar de forma progresiva haciendo que la potencia aplicada dependa de cuánto nos falta, cuánto tiempo llevamos desviados y, cuando resulte útil, de la velocidad con la que cambia la temperatura.
SP, PV, OP y Error
Antes de hablar de P, I y D necesitamos cuatro conceptos. SP, de Set Point, es la consigna o valor que queremos alcanzar. PV, de Process Variable, es la variable que estamos midiendo. OP, de Output, es la salida del controlador, aquello que podemos modificar para actuar sobre el proceso. Finalmente, el error es la diferencia entre el valor deseado y el valor actual.
| Variable | Significado | Ejemplo |
| SP | Consigna | 50 °C |
| PV | Temperatura medida | 42 °C |
| OP | Potencia aplicada | 0-100 % |
| Error (e) | SP − PV | +8 °C |
Si queremos 50°C y estamos midiendo 42°C, el error será de +8°C. Si la temperatura sube hasta 52°C, el error pasa a ser −2°C. El signo nos indica a qué lado de la consigna nos encontramos.
¿Qué hace realmente un PID?
PID son las iniciales de Proporcional, Integral y Derivativo. Podemos recordar intuitivamente la función de cada término pensando que P se fija en cuánto nos falta en este momento, I en cuánto error llevamos acumulado y D en la velocidad con la que está cambiando la variable. No es una definición matemática rigurosa, pero resulta útil para entender qué aporta cada acción antes de entrar en las ecuaciones.
Acción proporcional
P=K_{c}\cdot eKc es la ganancia proporcional del controlador. Cuanto mayor sea el error, mayor será la actuación. En nuestro proceso térmico si queremos 50°C y estamos a 25°C necesitaremos una actuación importante, mientras que si estamos a 49,5°C probablemente no tenga sentido aplicar la misma potencia.
El valor de Kc determina cuánto reaccionará el controlador. Una ganancia pequeña producirá una respuesta suave pero posiblemente lenta, mientras que una ganancia demasiado grande puede producir sobreimpulso e incluso oscilaciones. El principal inconveniente de utilizar únicamente acción proporcional es que muchos procesos terminan estabilizándose ligeramente alejados de la consigna. Esa diferencia permanente recibe el nombre de offset.
Acción integral
I(k) = I(k−1) + Ki · e(k) · Ts
Imaginemos que el proceso se estabiliza en 48,5°C cuando queremos mantener 50°C. El error es pequeño, pero permanece durante mucho tiempo. La acción integral corrige precisamente esa situación acumulando el error. Mientras sigamos por debajo de la consigna, la integral irá aumentando poco a poco su contribución y elevando la salida hasta eliminar el offset.
El problema aparece cuando utilizamos una acción integral demasiado agresiva, porque podemos acumular más corrección de la necesaria y provocar sobreimpulso u oscilaciones. Más adelante veremos además qué ocurre cuando la salida llega a sus límites físicos y la integral sigue acumulándose.
Acción derivativa
D = −Kd · (PV(k) − PV(k−1)) / Ts
Supongamos que estamos a 45°C. No es lo mismo estar a esa temperatura aumentando lentamente que hacerlo mientras la temperatura sube varios grados por segundo. En ambos casos el error es exactamente el mismo, pero en el segundo sabemos que nos aproximamos rápidamente a la consigna y probablemente convenga empezar a reducir la actuación.
La acción derivativa utiliza la velocidad de cambio de la señal. Podemos imaginarla como una especie de amortiguador, si la temperatura aumenta con demasiada rapidez, D reduce la actuación antes de alcanzar la consigna. Su principal inconveniente es que también responde a cambios rápidos provocados por ruido, por lo que no siempre aporta una mejora.
¿P, PI, PD o PID?
Una confusión habitual consiste en asumir que un PID completo será siempre mejor que un PI, un PD o incluso un P. No es así. Cada término debe existir porque resuelve un problema concreto, y añadir acciones innecesarias puede empeorar el comportamiento del controlador.
| Controlador | Cuándo puede resultar apropiado | Ejemplos típicos |
| P | Podemos tolerar cierto offset o el propio proceso presenta comportamiento integral. | Nivel sencillo, algunos procesos integradores. |
| PI | Necesitamos eliminar offset y la derivada aporta poco o tenemos una medida ruidosa. | Temperatura, caudal, presión, velocidad. |
| PD | Necesitamos amortiguamiento o anticipación, pero no integral adicional. | Posición, servomecanismos, sistemas mecánicos. |
| PID | Necesitamos eliminar offset y D mejora claramente la dinámica. | Procesos con inercia, algunos controles térmicos y de movimiento. |
Un buen ejemplo de PD es un control de posición. La acción proporcional empuja hacia el punto deseado y la derivativa actúa como amortiguamiento de modo que cuanto más rápidamente nos aproximamos al objetivo, más empieza a frenar. En este tipo de sistemas la derivada puede tener mucho sentido aunque no necesitemos acción integral.
En un control de temperatura «casero» es muy habitual que un PI sea suficiente. La integral elimina el offset y, debido a que la dinámica térmica suele ser relativamente lenta, la derivada puede aportar poco o resultar sensible al ruido de la medida. La idea importante es que más términos no significa mejor control. Si un PI controla correctamente el proceso, añadir D no tiene por qué aportar ninguna ventaja.
Ki y Kd frente a Ti y Td
No todos los libros, controladores y librerías expresan los parámetros del PID de la misma forma. Una formulación muy habitual en control industrial es la forma ideal o no interactiva:
OP = Kc \left[ e(t) + (\frac{1}{T_{i}}) ∫e(t)dt + Td · \frac{de(t)}{dt} \right]En esta expresión Kc es la ganancia proporcional del controlador, Ti es el tiempo integral y Td el tiempo derivativo. Tanto Ti como Td tienen unidades de tiempo. Un Ti menor implica una acción integral más intensa, mientras que un Td mayor aumenta el peso de la derivada.
En una implementación digital también es habitual trabajar con ganancias independientes. Si ambas expresiones representan la misma estructura PID, las relaciones entre ambas formas son:
\begin{align}
& K_{i}=\frac{K_{c}}{T_{i}} \hspace{0.2cm};\hspace{0.2cm} K_{d}={K_{c}}\times {T_{d}}
\end{align}Esto será importante cuando lleguemos a la sintonía, porque muchos métodos proporcionan directamente Kc, Ti y Td, mientras que nuestro código o una determinada librería puede esperar Kc, Ki y Kd. No debemos introducir Ti directamente en una variable llamada Ki ni Td en una variable llamada Kd.
Por ejemplo, si una regla de sintonía proporciona Kc = 2, Ti = 10s y Td = 2s, para una implementación con ganancias independientes tendremos Ki = 0,2 y Kd = 4. Además, antes de convertir parámetros debemos comprobar siempre qué formulación PID utiliza el controlador o la librería, porque no todas las implementaciones son equivalentes.
A lo largo de estos artículos utilizaremos Kc para la ganancia proporcional del controlador y reservaremos Kp para la ganancia del proceso durante la identificación. De esta forma evitamos mezclar dos conceptos completamente distintos.
Ecuaciones
Hasta ahora hemos hablado de las acciones proporcional, integral y derivativa, pero todavía falta una cuestión importante y es que no todos los controladores que llamamos PID aplican P, I y D sobre la misma señal. Dos controladores con los mismos valores de Kc, Ti y Td pueden responder de forma diferente si utilizan estructuras distintas.
PID clásico
En la estructura PID clásica las tres acciones trabajan sobre el error.

Un cambio brusco de SP modifica instantáneamente el error. Por tanto, P reacciona de inmediato y D también puede hacerlo con un pico importante. Este último efecto es el famoso derivative kick que veremos al llevar el algoritmo a código.
PI-D
En una estructura PI-D, P e I continúan trabajando sobre el error, pero D se calcula sobre PV.

Al cambiar SP, P mantiene su respuesta inmediata, pero D no reacciona directamente al salto de consigna, solo lo hará cuando PV empiece realmente a moverse.
I-PD
En I-PD únicamente la acción integral trabaja sobre el error. P y D se aplican sobre PV.

Con I-PD, un cambio de SP no llega directamente ni a P ni a D, por lo que la respuesta a cambios de consigna es más progresiva. Esto puede ser deseable cuando queremos evitar movimientos bruscos de OP, aunque también elimina la respuesta proporcional inmediata al cambio de SP.
El PID llevado a código
error = SP - PV; P = Kc * error; I += Ki * error * Ts; D = -Kd * (PV - PVant) / Ts; OP = P + I + D; PVant = PV;
Tiempo de muestreo
El PID no debería calcularse simplemente cada vez que Arduino termina loop(), porque el tiempo de ejecución del programa puede variar. Tanto la integral como la derivada dependen del tiempo, por lo que debemos ejecutar el cálculo con un periodo conocido Ts.
const unsigned long Ts_ms = 100;
const double Ts = Ts_ms / 1000.0;
if (millis() - tiempoAnterior >= Ts_ms)
{
tiempoAnterior += Ts_ms;
// Leer PV
// Calcular PID
// Actualizar OP
}
De esta forma evitamos bloquear el programa con delay() y mantenemos aproximadamente constante el intervalo entre cálculos.
Saturación y anti-windup
Todo actuador tiene límites físicos. En nuestro proceso térmico podemos normalizar la potencia entre 0 y 100 %, pero el controlador podría calcular teóricamente valores superiores. La resistencia de calentamiento no puede entregar un 130 % de potencia por mucho que el PID lo solicite.
PID calcula: 105 % → 125 % → 150 % → 180 % Salida física: 100 %
El problema es que la integral puede continuar acumulando error aunque la salida real ya esté saturada. Cuando finalmente nos acerquemos a la consigna, toda esa integral acumulada tendrá que descargarse antes de recuperar el control, provocando normalmente un sobreimpulso importante. Este fenómeno recibe el nombre de integral windup.
Una primera protección consiste en limitar el valor de la integral. Una alternativa algo mejor es utilizar integración condicional, es decir, si la salida ya está saturada y el error intenta empujarla todavía más hacia esa saturación, dejamos temporalmente de integrar. Cuando el error cambie de sentido y ayude a abandonar el límite, volvemos a hacerlo.
Derivative kick y ruido
Si calculamos la derivada sobre el error y modificamos bruscamente SP, el error también cambia instantáneamente. D interpreta ese salto como una velocidad enorme y puede producir un pico brusco en la salida, fenómeno conocido como derivative kick. Una solución habitual consiste en calcular la derivada sobre la PV, ya que la variable real no puede cambiar instantáneamente simplemente porque hayamos modificado la consigna.
La derivada responde además a cualquier cambio rápido, incluido el ruido. Un ADC, una sonda digital o una señal cuantificada pueden presentar pequeñas variaciones aunque la variable física apenas haya cambiado. Podemos filtrar la medida, pero un filtrado excesivo introduce retardo también en P e I; cuando utilizamos D suele ser preferible filtrar específicamente su acción. Si D no aporta una mejora clara, la opción más sencilla sigue siendo no utilizarla.
Acción de control
Antes de poner en marcha el PID debemos configurar correctamente su acción de control, que puede ser directa o inversa. Una forma sencilla de determinarla es olvidarnos momentáneamente de las ecuaciones y hacernos la siguiente pregunta:
Ante un incremento de la PV, ¿qué debe hacer la OP para corregirlo?
Si al aumentar PV necesitamos aumentar OP, la acción del controlador es directa. Si al aumentar PV necesitamos disminuir OP, la acción es inversa.
PV ↑ → OP ↑ ACCIÓN DIRECTA PV ↑ → OP ↓ ACCIÓN INVERSA
Es importante no confundir la acción del controlador con la respuesta del proceso. Para decidir si el PID debe configurarse como directo o inverso debemos pensar siempre en qué tiene que hacer OP cuando cambia PV para llevarla de nuevo hacia SP.
Volviendo a nuestro ejemplo, ante un incremento de la la temperatura (PV+) la resistencia tiene que entregar menos potencia (OP-), por lo que la acción que necesitamos configurar es inversa.
Inicialización y cambio manual/automático
Cuando arrancamos un PID no deberíamos asumir que todas sus variables internas pueden comenzar simplemente a cero. Si el proceso ya está funcionando y necesita una determinada salida para mantenerse cerca de su punto de trabajo, inicializar la integral a cero puede provocar un salto importante de OP en el momento en que activemos el controlador.
Imaginemos que el proceso está estable alrededor de 50°C con una potencia manual del 35%. Si pasamos a automático con la integral inicializada a cero, el controlador calculará inicialmente la salida únicamente a partir de P y D. El resultado puede ser muy diferente de ese 35% que mantenía el proceso estabilizado y provocar una perturbación precisamente durante el cambio de modo.
Inicialización de la integral
Una estrategia sencilla consiste en inicializar la contribución integral de forma que la salida calculada por el PID sea aproximadamente igual a la salida que ya estaba aplicando el proceso. Si conocemos OPmanual en el instante de la transferencia podemos utilizar:
I_{0} = OPmanual − P_{0} − D_{0}De esta manera, en el primer cálculo OP = P + I + D seguirá siendo aproximadamente igual a la salida anterior. Después la integral evolucionará normalmente según el error. Si calculamos D sobre PV también conviene inicializar PVant = PV, evitando que una medida antigua o no inicializada produzca una derivada artificial.
double error = SP - PV; double P = Kc * error; PVant = PV; double D = 0.0; integral = OPmanual - P - D; integral = constrain(integral, minOP, maxOP);
La idea general es que el controlador debe empezar desde un estado coherente con el estado real del proceso. Inicializar variables internas sin tener en cuenta dónde estamos puede introducir una perturbación que no pertenece al proceso, sino a nuestra propia implementación.
Paso manual/automático
La inicialización anterior está directamente relacionada con la transferencia entre modo manual y automático. En manual, el usuario fija directamente OP y el PID no gobierna el proceso. Cuando pasamos a automático, queremos que el controlador tome el control sin provocar un salto brusco de salida. A este comportamiento se le suele denominar bumpless transfer.
Para conseguirlo necesitamos que las variables internas del PID se ajusten durante la transferencia. La integral es normalmente el término más importante, porque actúa como memoria del controlador y puede absorber la diferencia entre la salida actual y las contribuciones P y D.
PV Tracking
Una estrategia muy utilizada para facilitar la transferencia entre manual y automático consiste en hacer que, mientras el controlador está en manual, la consigna siga a la variable de proceso. Es decir, SP = PV mientras permanecemos en manual. Esta función se conoce habitualmente como PV Tracking.
Supongamos que dejamos el proceso estabilizado manualmente en 46°C mientras la consigna automática almacenada permanece en 60°C. Si activamos directamente el PID aparecerá un error de 14°C y el controlador reaccionará con fuerza. Con PV Tracking, mientras estamos en manual SP sigue a PV, de modo que al pasar a automático el error inicial es aproximadamente cero.
Inicialización, PV Tracking y bumpless transfer son conceptos distintos pero complementarios. La inicialización hace coherentes las variables internas del PID con el estado real del proceso, PV Tracking reduce el error inicial durante manual y la transferencia sin salto persigue que OP no cambie bruscamente al pasar a automático.
Código básico en Arduino
El siguiente ejemplo reúne los conceptos principales y añade modo manual, PV Tracking, inicialización al pasar a automático y selección del tipo de PID. Se mantiene deliberadamente sencillo para que sea fácil relacionar cada bloque con la explicación anterior.
const int PIN_PV = A0;
const int PIN_OP = 6;
const unsigned long Ts_ms = 100;
enum TipoPID { PID_CLASICO, PI_D, I_PD };
enum AccionPID { DIRECT, REVERSE };
enum ModoPID { MANUAL, AUTOMATICO };
class PID
{
public:
PID(double *input, double *output, double *setpoint,
double kc, double ki, double kd,
TipoPID estructura, AccionPID accion, bool pvTracking)
: Input(input), Output(output), Setpoint(setpoint),
Kc(kc), Ki(ki), Kd(kd),
estructuraPID(estructura), accionPID(accion),
pvTrackingActivo(pvTracking)
{
modoPID = MANUAL;
minOutput = 0.0;
maxOutput = 100.0;
sampleTimeMs = 100;
integral = 0.0;
PVant = *Input;
errorAnt = *Setpoint - *Input;
salidaManual = *Output;
SPoperador = *Setpoint;
tiempoAnterior = 0;
}
bool Compute()
{
if (modoPID == MANUAL)
{
*Output = Limitar(salidaManual);
if (pvTrackingActivo) *Setpoint = *Input;
return false;
}
unsigned long ahora = millis();
if (ahora - tiempoAnterior < sampleTimeMs) return false;
double Ts = (ahora - tiempoAnterior) / 1000.0;
tiempoAnterior = ahora;
double error = *Setpoint - *Input;
double signo = SignoAccion();
double P = (estructuraPID == I_PD)
? -signo * Kc * (*Input)
: signo * Kc * error;
double D = (estructuraPID == PID_CLASICO)
? signo * Kd * (error - errorAnt) / Ts
: -signo * Kd * ((*Input) - PVant) / Ts;
double incrementoIntegral = signo * Ki * error * Ts;
double nuevaIntegral = integral + incrementoIntegral;
double opSinLimitar = P + nuevaIntegral + D;
if (!((opSinLimitar > maxOutput && incrementoIntegral > 0.0) ||
(opSinLimitar < minOutput && incrementoIntegral < 0.0)))
integral = nuevaIntegral;
*Output = Limitar(P + integral + D);
PVant = *Input;
errorAnt = error;
return true;
}
void SetMode(ModoPID nuevoModo)
{
if (nuevoModo == modoPID) return;
if (nuevoModo == MANUAL)
{
salidaManual = Limitar(*Output);
SPoperador = *Setpoint;
modoPID = MANUAL;
if (pvTrackingActivo) *Setpoint = *Input;
return;
}
*Setpoint = pvTrackingActivo ? *Input : SPoperador;
InicializarBumpless();
modoPID = AUTOMATICO;
tiempoAnterior = millis();
}
void SetManualOutput(double valor)
{
salidaManual = Limitar(valor);
if (modoPID == MANUAL) *Output = salidaManual;
}
double GetManualOutput() { return salidaManual; }
void SetTunings(double kc, double ki, double kd)
{
if (kc < 0 || ki < 0 || kd < 0) return;
Kc = kc;
Ki = ki;
Kd = kd;
if (modoPID == AUTOMATICO) InicializarBumpless();
}
void SetStructure(TipoPID estructura)
{
if (estructura == estructuraPID) return;
estructuraPID = estructura;
if (modoPID == AUTOMATICO) InicializarBumpless();
}
void SetDirection(AccionPID accion)
{
if (accion == accionPID) return;
accionPID = accion;
if (modoPID == AUTOMATICO) InicializarBumpless();
}
void SetPVTracking(bool activar)
{
if (activar == pvTrackingActivo) return;
if (activar)
{
SPoperador = *Setpoint;
pvTrackingActivo = true;
if (modoPID == MANUAL) *Setpoint = *Input;
}
else
{
pvTrackingActivo = false;
if (modoPID == MANUAL) *Setpoint = SPoperador;
}
}
void SetSetpoint(double valor)
{
SPoperador = valor;
if (modoPID == AUTOMATICO || !pvTrackingActivo)
*Setpoint = valor;
}
void SetOutputLimits(double minimo, double maximo)
{
if (minimo >= maximo) return;
minOutput = minimo;
maxOutput = maximo;
salidaManual = Limitar(salidaManual);
*Output = Limitar(*Output);
if (modoPID == AUTOMATICO) InicializarBumpless();
}
void SetSampleTime(unsigned long tiempoMs)
{
if (tiempoMs > 0) sampleTimeMs = tiempoMs;
}
private:
double *Input, *Output, *Setpoint;
double Kc, Ki, Kd;
double integral, PVant, errorAnt;
double salidaManual, SPoperador;
double minOutput, maxOutput;
TipoPID estructuraPID;
AccionPID accionPID;
ModoPID modoPID;
bool pvTrackingActivo;
unsigned long sampleTimeMs, tiempoAnterior;
double SignoAccion()
{
return (accionPID == REVERSE) ? 1.0 : -1.0;
}
double Limitar(double valor)
{
if (valor > maxOutput) return maxOutput;
if (valor < minOutput) return minOutput;
return valor;
}
void InicializarBumpless()
{
double error = *Setpoint - *Input;
double signo = SignoAccion();
double P = (estructuraPID == I_PD)
? -signo * Kc * (*Input)
: signo * Kc * error;
PVant = *Input;
errorAnt = error;
integral = *Output - P;
}
};
// ==========================================================
// PROCESO
// ==========================================================
double SP = 50.0;
double PV = 0.0;
double OP = 0.0;
double Kc = 1.0;
double Ki = 0.4;
double Kd = 0.0;
PID pid(&PV, &OP, &SP, Kc, Ki, Kd, PI_D, REVERSE, true);
// ==========================================================
// SETUP
// ==========================================================
void setup()
{
pinMode(PIN_OP, OUTPUT);
pid.SetSampleTime(Ts_ms);
pid.SetOutputLimits(0.0, 100.0);
pid.SetManualOutput(35.0);
pid.SetMode(MANUAL);
}
// ==========================================================
// LOOP
// ==========================================================
void loop()
{
PV = analogRead(PIN_PV) * 100.0 / 1023.0;
pid.Compute();
analogWrite(PIN_OP, (int)(OP * 255.0 / 100.0));
}
Como veis, implementar un PID digital con unas protecciones y características mínimas hace que el código alcance fácilmente unos cientos de líneas. En este caso está todo contenido en un único archivo, aunque la lógica del PID se ha separado en una clase independiente para mantener la función void loop() más limpia y facilitar su reutilización en otras implementaciones.
Lo ideal sería trasladar esta clase a una librería independiente, dejando las funciones void setup() y void loop() centradas únicamente en la lógica principal de nuestra aplicación. Sin embargo, el objetivo de este apartado no es construir una librería completa, sino que el lector comprenda cómo se realiza internamente la implementación de un controlador PID digital y qué elementos debemos tener en cuenta.
En el artículo 4 veremos con más detalle las librerías disponibles para Arduino, sus características y hasta qué punto pueden encargarse de todo este trabajo por nosotros.
Aquí tenéis las funcionalidades disponibles de nuestra implementación:
// Trabajar en manual pid.SetMode(MANUAL); pid.SetManualOutput(40.0); // Cambiar la sintonia pid.SetTunings(1.5, 0.15, 0.0); // Seleccionar PI-D pid.SetStructure(PI_D); // Accion inversa pid.SetDirection(REVERSE); // Activar PV Tracking pid.SetPVTracking(true); // Pasar a automatico sin salto de OP pid.SetMode(AUTOMATICO); // Introducir la nueva consigna pid.SetSetpoint(50.0);
He dejado Kd = 0, por lo que inicialmente tenemos un controlador PI. Los valores utilizados para Kc y Ki son solo un ejemplo de implementación y no representan una sintonía válida para nuestro proceso. La pregunta realmente interesante es de dónde deberían salir esos valores.
No sintonices a ciegas
Podríamos empezar a modificar Kc, Ki y Kd hasta conseguir una respuesta aparentemente aceptable, pero podemos hacerlo de una forma bastante más sistemática. El propio Arduino puede ayudarnos a provocar una respuesta conocida en el proceso y registrar qué ocurre. Por ejemplo, podemos colocar el controlador en manual, aumentar la salida del 30 al 40% y observar cómo evoluciona la temperatura.
De esa respuesta podemos obtener cuánto responde el proceso, cuánto tarda en empezar a hacerlo y con qué rapidez evoluciona. En nuestro ejemplo de control de temperatura podemos testear en lazo abierto (ya llegaremos aquí), en otras situaciones no podremos trabajar en lazo abierto y tendremos que obtener esa información manteniendo el proceso en lazo cerrado. El objetivo es llegar a parámetros medidos del proceso y utilizarlos para calcular la sintonía.
En el siguiente artículo veremos cómo identificar el proceso en lazo abierto y en lazo cerrado.
Serie Introducción al PID y su implementación en Arduino
- Artículo 1: Entender e implementar antes de sintonizar
- Artículo 2: Identificación de procesos para la sintonía de un PID
- Artículo 3: Métodos de sintonía PID a partir de la identificación del proceso
- Artículo 4: Librerías PID y herramientas de identificación para Arduino
Lectura recomendada
[1] Tore Hägglund. Process Control in Practice. De Gruyter, 2023. eBook ISBN: 978-3-11-110495-9.
[2] Karl J. Åström, Tore Hägglund. Control PID avanzado. Pearson Educación, 2009. ISBN: 978-84-8322-511-0.
[3] Daniel Chuk. Los sistemas de primer orden y los controladores PID. 2012. [Link] [Link2]
[4] Fernando Morilla García. ¿Qué quieres controlar? ¿Has probado con controladores PID? Dpto. de Informática y Automática, UNED, 2015. [Link]