domingo, 4 de marzo de 2012

CONTROL PID CON LM35 PARA ARDUINO:
ELEMENTO A CONTROLAR: CELDA PELTIER

En nuestras anteriores entradas, hemos aprendido como tomar datos de temperatura y hacer un control ON-OFF, aunque este último no debe usarse debido a su gran rango variable de estabilidad, por esta razón decidimos hacer un control mas continuo utilizando la señal PWM de la ARDUNIO la cual nos controlará la potencia suministrada de la fuente.
Para lograr este control, debemos utilizar un amplificador de señal que será incluido en la conexiones respectivas.
El programa que utilizaremos para graficar los datos se llama STAMPPLOTO PRO V3.9, aqui dejo el link para que lo puedan descargar:

http://www.parallax.com/tabid/441/Default.aspx

Aqui tambien está el manual del STAMPPLOT:

http://www.selmaware.com/downloads/StampPlot_v39_primer.pdf


Materiales:

  • 2 transistores NPN 2n222
  • 1 Mosfet IRFZ44N
  • 1 Resistencia de 100 Ω
  • 1 Resistencia de 100 KΩ
  • 2 Resistencia de 220 KΩ

Transistor NPN 2n222:

Mosfet IRFZ44M:

Conexiones:

Código:

///////////CONTROL PID//////////////////////

//Variables del Smooting
const int numReadings = 20;
int readings[numReadings];     
int index = 0;                  
int total = 0;                 
float Tprom = 0;               

float chaloTEM= A2; //Puerto analogico de lectura del sensor

float TempR; // Temperatura actual leída
int setpoint = 17 ; // Temperatura deseada "set point"
float error_actual = 0; // Variables de ERROR
float error_anterior = 0;
float t_muestreo = 1000; //Tiempo de muestreo [ms]

//=====Constantes del control PID ================
float Kpe = 40; // Constante Proporcional
float Kie = 0.00005; //Constante de Sumatoria
float Kde = 0.7; //Constante Derivativa del Sistema
float PID = 0; //Señal
//Recordar que las constantes deben ser halladas previamente según el comportamiento del sistema en lazo abierto

//=====Variables de cálculo=====================
float prop = 0;
float inte = 0;
float deri = 0;
float acum = 0;
float area = 0;
float Ts = 0;//Tiempo de Muestreo


void setup()
{
Serial.begin(9600);
   pinMode(7, OUTPUT); // salida de la señal PWM
  for (int thisReading = 0; thisReading < numReadings; thisReading++)
    readings[thisReading] = 0; //For para cantidad de datos promedios del smooting      
}
void loop()
{
//Operaciòn del smooting
  total= total - readings[index];        
  // lectura del sensor
  readings[index] = analogRead(chaloTEM);
  // suma la lectura al total:
  total= total + readings[index];      
  // avance a la siguiente posiciòn en el conteo
  index = index + 1;                   

  // si estamos al final del conteo...
  if (index >= numReadings)             
    // ...vuelva al principio
    index = 0;                          
        
Tprom= ( 5.0 * total * 100.0) / (1023.0 * numReadings);//se pasa de voltaje a temperature y se divide en el numero de lecturas que se quiere promediar
if (setpoint <= Tprom) //=======CELDA ON
 {
   //Serial.print(" Celda ON ");
   //Tiempo de muestreo en segundos:
   Ts = t_muestreo/1000;
   // Tomo la lectura del sensor
   TempR = Tprom; // Consigno el valor leido en esta variable 
   // Conversión lineal de la señal de entrada a temperatura en grados centígrados :
   error_actual = Tprom - setpoint ; //cálculo de error = Tdeseada -Tactual
   //error -> proporcional
   prop = error_actual*Kpe; // Error Proporcional=Kp*errror
   //error -> integral
   area = error_actual+error_anterior; // error sumatoria
   area = area*Ts;
   area = area*0.5;
   acum = acum+area;

   inte = acum*Kie;
   inte = constrain(inte, -110, 110); //filtro anti-windup, para evitar saturación del actuador
   //error -> derivada
   deri = error_actual-error_anterior;
   deri = deri*Kde;
   //PID-->>
   PID = prop + inte + deri;
   PID = constrain(PID, 0, 255); //restricción de la acción de control a rangos admisibles de PWM.
  //Almacenamiento del error actual
  error_anterior = error_actual;
  if(error_actual<1)
  {

  PID = PID;
  //condición primaria
  }
 
  digitalWrite(7,PID);
  //imprimo los valores deseados
  Serial.print(Tprom);
  Serial.print(",");
  Serial.println(PID);
  Serial.print(" ERROR (+) = ");
  Serial.println(error_actual);
  Serial.println(" ");
 }
 else //==CELDA APAGADA
 {
  //Serial.print(" Celda OFF ");
 
  PID = PID ;
  digitalWrite(7,PID);
  Serial.print(Tprom);
  Serial.print(",");
  //Serial.print(" PID = ");
  Serial.println(PID);
  Serial.print(" ERROR (-) = ");
  Serial.println(error_actual);
  Serial.println(" ");
  }
  delay(t_muestreo);

}

Recordar: El smooting en un programa ejemplo del arduino que nos enseña como promediar los datos tomados por el sensor análogamente. Si este no se aplica, los datos del sensor serán muy retirados (28.5 , 29.8 , 27.5 , ect) mientras que con el los datos serán mas cercanos (28.5 , 28.7 , 28.9 , ect).

Gráfica deseada:

Gráfica Obtenida:





Espero haya sido de su agrado el trabajo hecho :D










27 comentarios:

  1. Se me olvido mencionar que la celda peltier por si sola no se estabiliza asi que para que ocurra la estabilizacion se necesita colocar una carga, en nuestro caso tomamos de ayuda un ventilador cerca a las peltier.

    ResponderEliminar
  2. Hola amigo esta muy interesante el proyecto, tengo una duda con que podria sustituir la celda peltier???

    ResponderEliminar
  3. Hola Isaac.
    Puedes sustituirlo por cualquier tipo de dispositivo que se maneje con 24v ( o con una fuente de este tipo).

    ResponderEliminar
  4. Hola, una pregunta, como le hago para encontrar las constantes de lazo abierto? te agradeceria mucho la ayuda!

    ResponderEliminar
  5. Hola, una pregunta, soy nuevo en el uso de las peltier, y no entiendo a qué te refieres con la carga (ventilador), ¿por qué es necesario?

    ¿a que te refieres con estabilizar la peltier?

    ¿el ventilador ayuda a enfriar la superficie caliente?, o ¿ayuda distribuir el calor?

    Gracias!

    Atte Saúl

    ResponderEliminar
  6. Hola fexrubio.
    Se puede resolver de dos formas:

    1). Ajuste manual

    Si el sistema debe mantenerse online, un método de ajuste consiste en establecer primero los valores de I y D a cero. A continuación, incremente P hasta que la salida del lazo oscile. Luego establezca P a aproximadamente la mitad del valor configurado previamente. Después incremente I hasta que el proceso se ajuste en el tiempo requerido (aunque subir mucho I puede causar inestabilidad). Finalmente, incremente D, si se necesita, hasta que el lazo sea lo suficientemente rápido para alcanzar su referencia tras una variación brusca de la carga.

    2). Ajuste por ecuaciones:

    P = Kp*e(t) I = Ki* integral(e(t)dt) D = Kd*de/dt

    Yo lo realizé por el método manual, me parecio mas facil a prueba y error y solo demore unas dos horas cuadrandolo.

    ojala te sirva

    ResponderEliminar
  7. Hola saul.

    Cuando realize el experimento sin el ventilador llegaba un punto donde la estabilizacion disminuia el voltaje hasta cero (0) reduciendo todo a un controlador on-off, esto sucedia a que la peltier sola no era capaz de "estabilizar" o no dejar caer a cero el voltaje que suministraba el controlador por esta razon habia que añadirle una "carga" o ventilador para que el enfriamiento se pudiera manejar y no disminuyera el voltaje a cero.

    Simplemente el ventilador ayuda a enfriar por decirlo asi :).

    ojala te sirva.

    ResponderEliminar
  8. Hola, muy buen proyecto amigo, crees poder ayudarme con la elaboración de un control de temperatura con PID y arduino??

    ResponderEliminar
  9. Hola francisco soy chalom ( es que no me acuerdo de mi cuenta)
    Con mucho gusto, dígame en que podría ayudar....

    ResponderEliminar
  10. Buena ayuda y buen ejemplo, cada vez me voy enterando más sobre el control PID. Me gustaría saber si alguno de vosotros puede echarme un capote, estoy haciendo un cuadcopter y aunque voy bastante avanzado aún no le añadido el control PID al código por tener muchas dudas sobre ello aún. Podrías ayudarme?
    Gracias por adelantado. Mi correo es emarpe2@gmail.com

    ResponderEliminar
  11. Hola! creo que ya es muy viejo el blog a ver si me respondes, como es tu sistema?
    porque se necesita saber esto para sacar KP KI Y KD no ?

    ResponderEliminar
  12. Porque dice que la salida es el pin 3 y en el codigo dice que la 7

    ResponderEliminar
  13. Porque dice que la salida es el pin 3 y en el codigo dice que la 7

    ResponderEliminar
  14. Porque dice que la salida es el pin 3 y en el codigo dice que la 7

    ResponderEliminar
  15. Este comentario ha sido eliminado por el autor.

    ResponderEliminar
  16. Que tipo de asignacion es PID=PID??? No tiene sentido!!

    ResponderEliminar
  17. hola que tal una pregunta como determinaste las constantes kpe kie kde

    ResponderEliminar
  18. esta muy bueno el apunte, la carga de la celda peltier supongo que te referis a carga termica, tambien se puede realizar por medio de una masa termica como cobre o aluminio para tener inercia termica

    ResponderEliminar
  19. puedo cambiar la celda de peltier por una hornilla electrica?

    ResponderEliminar
  20. En lugar de la celda peltier puedo usar una lampara incandecente de corriente directa? (foco de carro)

    ResponderEliminar
  21. Hola!! en vez usar una celda peltier, necesito accionar una resistencia de calor a una tensión de control a 5V.¿ Que necesito modificar en el circuito?

    ResponderEliminar
  22. debo hacer algo similar a este proyecto. ¿podrias compartirlo completo porfavor? mi correo es dea23rengo@gmail.com

    ResponderEliminar
  23. hola, muy buena explicacion, una pregunta donde conectaria el ventilador?

    ResponderEliminar
  24. tienes otro error en tu codigo ya que muchos tuvieron problema
    fue en esta parte del codigo........

    error_actual = Tprom - setpoint ; //cálculo de error = Tdeseada -Tactual ........

    ya que se resta la temperatura deseada que seria el punto fijo - la temperatura actual a la cual es la temperatura promedio

    y esa parte del codigo deberia de quedar asi..........

    error_actual = setpoint - Tprom ; //cálculo de error = Tdeseada -Tactual

    tal vez no afecte mucho pero es un pequeño error que hace la diferencia en el PID

    ResponderEliminar
  25. hola amigo una consulta se puede cambiar el LM35 por un serson ds18b20 usando el mismo programa

    ResponderEliminar