Programación de un PID en Arduino – Teoría y Método de Calibración – Simulación en Proteus

En esta ocasión vamos aprender a usar la Librería PID, esta nos permitirá configurar no solo uno, si no la cantidad de PIDs que necesitemos en nuestro Arduino, para esto requerimos primeramente conocer la teoría asociada, y por supuesto conocer todas las instrucciones propias de la Liberia, para lograr la mayor comprensión de este tema, se realizara una simulación en Proteus ISIS. al final de este post encontraras todos los archivos de la simulación, programación y librerías, comencemos…

Tutorial en Youtube

¿QUE ES UN PID?

Comencemos por la teoría, si bien hay mucha información al respecto, tratare de explicar esto desde un punto de vista lo mas sencillo posible. Lo primero que debes saber es que un PID es un sistema de control (punto de operación) que podría ser por ejemplo 100°C, por ende tendremos un OUTPUT (salida controlada) que debería oscilar lo mas cerca posible al valor marcado en el SETPOIN, en caso que esto no suceda el sistema PID debe tomar una acción de control que corrija el error existente entre la entrada (INPUT) y la salida (OUTPUT) del sistema. La forma de hacer esta corrección es aplicando tres tipos de controles diferentes sumados entre si, es decir:

  • Control Proporcional: Es un control que se aplica desde 0% al 100%, por ejemplo abrir en forma proporcional una válvula al 10,20,50% de forma gradual, es decir, es un control que se ejecuta en tiempo real, puedo leer el error en tiempo real.
  • Control Integral: La definición de una integral es el área bajo la curva de la función (si, las integrales tienen usos prácticos y no solo sirven para fastidiar la existencia), aplicado a un sistema de control nos permite calcular el error ocurrido en el pasado, es decir, matemáticamente puedo leer el error en el tiempo pasado.
  • Control Derivativo:

Toma en cuenta que un PID se basa en un sistema de control de lazo cerrado, donde se tiene una linea de control y una linea de instrumentación que nos permite leer los errores de la salida con respecto a la entrada, sin ánimos de desviarnos demasiado del tema iremos al grano:

Diagrama de bloque de un PID:

En el diagrama mostrado arriba, podemos observar que la acción Proporcional es acompaña por una componente integrativa y otra derivativa, todas estas componentes son acompañadas de un factor de multiplicación K, siendo «Kp» la constante proporcional, Ki, constante integrativa y Kd, la constante derivativa, estas constantes permiten calibrar el sistema PID.

  • KP: Ajuste grueso, se logra aumentar bruscamente la capacidad de control, de ser muy elevado el ajuste se generan picos en la variable de control, si por el contrario el ajuste es muy pobre, la señal controlada le demorara mucho tiempo en estabilizarse en valor deseado, valor recomendado entre 0 a 50.
  • KI: Ajuste medio, permite ajustar la agresividad con la cual el PID hará la correcciones en caso de cambios muy bruscos en la variable. Valores típicos entre 0.1 a 500.
  • KD: Es el ajuste fino, permite ajustar las inestabilidades y oscilaciones del PID cuando la salida es cercana al SETPOIN, valores típicos de 0.1 a 5000.


Si algunas de las constantes es cero el sistema ya no será un PID, dependiendo de cual de estas sea cero el resultado será por ejemplo un control PD en caso que KI = 0, en caso que KD = 0, el control seria un PI, y así sucesivamente.

En resumen:

Un PID puede hacer correcciones de control para mantener una variable en su estado deseado tomando decisiones en base a lo que observa en el presente, lo que lee en el pasado y a lo predice que sucederá en el futuro, ¿Qué interesante verdad?.

DESCARGAR LIBRERÍA PID PARA ARDUINO

Lo primero es bajar la librería «Arduino-PID-Library-master.zip» podemos descargarla directamente dando Clic Aquí, y luego cargar la librería a nuestro IDE Arduino (sin descomprimirla) de la siguiente forma :

COMO USAR LA LIBRERÍA PID

Bien, instalada la librería procedemos a explicar de forma sencilla como utilizarla, para esto es importante conocer cada una de las instrucciones asociadas a esta librería, comencemos:

Declarar Librería PID:

Comencemos por declarar la librería, para esto copiamos la siguiente instrucción en la parte superior de nuestro código:

#include <PID_v1.h>   //Incluyo Librería PID.

Variables Asociadas al PID:

Crearemos ahora las variables asociadas a nuestro PID, para esto:

double SETPOINT = 37; //Sera el valor que deseamos mantener en el tiempo.
double INPUT_PID;     //Sera la el valor de entrada a controlar.
double OUTPUT_PID;    //Sera nuestra salida, efectúa la acción de control.
double KP = 2;        //Constante Proporcional, nosotros asignamos el valor.
double KI = 1;        //Constante Integral, nosotros asignamos el valor.
double KD = 1;        //Constante Derivativa, nosotros asignamos el valor.
#define TIME_PID 100  //Cada 100ms se actualizara el PID.
#define MINIMO 0      //El valor mínimo de OUTPUT será 0.
#define MAXIMO 255    //EL valor máximo de OUTPUT será 255.

Las variables de nuestro PID deben ser de tipo double, dado que estamos trabajando con funciones matemáticas y el mejor tipo de variable para este fin son las double, estas permiten usar coma flotante y los resultados son mas precisos en comparación con las variables tipo float.


Configuración y Declaración del PID:

Creamos ahora la estructura de nuestro PID, para esto usamos creamos un objeto nuevo dentro de la Librería PID, es decir:

PID namePID(&INPUT_PID, &OUTPUT_PID, &SETPOINT ,KP,KI,KD, DIRECT);


namePID es el nombre del objeto PID, podemos colocar el nombre que deseemos. Las primeras tres declaraciones deben ir acompañadas de un &, los siguientes tres son nuestras constantes, por ultimo debemos indicar si nuestro PID sera en modo DIRECT o en modo RESERVE.


Modo DIRECT:

Modo RESERVE: 


Modo de Ajuste del PID:

namePID.SetMode(AUTOMATIC); //Seleccionamos AUTOMATIC o MANUAL.

En caso que usemos AUTOMATIC el PID  hará los ajustes de forma autónoma, no tiene sentido usar la opción MANUAL, dado que esta supone abrir la posibilidad de modificar los valores de KP, KI, KD respectivamente, estas constantes se recomiendan dejarlas en un valor estático, pero en caso que sea necesario varias los valores de las constantes a mitad de programa se configura la opción MANUAL seguida de la siguiente instrucción que debe estar ubicada en el void loop de nuestro programa.
namePID.SetTunings(KP, KI, KD); //Me permite modificar las constantes en cualquier punto del void loop.


Como Iniciar el PID:

namePID.Compute(); //Me permite Activar el PID, se introduce en el void loop()

Ajustar Rango de Salida PID:

namePID.SetOutputLimits(MINIMO,MAXIMO); //Ajusta los valores de nuestra salida

Esta instrucción nos permite colocar un limite a los valores que puede tomar la salida, esto resulta muy útil en caso de querer asociar nuestro PID a una salida PWM de Arduino, estas salidas PWM se controlan con rangos de 0 a 255.

En caso de usar un PID con un relé electromecánico (cosa que no es recomendable, dado que estos relés solo tiene dos estados posibles y son susceptibles a desgaste mecánicos) se recomienda establecer el valor de mínimo como 0, y el valor máximo como 1, de esta forma el relé estará encendido o apagado, sin puntos intermedios.

Configurar Tiempo de Muestreo PID:

namePID.SetSampleTime(TIME_PID); //Configuramos cada cuantos ms nuestro PID hará una actualización en su estado.


Por defecto la librería PID viene con un tiempo de muestreo de 200ms, así que no es obligatorio declarar esta instrucción, pero en caso que este valor de 200ms te parezca poco, o mucho, ya sabes como ajustarlo al valor que mejor consideres.
EJEMPLO DE UN PID FUNCIONAL EN ARDUINO

//Control de TEMPERATURA CON PID - Autor: Ing. Fernando Molleja
//    SE USARA UN SENSOR LM35 PARA LECTURA DE TEMPERATURA
//EL CONTROL SE HARA CON UNA SALIDA PWM CONECTADA A UN RELE SOLIDO

#include <PID_v1.h>   //Incluyo Librería PID.
#include <LiquidCrystal.h> //Librería Pantalla LCD.
LiquidCrystal lcd(7, 6, 5, 4, 3, 2); //RS,E,D4,D5,D6,D6,D7.
double SETPOINT = 37; //Sera el valor que deseamos mantener en el tiempo.
double INPUT_PID;     //Sera la el valor de entrada a controlar.
double OUTPUT_PID;    //Sera nuestra salida, efectúa la acción de control.
double KP = 2;        //Constante Proporcional, nosotros asignamos el valor.
double KI = 1;        //Constante Integral, nosotros asignamos el valor.
double KD = 1;        //Constante Derivativa, nosotros asignamos el valor.
#define TIME_PID 100  //Cada 100ms se actualizara el PID.
#define MINIMO 0      //El valor mínimo de OUTPUT será 0.
#define MAXIMO 255    //EL valor máximo de OUTPUT será 255.
#define RESISTENCIA 8 //EL PIN 8 ESTA ASOCIADO A UNA RESISTENCIA ELECTRICA.
PID namePID(&INPUT_PID, &OUTPUT_PID, &SETPOINT ,KP,KI,KD, DIRECT);

void setup() {
namePID.SetMode(AUTOMATIC); //Seleccionamos AUTOMATIC o MANUAL.
namePID.SetSampleTime(TIME_PID); //Asigno valor de muestreo.
namePID.SetOutputLimits(MINIMO, MAXIMO); //Declaro rango de salida.
pinMode(RESISTENCIA, OUTPUT); //Asigno este pin como salida.
lcd.begin(16, 2); //Activo LCD 16X2.
}
void loop() {
//Formula para convertir lectura de un LM35 a Grados °C:
INPUT_PID = ((analogRead(A0) * 5000.0) / 1023) / 10;
namePID.Compute(); //ACTIVO MI PID.
analogWrite(RESISTENCIA, OUTPUT_PID); // Aplico PWM en base a PID.
//Escribo en Pantalla LCD:
lcd.setCursor(0, 0);
lcd.print("Tempe: ");
lcd.print(INPUT_PID);
lcd.setCursor(0, 1);
lcd.print("PID: ");
lcd.print(OUTPUT_PID);
}
Simulación En Proteus


DESCARGA DE ARCHIVOS


Para descargar la simulación en Proteus Isis y la programación de Ejemplo has Clic AquíNo dudes en comentarnos cualquier duda o inquietud que tengas sobre el tema, adiós.

Deja un comentario