lunes, 16 de septiembre de 2013

CONTROL PID CON LM35 PARA ARDUINO

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

2 comentarios:

  1. Muy interesante. Porque exitas el mosfet con 2 bipolares?

    ResponderEliminar
  2. BUSQUEN EN GOOGLE "SISTEMAS TERMICOS Y MAS!!!",DE AHI LO SACO :V

    ResponderEliminar