Connection of the Heating Block Including PID Control and Menu - ARDUINO !

by InventionsLab in Circuits > Arduino

2250 Views, 2 Favorites, 0 Comments

Connection of the Heating Block Including PID Control and Menu - ARDUINO !

maxresdefault.jpg

Today we will look at how to connect the heating element to the arduino, connect the rotary encoder and also set the PID control. How to Pid regulation? WHAT is PID control? What is PID control used for? How to set parameters Kp, Kd and Ki? How to make a menu in arduino UNO? Everything and more, including graphs where we can plot the course of temperature regulation.

Connection Of The Heating Block Including PID Control And Menu - ARDUINO !

Today we will look at how to connect the heating element to the arduino, connect the rotary encoder and also set the PID control. How to Pid regulation? WHAT is PID control? What is PID control used for? How to set parameters Kp, Kd and Ki? How to make a menu in arduino UNO? Everything and more, including graphs where we can plot the course of temperature regulation.

#include <Wire.h>

#include <LiquidCrystal_I2C.h>

#include <PID_v1.h>




//variables for the temperature sensor

int termPin = 0;      // The analog pin the thermistor is connected to

int termNom = 100000;  // Thermistor reference resistance

int refTep = 25;      // Temperature for reference resistance

int beta = 3950;      // Beta factor

int rezistor = 100000; // resistance value in series

double temp=0.0;

 float voltage;


//button commands only for button and potentiometer

int pin3= 5;  //Pin SW 4

const int pin1 = 2;

const int pin2 = 3;

volatile int statePin1 = 0; // Pin 1 status

volatile int statePin2 = 0; // Pin 2 status

volatile int laststatePin1 = 0;

volatile int laststatePin2 = 0;

volatile unsigned long timePin1 = 0; // Time for pin 1

volatile unsigned long timePin2 = 0; // Time for pin 2

volatile unsigned long lasttimePin1 = 0; // last Time for pin 1

volatile unsigned long lasttimePin2 = 0; // last Time for pin 2

int countererror2;

int countererror1;


//button

unsigned long lastButtonPress = 0;

bool buttonState = HIGH;

bool buttoncheck;

int buttonpressed=0;


// variables for the menu

int menu_activated=0;

int numberofmenu=4;

int checkmenu1=0;

unsigned long previousMillis = 0;  // Variable to store previous time

const long interval = 500;         // Interval for flashing text in menu

unsigned long currentMillismenu;

int checkemptyvalues=0;

unsigned long previousMillis2= 0;


//set to mosfet and temperature

int PWM_pin = 6;  //Digital pin for PWM signal to the MOSFET driver

double set_temperature = 50.00; //The default temperature where you will tune the PID °C

float last_set_temperature = 0;

double PID_value = 0;



float last_kp = 0;

float last_ki = -100;  // -100 remove error for display when value is 0

float last_kd = -100; // -100 remove error for display when value is 0



//PID constants double input, output;

double kp = 90, ki = 1.1,  kd = 1; //set constant


PID pid(&temp, &PID_value, &set_temperature, kp, ki, kd, DIRECT);



LiquidCrystal_I2C lcd(0x27, 16, 2);




void setup() {

  Serial.begin(9600);

  analogReference(EXTERNAL);

  lcd.init();

  lcd.backlight();

  lcd.setCursor(0, 0);

  lcd.display();

   



// BUTTON set pin

  pinMode(pin3, INPUT_PULLUP);

  pinMode(pin1, INPUT);

  pinMode(pin2, INPUT);

  attachInterrupt(digitalPinToInterrupt(pin1), handlePin1Change, CHANGE);

  attachInterrupt(digitalPinToInterrupt(pin2), handlePin2Change, CHANGE);


  // Setting the output mode for PID

  pid.SetMode(AUTOMATIC);


  // Setting the sampling interval (time interval for PID calculation)

  pid.SetSampleTime(50);  // In this case 1000 ms (1 second)


}






void handlePin1Change() {

   

  statePin1 = digitalRead(pin1);

  timePin1 = millis(); // Record the change time on pin 1

 

  //filtering annoying duplicates, both temporal and identical consecutive values, omitting zeros, lets only 1

   if (timePin1 != lasttimePin1 && statePin1 != laststatePin1 ) {

  if ( statePin1 == 1) {

   countererror1++; }


  compareStates();

 

 

 lasttimePin1=timePin1;

 laststatePin1=statePin1;

   

  }

   

 

}


void handlePin2Change() {

 

  statePin2 = digitalRead(pin2);

  timePin2 = millis(); // Record the change time on pin 2

 

 //filtering annoying duplicates, both temporal and identical consecutive values, omitting zeros, lets only 1

  if (timePin2 != lasttimePin2 && statePin2 != laststatePin2 ) {

   

   if ( statePin2 == 1) {  

   countererror2++; }


  compareStates();


   

 lasttimePin2=timePin2;

 laststatePin2=statePin2;

  }


 

}




void compareStates() {


 //checking the last pin, which is always 1 + checking if the pins have changed at least 1x to check the wrong direction

 if (statePin2 == 1 && statePin1 == 1  && countererror1 > 0 && countererror2 > 0 ) {


 


// checking if the button is not pressed, to check if the menu is preserved


 if (buttonpressed == 0   ) {



  //finding which direction it is facing

  if (timePin2 > timePin1 ) {


//restriction to positive values only for menu

    if (menu_activated > 0  ) {


menu_activated--;


}else

{

menu_activated=numberofmenu;

}



countererror1= 0;

countererror2= 0;


}else

  {

    // limitation the number of menus

   if (numberofmenu > menu_activated  ) {  


     menu_activated++;

   }else {

menu_activated = 0;

}

countererror2=0;

countererror1=0;

}





}else {

if ( menu_activated == 1)  {



 if (timePin2 > timePin1 ) {

       set_temperature = set_temperature-0.5 ;

     }

     else {

       set_temperature = set_temperature+0.5;

     }


     countererror1= 0;

countererror2= 0;

}

if ( menu_activated == 2 )  {



 if (timePin2 > timePin1 ) {

       kp = kp-1 ;

     }

     else {

      kp = kp+1 ;

     }


     countererror1= 0;

countererror2= 0;

}


if ( menu_activated == 3 )  {



 if (timePin2 > timePin1 ) {

       ki = ki-1 ;

     }

     else {

      ki = ki+1 ;

     }


     countererror1= 0;

countererror2= 0;

}


if ( menu_activated == 4 )  {



 if (timePin2 > timePin1 ) {

       kd = kd-1 ;

     }

     else {

      kd = kd+1 ;

     }


     countererror1= 0;

countererror2= 0;

}



}

}

 }







//variables to calculate the highest and lowest values

unsigned long previousMillisa = 0;

double lowestdowntemp= set_temperature;

double higesttemp=set_temperature;

double maxhigesttemp=set_temperature;

double minlowestdowntemp= set_temperature;

double maxhigesttemp1=set_temperature;

double minlowestdowntemp1= set_temperature;

double result=0;


void loop() {

   

 


//graph display  - this is for chart information only

  if (millis()- previousMillisa >= 1000) {


  // Find the highest value with a time interval to mitigate noise

if (temp > higesttemp ) {

 //restart values

  lowestdowntemp= set_temperature;

    higesttemp = temp;


      }

     

 if (higesttemp >= temp && temp  > set_temperature ) {


maxhigesttemp=higesttemp;  }


 if ( set_temperature > temp ) {


maxhigesttemp1=maxhigesttemp;

  }



  // Finding the lowest value

  if (lowestdowntemp > temp   ) {

    //restart hodnot

   higesttemp=set_temperature;

    lowestdowntemp = temp;

   

  }


  if (temp >= lowestdowntemp && set_temperature   > temp ) {

 

minlowestdowntemp=lowestdowntemp;


  }


 if ( temp >  set_temperature) {


minlowestdowntemp1=minlowestdowntemp;

  }


result=maxhigesttemp1-minlowestdowntemp1+50;




    previousMillisa = millis();

   Serial.print("PID_value:");

    Serial.print(PID_value);

     Serial.print(",");

      Serial.print("temp:");

  Serial.print(temp);

    Serial.print(",");

Serial.print("ref.temp.:");

       Serial.print(set_temperature);

        Serial.print(",");

         Serial.print("mintemp");

         Serial.print(minlowestdowntemp1);

        Serial.print(",");

          Serial.print("maxtemp:");

       Serial.print(maxhigesttemp1);

       Serial.print(",");

        Serial.print("deviation:");

       Serial.print(result);

      Serial.println("");




}






 //measuring the voltage on the thermistor

  voltage = analogRead(termPin);

 


 // Convert the measured value to the thermistor resistance

  voltage = 1023 / voltage - 1;

  voltage = rezistor / voltage;


 //Calculation of temperature according to the relation for the beta factor

  temp = voltage / termNom;         // (R/Ro)

  temp = log(temp);                 // ln(R/Ro)

  temp /= beta;                     // 1/B * ln(R/Ro)

  temp += 1.0 / (refTep + 273.15); // + (1/To)

  temp = 1.0 / temp;                //The inverted value

  temp -= 273.15;                  // Convert from Kelvin to degrees Celsius



// Calculation of PID control

 pid.Compute();

analogWrite(PWM_pin,PID_value);


delay(50);



//menu 0

 if(menu_activated == 0)

 {


 if (millis()- previousMillis2 >= 500) {

  previousMillis2 = millis();


   lcd.setCursor(0,0);

  lcd.print("ACTUAL TEMP");

  lcd.setCursor(0,1);

  lcd.print("T:");

  lcd.setCursor(2,1);

  lcd.print(temp,1);

  lcd.print("C    ");

 

  lcd.setCursor(9,1);

  lcd.print("S:");

  lcd.setCursor(11,1);

  lcd.print(set_temperature,1);

  lcd.print("C");


  last_set_temperature=0;

  last_kd=-100;


   }

}//end of menu 0 (PID control)







 

  //check button pressed for menu

   buttoncheck = digitalRead(pin3);


  if ((millis() - lastButtonPress) > 50) {

    if (buttoncheck != buttonState) {

      buttonState = buttoncheck;


      if (buttonState == LOW) {


       if (buttonpressed == 0) {

        if (menu_activated != 0) {

        buttonpressed=1;

         }

        }

        else {


          buttonpressed=0;

       

        }


       


       lastButtonPress = millis();

      }

    }

  }

  delay(1);

//end of button press

 



 

//Menu-page 1 (temperature setpoint)

if(menu_activated == 1)

{



if(buttonpressed == 1)

  {

   currentMillismenu = millis();

    if (currentMillismenu - previousMillis >= interval) {

      previousMillis = currentMillismenu;

//menu flashing when pressed, editing activation

     if(checkmenu1 == 0){

       lcd.setCursor(0,1);

        lcd.print("                ");

       

        checkmenu1=1;

        checkemptyvalues=1;

         }else {

         

           lcd.setCursor(0,1);

           lcd.print(set_temperature, 1);

           lcd.print("C");

         checkmenu1=0;

          checkemptyvalues=0;

 

       

  }}

    }else{


// checking for an empty value after pressing the button

if(checkemptyvalues == 1)

  {


lcd.setCursor(0,1);

           lcd.print(set_temperature, 1);

           lcd.print("C");

}}




  if(set_temperature != last_set_temperature)

  {

    lcd.clear();

  lcd.setCursor(0,0);

  lcd.print("Set  temperature:");    

  lcd.setCursor(0,1);

  lcd.print(set_temperature, 1);  

  lcd.print("C");

}

  last_set_temperature = set_temperature;

 



 last_kp=0;

}

//end of menu 1





//Setting P - second menu

if(menu_activated == 2)

{




if(buttonpressed == 1)

  {

   currentMillismenu = millis();

    if (currentMillismenu - previousMillis >= interval) {

      previousMillis = currentMillismenu;

//menu flashing when pressed, editing activation

     if(checkmenu1 == 0){

       lcd.setCursor(0,1);

        lcd.print("P: ");

        lcd.print("                ");

       

        checkmenu1=1;

        checkemptyvalues=1;

         }else {

         

          lcd.setCursor(0,1);

  lcd.print("P: ");

  lcd.print(kp);  

  lcd.print("                 ");

         checkmenu1=0;

          checkemptyvalues=0;

 

       

  }}

    }else{


// checking for an empty value after pressing the button

if(checkemptyvalues == 1)

  {


lcd.setCursor(0,1);

  lcd.print("P: ");

  lcd.print(kp);  

  lcd.print("                 ");

}}




  if(kp != last_kp)

  {

  lcd.clear();

  lcd.setCursor(0,0);

  lcd.print("Set value  ");    

  lcd.setCursor(0,1);

  lcd.print("P: ");

  lcd.print(kp);  

  lcd.print("                 ");

  }

  last_kp = kp;

 


  //it will be possible to display menu 0 again

 last_set_temperature=0;

 last_ki=-100;

}

//end - menu 2





//Setting I - 3 menu

if(menu_activated == 3)

{

 




if(buttonpressed == 1)

  {

   currentMillismenu = millis();

    if (currentMillismenu - previousMillis >= interval) {

      previousMillis = currentMillismenu;

//menu flashing when pressed, editing activation

     if(checkmenu1 == 0){

       lcd.setCursor(0,1);

        lcd.print("I: ");

        lcd.print("                ");

       

        checkmenu1=1;

        checkemptyvalues=1;

         }else {

         

          lcd.setCursor(0,1);

  lcd.print("I: ");

  lcd.print(ki);  

  lcd.print("                 ");

         checkmenu1=0;

          checkemptyvalues=0;

 

       

  }}

    }else{


// checking for an empty value after pressing the button

if(checkemptyvalues == 1)

  {


lcd.setCursor(0,1);

  lcd.print("I: ");

  lcd.print(ki);  

  lcd.print("                 ");

}}


  if(ki != last_ki  )

  {


    lcd.clear();

  lcd.setCursor(0,0);

  lcd.print("Set value  ");    

  lcd.setCursor(0,1);

  lcd.print("I: ");

  lcd.print(ki);  

  lcd.print("                 ");


  }

  last_ki = ki;

 

 last_set_temperature=0;

 last_kp=0;

 last_kd=-100;

}


//end - menu 3





//Setting D - 4 menu

if(menu_activated == 4)

{


  if(buttonpressed == 1)

  {

   currentMillismenu = millis();

    if (currentMillismenu - previousMillis >= interval) {

      previousMillis = currentMillismenu;

//menu flashing when pressed, editing activation

     if(checkmenu1 == 0){

       lcd.setCursor(0,1);

        lcd.print("D: ");

        lcd.print("                ");

       

        checkmenu1=1;

        checkemptyvalues=1;

         }else {

         

          lcd.setCursor(0,1);

  lcd.print("D: ");

  lcd.print(kd);  

  lcd.print("                 ");

         checkmenu1=0;

          checkemptyvalues=0;

 

       

  }}

    }else{


// checking for an empty value after pressing the button

if(checkemptyvalues == 1)

  {


lcd.setCursor(0,1);

  lcd.print("D: ");

  lcd.print(kd);  

  lcd.print("                 ");

}}




  if(kd != last_kd)

  {

    lcd.clear();

  lcd.setCursor(0,0);

  lcd.print("Set value  ");    

  lcd.setCursor(0,1);

  lcd.print("D: ");

  lcd.print(kd);  

  lcd.print("                 ");

  }

  last_kd = kd;


 last_ki=-100;

}


//end menu 4

 





}//Loop end