Temperature Control of Peltier Element #9

PID Control Loop

This is the final stage of project where we implement a PID control loop logic, and also sum up the other parts together.

The important part of the control loop was finding out the suitable constants Kp,Kd and Ki required for PID action. We discovered that our project setup required separate constants for Cooling and Heating. So depending on the room temperature calculated initially and the set temperature set by user, the system uses two different set of constants.

After a lot of experimenting (about 3 to 4 days with many different values) we obtained the values,

Constants Heating Cooling
Kp  50  30
Kd  50  12
Ki  0.001  1

With these values we were able to reach the set point with tolerance of  ± 1° C .

The final code of the project:

dht DHT;
#define DHT11_PIN 7

const int rs = 12, en = 8, d4 = 5, d5 = 4, d6 = 13, d7 = 2;

LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
int temp=0;
int temp1=0;
float potchange=0;
int sensorPin=A0;
int tempPin = A4;
int val=0;

int kp=0,kd=0,ki=0;

int temperature_read=0;
int set_temperature=0;

int PID_error=0;

float previous_error = 0;
float PID_p=0,PID_d=0,PID_i=0,PID_value=0;
float elapsedTime, Time, timePrev;

int RoomTemp=0;

void setup() 
{
            Time = millis(); 
            // Timer Setup for High Frequency PWM
           pinMode(10,OUTPUT);
           pinMode(9,OUTPUT);
           pinMode(3, OUTPUT);
           TCCR2A = _BV(COM2A1) | _BV(COM2B1) | _BV(WGM20);  
            TCCR2B = _BV(CS20);
    
            OCR2B = 0;
            
            Serial.begin(9600);
            int chk = DHT.read11(DHT11_PIN);
            for(int i=0; i<=100; i++)
            {
              lcd.begin(16, 2);
              lcd.setCursor(2, 0);
              lcd.print("Initial Setup");
              lcd.setCursor(5, 1);
              lcd.print(i);
              RoomTemp=(int)DHT.temperature;
              lcd.setCursor(9, 1);
              lcd.print(RoomTemp);
              //delay(1200);
              delay(100);
            }

}

void loop() 
{ 
  // LCD Setup
  lcd.clear();
  lcd.begin(16, 2);
  lcd.print("Set Temp: ");
  lcd.setCursor(10, 0);
  
  // DHT11 Reading
  int chk = DHT.read11(DHT11_PIN);  
 
  // LM 35 Reading 
  val = analogRead(tempPin);
  float mv = ( val/1024.0)*5000; 
  float cel = mv/10;

  temp=analogRead(sensorPin);
  
  potchange=temp;
  temp1=15+(temp/1023.0)*41.0;

  // LCD Printing
  
  lcd.print(temp1);
  lcd.setCursor(13, 0);
  lcd.print("C"); 
  lcd.setCursor(0,1);
  lcd.print("Actual Temp:");
  lcd.print((int)DHT.temperature);
  //lcd.print(cel);
  lcd.setCursor(15,1);
  lcd.print("C");

  Serial.println((int)DHT.temperature);  
  Serial.println(temp1);

  set_temperature=temp1;
  temperature_read= DHT.temperature;

  // ----------------------------- HEATING ----------------------------------------------------------
  if(set_temperature>=RoomTemp)
  {
        digitalWrite(9,HIGH);
        digitalWrite(10,HIGH);
        lcd.setCursor(15, 0);
        lcd.print("H");
        kp=50;
        kd=400;
        ki=0.05;
        
        
        PID_error = -(temperature_read - set_temperature)+1 ;
       
        PID_p = kp * PID_error;
       
        PID_i = (PID_i + (ki * PID_error));
        
        timePrev = Time;                            
        Time = millis();                            
        elapsedTime = (Time - timePrev) / 1000; 
        PID_d = kd*((PID_error - previous_error)/elapsedTime);
      
        PID_value = PID_p + PID_d + PID_i ;
      
         if(PID_value < 0 || PID_error<0 || PID_p < 0)
          {    PID_value = 0;
              //|| PID_p < 0 || PID_error<0               // Serial.println("Flag");             }         if(PID_value > 255)  
          {    PID_value = 255;  }
        
        OCR2B=PID_value;
        previous_error = PID_error; 
  }


// ----------------------------- COOLING ----------------------------------------------------------
  else if(set_temperature<RoomTemp)
  {
        digitalWrite(9,LOW);
        digitalWrite(10,LOW);
        lcd.setCursor(15, 0);
        lcd.print("C");
        kp=20;
        kd=12;
        ki=1;
        
        
        PID_error = (temperature_read - set_temperature) ;
        
        PID_p = kp * PID_error;
       
        PID_i = (PID_i + (ki * PID_error));
        
        timePrev = Time;                            
        Time = millis();                            
        elapsedTime = (Time - timePrev) / 1000; 
        PID_d = kd*((PID_error - previous_error)/elapsedTime);
      
        PID_value = PID_p + PID_d + PID_i ;
      
         if(PID_value < 0 || PID_error<0 )
          {    PID_value = 0;}         
          if(PID_value > 255)  
          {    PID_value = 255;  }
        
        OCR2B=PID_value;
        previous_error = PID_error; 
  }

delay(1500);

}

Click here to view and download the entire code.

 

0

Leave a Reply