Más allá del mar, habrá un lugar para convertir tu Arduino en un PID
PID PID PID!!!! La semana pasada hablaba del PID. Pero claro tanto hablar del PID no caí en que un PID se puede implementar también en un ordenador o incluso en un Arduino. Su estado natural es en una serie de cajas que se programan con los valores adecuados de P, I y D. Estas cajas ya se encargan de controlar el proceso.
En realidad, estos valores de P, I y D muchas veces los calcula la misma caja con algo llamado ‘autotune’, que no es más que una elección automática de los valores que hace el PID según el proceso que tengamos que controlar. Pero vamos, que ¿Por qué no implementarlo con Arduino?
¡Vamos a ello!
El PID en Arduino
La verdad es que para programar un PID en C el código en sí da bastante miedo (Puedes buscarlo en la red). Ya que se debe de programar la integral y la derivada y eso siempre trae problemas porque esas funciones matemáticas no existen en C como tal. Así que hay que aplicar algunos trucos.
Otro modo de programación sería una programación visual. Para ello en el ámbito industrial se utiliza mucho Labview. Que es un pseudo-lenguaje de programación. Labview dispone de una serie de cajas que puedes unir para hacer las funciones. En este caso, existen cajas para PID que te permiten añadirle a unos terminales de la caja los valores de los parámetros P, I y D.
Esto hace la cosa bastante más sencilla. Pero, ¿Quieres algo más sencillo aún? En Arduino aún es más sencillo ya que solo tenemos que aplicar la librería de PID para poder empezar a funcionar. Para llamarla se hace así:
#include <PID_v1.h>
Pero antes tendrás que haberla instalado desde el Library Manager. Se llama PID y su autor es Brett Beauregard.

Información básica sobre Proteción de datos
Responsable ➥ Sergio Luján Cuenca
Finalidad ➥ Gestionar el envío de correos electrónicos con artículos, noticias y publicidad. Todo relacionado con los temas de rufianenlared.com
Legitimación ➥ Consentimiento del interesado
Destinatarios ➥ Estos datos se comunicarán a MailRelay para gestionar el envío de los correos electrónicos
Derechos ➥ Acceder, rectificar y suprimir los datos, así como otros derechos, como se explica en la política de privacidad
Plazo de conservación de los datos ➥ Hasta que se solicite la supresión por parte del interesado
Información adicional ➥ Puedes encontrarla en la política de privacidad y el aviso legal
Estructura para programar un PID
Una vez con la librería adecuada, ya podemos crear el objeto PID. Para ello utilizaremos:
double Setpoint, Entrada, Salida; int Kp = 3; int Ki = 1; int Kd = 0; PID nombrePID(&Entrada, &Salida, &Setpoint,Kp,Ki,Kd, DIRECT);
Donde nombrePID es el nombre del objeto PID, Entrada es la variable de entrada que vamos a controlar, Salida es la variable que ajustaremos con el PID, Setpoint es el valor al que queremos que esté la salida y DIRECT es la dirección en la que actúa el PID cuando encuentra un error. Podría ser REVERSE pero no es muy común.
Kp, Ki y Kd son nuestros valores de P, I y D pero con otro nombre. Todos estos valores pueden ser escritos en número o ser declarados como variables. Por otra parte, los tres primeros parámetros que llevan un & delante, deben de ser declarados como variables antes.
Esta declaración se hace antes del setup, ya que nombrePID es un objeto nuevo que contiene a nuestro PID. Exactamente igual que pasaba con los motores paso a paso. Una vez definido eso, dentro del setup deberemos de incluir la orden:
nombrePID.SetMode(AUTOMATIC);
Donde lo que decimos es si nuestro PID funcionará en automático y él solo ajustará los parámetros o en modo manual. Para ello hay que poner o MANUAL o AUTOMATIC en el parámetro de la función.
Una vez con todo ya definido y hechas las configuraciones, en el loop ya se puede llamar al PID para que actúe:
nombrePID.Compute();
La función Compute debe de ser llamada cada vez que necesitemos que actúe el PID. Esa es la razón por la que se inserta dentro del bucle principal, también llamado loop.
Otras opciones de configuración…
En la configuración, también se puede utilizar una función que permite poner límites a la salida. Lo normal es que vaya de 0 a 255 en el caso de los pines digitales PWM, por lo que puede ser de utilidad:
nombrePID.SetOutputLimits(minimo,maximo);
Como ves, solo hay que añadir los valores del mínimo y el máximo. Otra configuración interesante es la de decidir los valores de Kp, Ki y Kd si queremos modificar los que le dimos al inicio:
nombrePID.SetTunings(Kp, Ki, Kd);
Esto solo tiene sentido si estamos en modo manual y hay un cambio a mitad del programa o similar. Sino, con la definición inicial debería de bastarnos…
Otra cosa importante es, cada cuánto toma muestras nuestro PID. De manera predeterminada lo hace cada 0.2 segundos. Pero si te parece muy poco o demasiado, siempre puedes cambiarlo utilizando la instrucción:
nombrePID.SetSampleTime(Tiempo_Muestreo);
Un ejemplito y un adiós…
Por último, para rizar más el rizo, está la siguiente función:
nombrePID.SetControllerDirection(DIRECT);
Esta se define con el PID, pero puede que quieras cambiarlo on the go. ¿Para qué sirve exactamente esto de DIRECT o REVERSE? Directo significa que cuanto más salida necesito, más entrada le tengo que dar. En el caso del ascensor que subía con el aire de un ventilador, a más altura, necesitaré más aire del ventilador.
En el caso de una nevera, cuanta más energía le dé conseguiré una temperatura menor. En este caso la acción es invertida, este es el caso de REVERSE.
Y nada, espero que no te vuelvas loco con esto de los PIDS pero puedes probarlos con solo unas líneas de código y así sales de dudas de si te sirve para tu proyecto.
Por cierto, te dejo un poco de código de ejemplo 😉
#include <PID_v1.h> double Setpoint, Entrada, Salida; int Kp = 3; int Ki = 1; int Kd = 0; PID nombrePID(&Entrada, &Salida, &Setpoint,Kp,Ki,Kd, DIRECT); void setup() { nombrePID.SetMode(MANUAL); } void loop() { nombrePID.Compute(); }