Maqueta de control PID con Arduino

.


.
.
Con el motivo de la primera VirtualCamp (Julio 2011), el proyecto ha sido crear una maqueta de control didáctica con un presupuesto de menos de 10 euros (Arduino no incluido). La idea fue hacer un proyecto en 48h durante el fin de semana del 16-17 de Julio.
El proceso elegido es el control de temperatura. Para ello dos resistencias de potencia generan el calor y un ventilador actua como control para la refrigeración. Un sensor resistivo de tipo NTC se encarga de registrar la temperatura del habitáculo.
Se ha instalado el sensor de temperatura en medio de las resistencias de potencia para que el proceso disponga de la menor inercia posible, y así se comporte más rápido ante cambios de la entrada.

Los participantes del proyecto:
  • Igor R. -> Creación de la maqueta física, software Arduino y documentación.
  • Alberto Yebra -> Interfaz gráfica en python para la visualización del proceso. [se ampliará este proyecto con su trabajo].
  • LeoBot (Manuel) -> Introducción al control PID y teoría PWM.




Componentes necesarios:
  • Ventilador 12v usado para refrigeración de componentes en ordenadores.
  • Resistencias de potencia (47ohm) --> 2 unidades
  • Un sensor temperatura resistivo (NTC) + resistencia 3k pull up
  • Transistor Mosfet.
  • Diodo 1N4148.
  • Un recipiente (habitáculo). 
  • Transformador externo para alimentación a 12v.

Los objetivos del proyecto usando Arduino han sido:
  1. Creación física de la maqueta.
  2. Control de un proceso usando un PID.
  3. Captura de señal analógica.
  4. Convertir la señal eléctrica a física mediante una tabla guardada en memoria de programa (flash) para evitar uso de RAM del microcontrolador.
  5. Control carga de potencia mediante PWM.
  6. Monitorización en el PC de resultados.

Veámos una foto de como ha quedado la maqueta (se ha usado una dremel para modificar el recipiente de plástico):

Otra foto de la instalación del ventilador:



La instalación eléctrica necesaria es bastante sencilla. La podemos dividir en dos partes: control del ventilador mediante transistor mosfet y adquisición de la temperatura mediante NTC.
A continuación, se puede observar un esquema de la conexión del ventilador. La salida utilizada en Arduino es el pin 9 (PWM).


En los sistemas de control en lazo cerrado la salida del controlador actúa sobre el actuador (en este caso motor eléctrico del ventilador) para corregir la magnitud física (temperatura) que se quiere controlar. 

La técnica más habitual que se utiliza para el control de velocidad de motores de continua, es la modulación por anchura de pulso PWM (Pulse Width Modulation). Esta técnica consiste en una señal periódica cuadrada que cambia el tiempo de su estado activo (nivel alto) en el tiempo del período de la señal.
El tiempo que la señal periódica está activa con respecto a período de la señal se denomina Ciclo de Trabajo (Duty Cycle)
D = (ton/ T) 
Es decir, el duty cycle describe la proporción del tiempo a ON (encendido) sobre un período de tiempo fijo.
Crear este tipo de señal resulta muy sencillo en un microcontrolador, aunque cabe destacar que la corriente generada por el mismo es muy pequeña, por lo que hace necesario de una etapa de adaptación de potencia antes de unirlo al motor. Para ello se utiliza el transistor en conmutación (corte y saturación).  Veámos como sería nuestro circuito conectado a la salida PWM del microcontrolador:

En el circuito, el transistor va a funcionar en corte-saturación, activando y desactivando el motor del ventilador mediante la señal PWM. Como el motor es un dispositivo inductivo (por las bobinas que tiene) se debe instalar un diodo (conocido como diodo de flyback ó freewheeling). Las bobinas se oponen al cambio de corriente, por lo que al "cortar" la alimentación se crea unos picos de voltaje muy altos que pueden dañar nuestra salida del microcontrolador. Gracias a este diodo, la corriente dispone de un camino de descarga.

El control de velocidad del motor se consigue variando la tensión que pasa por el motor y esta tarea la realiza la señal PWM que genera el microcontrolador. Al cambiar el tiempo a ON de la señal PWM (duty cycle), estamos cambiando efectivamente el valor medio (voltaje) sobre nuestro motor, lo que se traslada en un incremento/decremento de la velocidad del ventilador.
Por lo que la salida de control PID es el duty cycle de la señal PWM aplicada al ventilador. Se ha modificado el registro del timer 1, que controla la frecuencia del pin 9, para que la frecuencia sea aproximadamente 32 kHz. La frecuencia de dicha señal, debe ser lo suficientemente rápida para que no afecte la inercia del sistema a controlar.
Veámos una captura real de la señal que sale de nuestro control:

Se observa como el control va modificando adecuadamente el tiempo a ON del PWM para conseguir el SetPoint predefinido.

Para el caso del sensor NTC:

Para evitar resolver operaciones matemáticas en el microcontrolador, se ha creado una tabla de valores obtenidos del conversor ADC del Arduino versus temperatura en grados centígrados. Para ello se ha utilizado la hoja de cálculo LibreOffice Calc. Los datos de entrada son la Ro (resistencia a 25ºC) y el coeficiente beta del sensor [información proveniente del datasheet del fabricante]. Los pasos han sido crear la tabla de resistencia versus temperatura, e ir convirtiendo adecuadamente para obtener una tabla en forma lectura ADC versus temperatura en grados.


Dicha tabla, será guardada en memoria de programa, evitando consumir memoria RAM innecesariamente de nuestro Arduino.
Se observa que la respuesta de un sensor NTC no es lineal.

La NTC se ha situado entre las dos resistencias calentadoras. De esta forma, se consigue que el sistema tenga menos inercia y su respuesta sea rápida.





INTRODUCCIÓN  Por LeoBot (Manuel)

La temperatura es una magnitud física que tanto en el ámbito doméstico e industrial es interesante controlar para tener un un mayor confort y eficiencia energética.
El control se puede realizar tanto manual (control en lazo abierto) como automático (control en lazo cerrado).
El control en lazo abierto es un control de encendido-apagado, en nuestro caso para calentar una habitación, un calentador se enciende o se apaga. En control en lazo cerrado se tiene un controlador que compara la variable (temperatura que se mide con un sensor) con la referencia, temperatura que se quiere tener en la habitación, y convertir el error que resulta en una acción de control para reducir el error.


a) SISTEMA EN LAZO ABIERTO

b) SISTEMA EN LAZO CERRADO

La unidad de control puede reaccionar de diferentes maneras ante la señal de error y proporcionar señales de salida para que actúen los elementos correctores.
Tipos de control
1.- Control de dos posiciones: el controlador es un interruptor activado por la señal de error y proporciona una señal correctora tipo encendido-apagado.

2.- Control proporcional (P): produce una acción de control que es proporcional al error. La señal de correctora aumenta al aumentar la señal de error.

3.- Control derivativo (D): produce una señal de control que es proporcional a la rapidez con la que cambia el error. Ante un cambio rápido de la señal de error, el controlador produce una señal de corrección de gran valor; cuando el cambio es progresivo, sólo se produce una señal pequeña de corrección. El control derivativo se puede considerar un control anticipativo porque al medir la rapidez con que cambia el error se anticipa a la llegada de un error más grande y se aplica la corrección antes que llegue. El control derivativo no se usa solo, siempre va en combinación con el control proporcional y/o con el control integral.

4.- Control integral (I): produce una acción de control que es proporcional a la integral del error en el tiempo. En consecuencia, una señal de error constante producirá una señal correctora creciente y aumentará si el error continua. El control integral se puede considerar que recuerda la situación anterior, suma todos los errores y responde a los cambios que ocurren.

5.- Combinación de tipos de control: proporcional derivativo (PD), proporcional integral (PI) y proporcional integral derivativo (PID).
 



CONTROL PID

El control Proporcional Integral Derivativo (PID) es mecanismo de control mediante realimentación negativa, el cual aplica una acción correctora al sistema para obtener el valor de consigna (Setpoint).

Existe multitud de recursos en internet acerca del mismo, por lo que aquí se verá desde el punto de vista práctico. Por ejemplo, wikipedia dispone de una buena introducción.

El nuestro sistema:
  • Setpoint -> Temperatura de consigna del sistema. Se trata de la temperatura deseada a la cual el proceso tiene que mantenerse a través de la acción del control. El algoritmo oscila entre dos temperaturas, con el motivo de ver como se comporta ante cambios de la entrada. Es decir, es a la temperatura que queremos que se encuentre nuesto recipiente.
  • La realimentación o información de cómo se encuentra el sistema, es adquirida por la NTC. El objetivo es que el valor medido sea siempre igual al valor deseado (Setpoint).
  • El actuador es el ventilador, el cual regulamos su velocidad mediante modulación de ancho de pulsos (PWM).
Para la visualización, se ha utilizado el software gratuito para Windows Stamp Plot Lite (http://www.selmaware.com/stampplotlite/index.htm).

Empezaremos por realizar sólo un control PROPORCIONAL. El programa de Arduino, cambia cada 120 segundos el Set Point entre 60 y 59 grados centígrados.
Se puede observar cómo el control proporcional no elimina el error permanente del sistema.


Existe un límite en el valor de la constante proporcional, ya que nuestro sistema se vuelve oscilatorio, ya que un pequeño cambio en el error, hace que la salida de controlador sea muy grande. A continuación un ejemplo:


Como se ha observado, la parte proporcional no tiene en cuenta el tiempo, por lo que para corregir el error permanente, necesitamos añadirle la parte INTEGRAL.
Para poder observar cómo se comporta, se ha introducido un retraso a la actuación de la misma.


La parte integral consigue que nuestro sistema alcance los valores objetivo (Set Points de 60 y 58 grados), ya que corrige el error permanente del sistema.

La parte DERIVATIVA,sólo actua si hay un cambio en el valor absoluto del error. Es decir, si el error es constante, no actuará.

El objetivo final de un sistema de control, es que el sistema siga lo más fielmente a su entrada ante perturbaciones externas y que responda ante cambios de consigna (SetPoint). Veámos un video, en el cual se altera el sistema (tapando la salida de aire-cables) y como al subir la temperatura, el sistema aumenta la velocidad del ventilador para tratar de contrarrestar la perturbación.




DESCARGA EL SKETCH DE ARDUINO AQUÍ




O puedes ojear el código a continuación:



.

56 comentarios:

  1. Enhorabuena, increíble trabajo !!! Gracias por compartirlo.

    ResponderEliminar
  2. Felicitaciones... una explicacion de algo tecnico pensado nativamente en español y redactado en español; NO una traduccion.
    De nuevo ... muy bien

    ResponderEliminar
  3. muy bueno!!... estoy trabajando en algo muy similar, podrian ayudarme y poner el Diagrama completo de conexiones, con arduino y todo?
    porfavor

    Gracias

    ResponderEliminar
  4. me encanta genial pefecto wau

    ResponderEliminar
  5. buenas, faltaria un archivo para cargar en el StampPlotSoftware ?

    ResponderEliminar
  6. cuando tu conectas el mosfet no se te calienta??

    ResponderEliminar
    Respuestas
    1. No porque controla el ventilador, que tiene un consumo mínimo. Podría usarse uno mucho más pequeño, pero usé el primero que encontré por casa.

      Eliminar
  7. Saludos...

    Impresionante trabajo, actualmente estaba pensando en hacer lo mismo pero empleando un conversor analogico digital maxim 3*** y un level shifter. Basicamente el proyecto incluiria el encendido y apagado de una bombilla mediante rele y la lectura de la temperatura. Luego para complicarlo habia pensado incluirle una rampa de subida durante un tiempo, estar otro tanto a la temperatur de trabajo y una rampa de bajada o enfriamiento gradual. No se si esto es viable, agradeceria vuestros consejos.
    Iñigo

    ResponderEliminar
    Respuestas
    1. Yo creo que tendrias que usar un triac para el control de la bombilla, en vez de un rele.

      Eliminar
  8. Buenas...

    En principio se trataria de ver si funciona y la forma mas secilla ya que tengo un control por rele es esta, mas adelante veria la posibilidad de accionar con triacs.

    Lo que me cuesta mas es temporizar ( tres pasos) y logicamente tres rangos de temperatura, precalentamiento, cocido y enfriamiento he visto ejemplos en los que por un lado se puede temporizar y otros controlar la temperatura accionando o no el dispositivo adecuado, una mezcla de los dos no lo veo.

    Iñigo

    Iñigo

    ResponderEliminar
  9. Buenas

    Consulta, cual es el pin al que estamos conectando el sensor a arduino ???

    ResponderEliminar
  10. Excelente proyecto Igor, una consulta, en la linea 136, el error no deberia ser el setpoint menos la temperatura actual, y en la linea 147, el valor de Integral no deberia ser la suma de Integral mas Ki dividido el error actual....
    Una ultima consulta, existe algun otro metodo de implementar la funcion calcTemp, si puedo realizar un calculo con matlab u otra herramienta y luego pasar al Arduino, o realizar algun tipo de interpolación????

    ResponderEliminar
    Respuestas
    1. Hola,

      Tendría que haberle puesto por ahí en comentarios, pero está cambiado el signo de la operación por cómo es el sistema. Necesito invertir la salida del PID para controlar el PWM porque si no, a mayor error=Setpoint-Tactual, necesito que tenga menos PWM (el ventilador funciona menos), para que así la temperatura actual suba y se acerque al Setpoint.

      Podrías hacer lo que comentas con Matlab o el soft que quieras. Yo he hecho una interpolación usando una "lookup table", pero puedes hacer lo que quieras.

      Saludos


      Igor

      Eliminar
  11. Excelente trabajo Felicidadeees!!!! ...Apoyo total al Software Libre!!!

    ResponderEliminar
  12. Como es que la señal pid es decir la suma de la parte proporcional, integral y derivativa se adapta al valor de pwm necesario??

    ResponderEliminar
    Respuestas
    1. La salida del PID es el PWM que controla el ventilador

      Eliminar
  13. Muy buen trabajo, pero tengo una duda...
    1-las "resistencias de potencia" son diferentes a las resistencias comunes?
    2-como alimentaste estas resistencias?

    ResponderEliminar
  14. Primero que todo un muy buen trabajo.
    Las constantes Kp, Ki, y Kd como se calculan.....Me podrian comentar

    ResponderEliminar
  15. Como es la conexion en la parte de la resistencias.....Nos prodias colaborar con el circuito
    ene el que este NTC las 2 resistencias de potencias y la resistencia que va con el sensor y como es la alimetacion gracias

    ResponderEliminar
  16. Me podrias decir como calculas las constantes Kp, Ki, Kd. Muchas gracias y excelente trabajo!

    ResponderEliminar
  17. Excelente!! estoy trabajando en algo parecido, y me funciona perfectamente, pero quisiera saber como hacer que el stamp plot pro que me he descargado se inicie automáticamente con una ventana como la que se puede ver en tu post. A mi me toca inicializarlo todo manualmente y como en el código la función config_StampPlot() se encarga de configurarlo quisiera saber porque no me funciona...
    Muchas grácias y enhorabuena!

    ResponderEliminar
  18. Maestro, gracias por publicar tanto sobre Arduino, PWM, PID...

    :)

    ResponderEliminar
  19. Una explicación muy técnica y a la vez sencilla de entender así que gracias por compartirlo. Igor, estoy metido en un proyecto, concretamente un cuadcopter, lo tengo casi terminado sin embargo en el control PID, aunque ahora lo entiendo, aún no soy capaz de integrarlo en mi código o al menos no del todo. Agradecería si pudieras echarme una mano. Mi correo es emarpe2@gmail.com si alguien del grupo puede hacerlo yo encantado. Gracias por adelantado.

    ResponderEliminar
  20. Amigo, disculpa, como es el circuito de las resistencias calentadoras.
    Enhorabuena, muchas gracias, saludos

    ResponderEliminar
  21. Por favor necesitamos el circuito de las resistencias calentadoras.. gracias

    ResponderEliminar
    Respuestas
    1. Las resistencias estan conectadas todo el tiempo (Vcc y Gnd).

      Saludos,

      Eliminar
  22. en hora buena tio.. que paso con el circuito de las resistencias calefactoras

    ResponderEliminar
  23. cuando quiero cargar el programa me dice: "Desde Arduino 1.0, la palabra clave 'BYTE' ya no está soportada en
    Serial.print(var, BYTE). Por favor utiliza Serial.write() en su lugar." que puedo hacer con eso???

    ResponderEliminar
  24. yop tengo el mismo problema que Braulio que puedo hacer

    ResponderEliminar
  25. Aqui la solucion http://arduino.cc/es/Serial/Write

    ResponderEliminar
  26. muy buenas noches. disculpa me podrias decir exactamente que NTC utilizaste..muchas gracias y buenas noches

    ResponderEliminar
  27. Chapeau! Mi hijo de 12 años queria empezar a jugar con un Arduino. Utilizare esta información como base de trabajo para introducirlo. BBBBB, Bueno, Bonito, Barato, Bien explicado y Bien documentado!

    ResponderEliminar
  28. Hola!! Muy buen trabajo, estoy haciendo un proyecto similar con las resistencias y el NTC y me gustaría poder basar esa parte en lo que tu hiciste. Tendrás el diagrama de conexiones del conjunto de las resitencias y NTC y arduino? Me ayudarías mucho. Gracias

    ResponderEliminar
  29. ola buen proyecto tendrías el diagrama de conexión de las resistencias y el sensor gracias

    ResponderEliminar
  30. Como se calculan las constantes del PID?

    ResponderEliminar
  31. Buen proyecto, puede que lo copie JEJE!!

    ResponderEliminar
  32. Que tipo de mosfet utilizas?? Gracias. Un saludo

    ResponderEliminar
  33. Alguin me puede ayudar con el diagrama de conexiones de manera urgente. gracias jchp16@gmail.com

    ResponderEliminar
  34. diculpen ...este codigo se puede meter a matlab?

    ResponderEliminar
  35. que tal, me parece muy bien!! pero me da un error al cargar en el arduino, me dice que algo esta mal en la linea 45 en la parte que dice prog_uint16_t espero me puedan ayudar, uso arduino mega 2560, gracias

    ResponderEliminar
    Respuestas
    1. a Mi tambien alguien sabe la solucion a eso muchas Gracias

      Eliminar
  36. Saludos.
    Estoy intentando realizar un trabajo similar, pero no se muy bien por donde comenzar a modelar la planta (las resistencias y el ventilador). En su caso ¿cómo obtuvieron las ganancias (Kp, Kd, Ki)? La parte de las resistencias de potencia tiene algun diagrama y a que voltaje van conectadas? El mosfet es alguno en particular o cualquiera sirve?
    Gracias de antemano.

    ResponderEliminar
  37. Saludos, Primero los felicito por su buen trabajo. Por otro lado, me gutaria saber como calculan de la derivada y la integral del error en el arduino, ya que en su codigo solo veo que tienen una multiplicacion en la parte integral y derivativa. Siendo que en un control PID se calcula la derivada del error y la integral del error. Espero me puedas responder mi duda y agradezco su tiempo

    ResponderEliminar
  38. Disculpa al compilarlo en mi arduino me manda un error diciendo
    Arduino: 1.6.5 (Windows 8.1), Board: "Arduino/Genuino Uno"

    PID_2:45: error: 'prog_uint16_t' does not name a type
    PID_2.ino: In function 'void loop()':
    PID_2:175: error: The 'BYTE' keyword is no longer supported.
    As of Arduino 1.0, the 'BYTE' keyword is no longer supported.
    Please use Serial.write() instead.

    In file included from PID_2.ino:7:0:
    PID_2.ino: In function 'float calcTemp(uint16_t)':
    PID_2:204: error: 'ntc' was not declared in this scope
    PID_2:206: error: 'ntc' was not declared in this scope
    PID_2:210: error: 'ntc' was not declared in this scope
    PID_2:212: error: 'ntc' was not declared in this scope
    PID_2:216: error: 'ntc' was not declared in this scope
    PID_2:222: error: 'ntc' was not declared in this scope
    PID_2:223: error: 'ntc' was not declared in this scope
    PID_2:224: error: 'ntc' was not declared in this scope
    PID_2.ino: In function 'void config_StampPlot()':
    PID_2:246: error: The 'BYTE' keyword is no longer supported.
    As of Arduino 1.0, the 'BYTE' keyword is no longer supported.
    Please use Serial.write() instead.

    'prog_uint16_t' does not name a type

    ResponderEliminar
  39. La solución es muy sencilla amig@s, basta con ver el mensaje de error. Indica claramente "Como en Arduino 1.0, la palabra clave 'BYTE' no se soportará más.Por favor, usa Serial.write() en su lugar".

    Recuerden que serial write deberá tener asignado un valor numérico dentro del paréntesis.

    La otra es que tampoco cuenten con la librería indicada, por lo cual no se podrá realizar la ejecución correcta de la compilación.

    La librería está disponible para su descarga:

    https://github.com/mikalhart/galileo-Pgmspace.h

    Lo que deben realizar es copiarla dentro de: \hardware\arduino\libraries\avr\pgmspace.h

    Y también dentro de: \arduino\libraries\avr\pgmspace.h

    La carpeta "avr" la deben crear ustedes mismos.


    Por último, el mensaje "'prog_uint16_t' does not name a type" lo solucionan al reemplazar la parte de esa línea así "const uint16_t" y la magia empezará a hacer la fantasía realidad.

    Espero que les sirva mi solución.

    ResponderEliminar
  40. Muy buen trabajo

    Tengo una duda, como calculaste las ganancias kp, ki. y kd, las calculaste experimentalmente, o utilizaste algún método matemático?

    ResponderEliminar
  41. Hola, tengo una duda respecto al transistor mosfet, no se si pueda ser sustituido por otro componente o que tipo de mosfet fue el que usaste. Me apoyarías con el diagrama del circuito para poder entenderlo mejor? Te agradezco la atención luz.gabriela.orozco.guerra@gmail.com

    ResponderEliminar
  42. Usted señor es un genio muy buen aporte mil gracias.

    ResponderEliminar
  43. Que regla de sintonización es utilizada?

    ResponderEliminar
  44. Disculpa en el programa para graficar, cual opción de graficar es la que debo usar?

    ResponderEliminar
  45. hola gracias por el excelente trabajo. Una duda, quiero incorporar este control a una incubadora casera, el ventilador no lo colocaría, sólo unas resistencias calefactoras,la alimentación de las resistencias para calentar y mantener la temperatura ha de ser a 230 en alterna, a máxima potencia quiero que disipen unos 80 Watios, no se muy bien que poner, o que problemas puedo tener al trabajar con alterna, por todo lo que leo entiendo que un triac de potencia sería la opción a usar, ¿me podéis aconsejar?

    ResponderEliminar