Sintonizar PID con Arduino I – Control de temperatura

Sintonizar PID con Arduino I – Control de temperatura

Introducción

Existen un montón de artículos sobre la implementación de controladores PID con Arduino, pero en la mayoría de ellos me encuentro que la sintonización se hace con el método de prueba y error. En este aspecto el algoritmo PID ha demostrado ser muy robusto, lo suficiente como para salir airoso incluso ante una «mala» sintonización. Esto no quiere decir que el método de prueba y error no sea válido, de hecho, cuando montamos algo serio por primera vez y no tenemos referencias de funcionamiento es normal recurrir a métodos pragmáticos, pero mi intención es que tengáis una alternativa de sintonización analítica.

No voy a aburriros con conceptos matemáticos ni espero perderme en la selva con las explicaciones, la intención de este artículo es que con un breve análisis y con unas sencillas herramientas desarrolladas para la ocasión seamos capaces de evitar el uso del famoso método de «prueba y error» y aplicarlo a la mayoría de nuestras implementaciones.

Sistema empleado

El sistema empleado es muy sencillo, en esencia consta de de una fuente de calor, un sensor de temperatura y un ventilador.

Alzado y planta del sistema

La fuente de calor es una resistencia de 12V como las que podemos encontrar en el interior de las planchas de alisar el pelo. En el interior y pegando a la fuente de calor he situado un sensor de temperatura DS18B20 y en la parte superior hay un ventilador de 12V y 120×120 mm para bajar la temperatura del sistema. El objetivo es mediante un controlador PID mantener estable la temperatura del interior aprovechando una salida PWM de Arduino.

El sistema presenta principalmente dos limitaciones. La primera es que el ventilador no es muy potente (1800 rpm) y al 100% (255PWM) es capaz de enfriar el sistema unos 15ºC. La segunda es que tenemos una zona muerta inicial en la que el ventilador no gira y es que hasta que no pasamos del 16% (PWM 40) el ventilador no gira. Esto puede hacer que en ciertos puntos de consigna el ventilador esté arrancando y parando o simplemente no actuando, lo que afectará a nuestro control PID. Para evitar esto intentaremos movernos en un margen de 54-44ºC.

Montaje del sistema

Componentes

El coste aproximado si tienes que comprar todos los componentes es de entre 40 y 50€

Esquema de conexiones

Conexiones del sistema

Para el montaje la única consideración es que cuando trabajamos con varios voltajes las masas deben ir unidas.

Código de Arduino

//***************************************************************
// Desarrollado por Garikoitz Martínez [garikoitz.info] [05/2020]
// https://garikoitz.info/blog/?p=638
// https://garikoitz.info/blog/?p=674
//***************************************************************
//===============================================================
// Librerías
//===============================================================
#include <Arduino.h>
#include <OneWire.h>
#include <DallasTemperature.h>   
#include <Wire.h>
#include <LCD.h>            
#include <LiquidCrystal_I2C.h>
#include <math.h>
#include <PID_v1.h>
//===============================================================
// Variables globales & Constantes
//===============================================================
OneWire onewire(8);
DallasTemperature sensors(&onewire);
double Setpoint, Input, Output;
double Kp=55, Ki=29, Kd=0;
PID myPID(&Input, &Output, &Setpoint, Kp, Ki, Kd, REVERSE);
boolean modo = false; //false=auto true=manual
String modos = "";
float OP;
const int pot =0; // Potenciómetro conectado al pin A0
const int vent =5; // ventilador conectado al pin 5
int velocidad;
LiquidCrystal_I2C lcd(0x3F,2, 1, 0, 4, 5, 6, 7);
//===============================================================
// SETUP
//===============================================================
void setup(void) {
    Serial.begin(9600);
    pinMode(vent, OUTPUT);
    sensors.begin();
    sensors.setResolution(0, 11);
    lcd.begin(20,4);
    lcd.setBacklightPin(3,POSITIVE);
    lcd.home(); 
}
//===============================================================
// BUCLE PRINCIPAL
//===============================================================
void loop() {
      // Interruptor Auto/Manual
      if (digitalRead(12) == HIGH){
        modo=true;
        modos="MANUAL";
        myPID.SetMode(MANUAL);
      }else{
          modo=false;
          modos="AUTOMATICO";
          myPID.SetMode(AUTOMATIC);
       }
       sensors.requestTemperatures();
       Input = sensors.getTempCByIndex(0);
     // MODO MANUAL Potenciómetro ---> PWM Ventilador
     if (modo==true){
         velocidad = analogRead (pot);
         OP = map(velocidad, 0, 1023, 0, 255);
         analogWrite(vent, OP);
         myPID.SetMode(MANUAL);
         //LCD en MANUAL
         lcd.clear();
         lcd.setCursor(0,0);
         lcd.print("====== ");
         lcd.print(modos);
         lcd.print(" ======");
         lcd.setCursor(0,1);
         lcd.print("  T: ");             
         lcd.print(Input,2);
         lcd.print("\337C ");
         lcd.setCursor(0,2);
         lcd.print(" OP: "); 
         lcd.print(OP*0.3921);
         lcd.print(" % ");
         lcd.setCursor(0,3);
         lcd.print("PWM: ");
         lcd.print(OP,0);
        // DEBUG PUERTO SERIE (Para Arduino COM Plotter)
        Serial.print("#");            //Char inicio
        Serial.print(0);              //Dejo vacío para ACP
        Serial.write(" ");            //Char separador
        Serial.print(Input,2);        //PV
        Serial.write(" ");            //Char separador
        Serial.print(OP*0.3921,0);    //OP
        Serial.println();
     }
     // MODO AUTOMÁTICO---------------------------------------------
     if (modo==false){
        float set=analogRead(pot);
        Setpoint=map(set,0,1023,60.0,40.0); 
        Input = sensors.getTempCByIndex(0);
        myPID.SetMode(AUTOMATIC);
        //-----------------------------
        //LCD en AUTO
        lcd.clear();
        lcd.setCursor(0,0);
        lcd.print("==== ");
        lcd.print(modos);
        lcd.print(" ====");
        //
        lcd.setCursor(0,1);
        lcd.print("PV: ");
        lcd.print(Input,2);
        lcd.print(" \337C ");
        lcd.setCursor(0,2);
        lcd.print("SP: ");
        lcd.print(Setpoint,2);
        lcd.print(" \337C ");
        lcd.setCursor(0,3);
        lcd.print("OP: ");
        lcd.print(Output*0.3921,2);
        lcd.print(" %");
        //
        myPID.Compute();
        analogWrite(vent, Output);
       //===============================================================
       // DEBUG PUERTO SERIE (Para Arduino COM Plotter)
       //===============================================================
        Serial.print("#");              //Char inicio
        Serial.print(Setpoint,0);       //SP
        Serial.write(" ");              //Char separador
        Serial.print(Input,2);          //PV
        Serial.write(" ");              //Char separador
        Serial.print(Output*0.3921,0);  //OP
        Serial.println();
    }
    delay(1000);
}//Fin void loop

Identificación del sistema

Recopilación de datos en lazo abierto

Con el controlador de temperatura en manual hacemos una serie de movimientos en la salida PWM del ventilador para ver como reacciona la temperatura.

StepTest

Se observa que la zona donde mejor trabaja el ventilador es en los tres primeros escalones, es decir, entre 55 y 45ºC. Por debajo de 45ºC y a medida que nos acercamos al límite inferior el tiempo de establecimiento es cada vez más corto y las constantes del sistema que hemos obtenido ya no son representativas y por lo tanto nuestro control se degradará.

Ejemplo de cálculo de K, To y Tp
Escalón analizado
Cálculo de las constantes con ACP

Con la ayuda de ACP obtenemos las siguientes constantes del sistema.

K0,120%/%
To8,5segundos
Tp103,5segundos
Constantes del sistema

Ajuste y simulación en lazo cerrado

A continuación un resumen de las posibles sintonías ofrecidas por ACP para nuestro sistema.

CC-25CC-10ZN-LA-25ZN-LA-10ITAE-SPIAE-SPLambdaIMCSIMCImp.SIMC
PKc92,0255,2191,3860,8248,254,3463.8988,027588,61
ITi24,1628,9928,3328,33101,83104,18103,5105,64640
Tf51031,5
PKc137,3882,43152,21101,3768,1579,4397,07
ITi20,2224,2721,2521,25132,03141,91107,75
DTd3,053,053,43,43,133,674,08
Posibles sintonías para el sistema obtenidas con ACP

Se aprecia que los métodos clásicos como el de Cohen Coon o Ziegler Nichols proponen sintonías más agresivas (>Kp y <Ti) y más centradas en la ganancia proporcional que los métodos más modernos como el Improved SIM C de Skogestad. Los métodos ITAE-SP e IAE-SP están en rojo porque el sistema no cumple la condición de aplicación 0,1<To/Tp<1. Cuando el sistema no cumple con alguna restricción del método de sintonía, ACP nos avisa con un mensaje. Esto no significa que no lo podamos usar, sencillamente que el método tiene restricciones de aplicación.

Resultados

CC-10 (PI)

La simulación refleja perfectamente el comportamiento real del sistema. La sintonía se comporta bien ante cualquier cambio del punto de consigna.

Respuesta real sintonía CC-10 (PI)
Simulación CC-10 (PI)

CC-10 (PID)

De nuevo la simulación y la respuesta real del sistema son similares. Aunque el comportamiento es bueno, al incorporar el termino derivativo la salida se ha vuelto más oscilante.

Respuesta real sintonía CC-10 (PID)
Simulación CC-10 (PID)

ZN-LA-10 (PI)

Al igual que con la sintonía de Cohen-Coon la simulación y el sistema real son prácticamente iguales con una respuesta equilibrada.

Respuesta real sintonía ZN-LA-10 (PI)
Simulación ZN-LA-10 (PI)

Lambda (PI)

La respuesta real no coincide con la simulación. Finalmente el control llega a mantenerse estable pero no reacciona de la manera esperada ante los cambios del punto de consigna.

Respuesta real sintonía Lambda (PI)
Simulación Lambda (PI)

IMC (PI)

La respuesta real no es tan suave como augura la simulación. El control es estable ante diferentes cambios del punto de consigna.

Respuesta real sintonía IMC (PI)
Simulación IMC (PI)

SIM C (PI)

La respuesta real no coincide con la simulación. El control es estable ante diferentes cambios del punto de consigna mejorando la respuesta del método IMC.

Respuesta real sintonía SIM C (PI)
Simulación SIM C (PI)

Improved SIM C (PI)

La respuesta real no coincide con la simulación. La respuesta ante cambios de punto de consigna es buena y llega a situación estable con facilidad aunque no en la forma que esperamos y por lo tanto no serviría ante restricciones de sobrepasamiento. Aún así mejora la respuesta ligeramente la respuesta del método SIM C.

Respuesta real sintonía Improved SIM C (PI)
Simulación Improved SIM C (PI)

Conclusiones

Desde el punto de vista comparativo de la simulación y la respuesta real del sistema, los métodos de sintonía clásicos son los que han dado mejores resultados siendo el método CC-10 en su versión PI la más equilibrada. En este aspecto el «fracaso» de los métodos modernos tiene que ver con las limitaciones de uno de los componentes (en concreto el ventilador) y con la rapidez de nuestro sistema (nos ha obligado a elegir un Tf muy pequeño), por lo que no se puede tildar de fracaso, simplemente no se pueden implementar correctamente por limitaciones inherentes al sistema. Desde el punto de vista de control se puede decir que todos los métodos probados han tenido una respuesta aceptable y por lo tanto con una dedicación mínima podemos realizar una sintonía robusta de nuestros sistemas para evitar el prueba y error.

Puede que le llame la atención al lector el «poco caso» que se le ha dado al termino derivativo, y es que en el 90% de los casos con un controlador PI es más que suficiente y por lo tanto os recomiendo que antes de usar un PID os hagáis la siguiente pregunta, ¿me aporta alguna mejora incluir el termino derivativo?. En nuestro caso, al incluir el término derivativo la única diferencia ha sido que la salida se ha vuelto más oscilante sin una mejora notable en la respuesta de control. Como norma general no se recomienda el uso del termino derivativo si To es pequeño en comparación con Tp (como es nuestro caso) y suele ser útil si To está en torno a Tp/2.

Ha quedado patente que es factible caracterizar la dinámica de un sistema relativamente sencillo por pocos datos que tengamos. Aún así, lo más importante que me gustaría remarcar es la importancia que tiene conocer bien el sistema que queremos controlar. En este caso y sin ir más lejos, nos enfrentábamos a un control básico de temperatura con una dinámica fácil de caracterizar y aún así la limitación de uno de los componentes nos condiciona la elección del método de sintonía.

Finalmente espero haber arrojado algo de luz sobre la sintonía PID y que os animéis a utilizar ACP para evitar el método prueba y error siempre que sea posible.

Referencias

Enlaces

Libros y Publicaciones

[1] Aidan O’Dwyer. Handbook of PI and PID controller tuning rules, 3rd edition, Imperial College Press. ISBN: 978-1-84816-242-6

[2] Karl J. Astrom, Tore Hagglund. Control PID avanzado, Pearson, ISBN: 978-84-8322-511-0

[3] Daniel Chuck. Los sistemas de primer orden y los controladores PID, edición 2012. [Link] [Link2]

[4] J.G. Ziegler, N.B. Nichols. Optimum Settings For Automatic Controllers, 1942 edition, American Society of Mechanical Engineers. [Link]

[5] G.H. Cohen, G.A. Coon. Theoretical Consideration of Retarded Control, 1953 edition, American Society of Mechanical Engineers. [Link] [Link2]

[6] Daniel E. Rivera. Internal Model Control: A Comprehensive View, 1999 edition, College of Engineering and Applied Sciences. [Link]

[7] R. Vilanova, A. Visioli. PID Control in the Third Millennium. Chapter 5, The SIMC Method for smooth PID Controller Tuning, Springer. ISBN: 978-1-4471-2424-5.

[8] Chriss Grimholt, Sigurd Skogestad. The improved SIMC method for PI controller tuning, IFAC-conference PID’12, Brescia, Italy, March 2012. [Link]

[9] Guillermo J. Silva, Aniruddha Datta, S.P. Bhattacharyya. PID Controllers for Time-Delay Systems. Chapter 10, Analysis of Some PID Tunning Techniques. Birkhäuser. ISBN: 0-8176-4266-8

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

diecisiete + 11 =