iTCLab : Internet-Based TCLab - PID, AI, and IoT-based Temperature Control Lab Kit. Suitable for researchers, Lecturers, Students, Teachers, and Electronics-Informatics Vocational School Students. This kit can be used for Learning: IoT, System Dynamics, Control, AI, Arduino and Python Programming, etc.

Riset PID dengan Arduino

Administrator | 20 April 2022

Riset PID dengan Arduino


Riset iTCLab : Pemrograman PID dengan Arduino Menggunakan Kit iTCLab



Pengaturan File - Preferences:

Kit iTCLab menggunakan Mikrokontroller ESP32. Silahkan di-copy dan di-paste, di FIle - Preferences, alamat berikut ini:

https://dl.espressif.com/dl/package_esp32_index.json



Pengaturan Board.

Kit iTCLab menggunakan Mikrokontroller ESP32. Jika belum muncul. Untuk menggunakan pertama kali , silahkan diinstall ESP32 di Board Manager.



Pilihan Board.

Selanjutnya, silahkan dipilih Board: DOIT ESP32 DEVKIT V1.



Program PID dengan Arduino Menggunakan Kit iTCLab

Berikut ini pemrograman PID dengan Arduino Menggunakan Kit iTCLab.

/****************************************************
 * Program : Kendali Suhu dengan PID Program Arduino
 *           Menggunakan Kit iTCLab
 * Oleh    : Tim io-t.net
 * Surabaya, 20 April 2022
 ****************************************************/

#include <Arduino.h>

// constants
const int baud = 115200;       // serial baud rate

// pin numbers corresponding to signals on the iTCLab Shield
const int pinT1   = 34;         // T1
const int pinT2   = 35;         // T2
const int pinQ1   = 32;         // Q1
const int pinQ2   = 33;         // Q2
const int pinLED  = 26;         // LED

// setting PWM properties
const int freq = 5000; //5000
const int ledChannel = 0;
const int Q1Channel = 1;
const int Q2Channel = 2;
const int resolutionLedChannel = 8; //Resolution 8, 10, 12, 15
const int resolutionQ1Channel = 8; //Resolution 8, 10, 12, 15
const int resolutionQ2Channel = 8; //Resolution 8, 10, 12, 15

float cel, cel1, degC, degC1;
float P, I, D, Kc, tauI, tauD;
float KP, KI, KD, op0, ophi, oplo, error, dpv;
float sp = 35, //set point
pv = 0,        //current temperature
pv_last = 0,   //prior temperature
ierr = 0,      //integral error
dt = 0,        //time between measurements
op = 0;        //PID controller output
unsigned long ts = 0, new_ts = 0; //timestamp
const float batas_suhu_atas = 58;

// global variables
float Q1 = 0;                 // value written to Q1 pin
float Q2 = 0;                 // value written to Q2 pin
int iwrite_value = 25;        // integer value for writing
int iwrite_led = 255;         // integer value for writing
int iwrite_min = 0;           // integer value for writing

void setup() {
  // put your setup code here, to run once:

  ts = millis();
  
  Serial.begin(baud); 
  while (!Serial) {
    ; // wait for serial port to connect.
  }

  // configure pinQ1 PWM functionalitites
  ledcSetup(Q1Channel, freq, resolutionQ1Channel);
  
  // attach the channel to the pinQ1 to be controlled
  ledcAttachPin(pinQ1, Q1Channel); 

  // configure pinQ2 PWM functionalitites
  ledcSetup(Q2Channel, freq, resolutionQ2Channel);
  
  // attach the channel to the pinQ2 to be controlled
  ledcAttachPin(pinQ2, Q2Channel);   

  // configure pinLED PWM functionalitites
  ledcSetup(ledChannel, freq, resolutionLedChannel);
  
  // attach the channel to the pinLED to be controlled
  ledcAttachPin(pinLED, ledChannel); 

  ledcWrite(Q1Channel,0);
  ledcWrite(Q2Channel,0); 
  ledcWrite(ledChannel,0); 
}

void Q1on(){
    ledcWrite(Q1Channel,iwrite_value);
    //Serial.println(Q1);
}

void Q1off(){
    ledcWrite(Q1Channel,iwrite_min);
    //Serial.println(Q1);
}

void Q2on(){
    ledcWrite(Q2Channel,iwrite_value);
    //Serial.println(Q2);
}

void Q2off(){
    ledcWrite(Q2Channel,iwrite_min);
    //Serial.println(Q2);
}

void ledon(){
    ledcWrite(ledChannel,iwrite_led);
}

void ledoff(){
    ledcWrite(ledChannel,iwrite_min);
}

void cektemp(){
  degC = analogRead(pinT1) * 0.322265625 ;    // use for 3.3v AREF
  cel = degC/10;
  degC1 = analogRead(pinT2) * 0.322265625 ;    // use for 3.3v AREF
  cel1 = degC1/10;

  Serial.print("Temperature T1: ");
  Serial.print(cel);   // print the temperature T1 in Celsius
  Serial.print("°C");
  Serial.print("  ~  "); // separator between Celsius and Fahrenheit
  Serial.print("Temperature T2: ");
  Serial.print(cel1);   // print the temperature T2 in Celsius
  Serial.println("°C");
}

// PID Controller
// inputs -----------------------------------
// sp = setpoint
// pv = current temperature
// pv_last = prior temperature
// ierr = integral error
// dt = time increment between measurements
// outputs ----------------------------------
// op = output of the PID controller
// P = proportional contribution
// I = integral contribution
// D = derivative contribution

float pid(float sp, float pv, float pv_last, float& ierr, float dt) {
  float Kc = 10.0; // K / %Heater
  float tauI = 50.0; // sec
  float tauD = 1.0;  // sec
  // PID coefficients
  float KP = Kc;
  float KI = Kc / tauI;
  float KD = Kc*tauD; 
  // upper and lower bounds on heater level
  float ophi = 100;
  float oplo = 0;
  // calculate the error
  float error = sp - pv;
  // calculate the integral error
  ierr = ierr + KI * error * dt;  
  // calculate the measurement derivative
  float dpv = (pv - pv_last) / dt;
  // calculate the PID output
  float P = KP * error; //proportional contribution
  float I = ierr; //integral contribution
  float D = -KD * dpv; //derivative contribution
  float op = P + I + D;
  // implement anti-reset windup
  if ((op < oplo) || (op > ophi)) {
    I = I - KI * error * dt;
    // clip output
    op = max(oplo, min(ophi, op));
  }
  ierr = I; 
  Serial.println("sp="+String(sp) + " pv=" + String(pv) + " dt=" + String(dt) + " op=" + String(op) + " P=" + String(P) + " I=" + String(I) + " D=" + String(D));
  return op;
}

void loop() { 
  new_ts = millis();
  if (new_ts - ts > 1000) {   

  // put your main code here, to run repeatedly:
  cektemp();
  if (cel > batas_suhu_atas){
    Q1off();
    ledon();
  }
  else {
    Q1on();
    ledoff();
  }
  if (cel1 > batas_suhu_atas){
    Q2off();
    ledon();
  }
  else {
    Q2on();
    ledoff();
  }

  pv = cel;   // Temperature T1
  dt = (new_ts - ts) / 1000.0;
  ts = new_ts;
  op = pid(sp,pv,pv_last,ierr,dt);
  ledcWrite(Q1Channel,op);
  pv_last = pv;
  
  delay (200);
  }
}

Download Program PID dengan Arduino Menggunakan Kit iTCLab (silahkan klik-kanan Save link as)di sini : 07-iTCLab_PID_Arduino.ino..


Silahkan diupload ke Kit iTCLab. Silahkan cek hasilnya di serial monitor. Seharusnya hasilnya seperti gambar berikut ini.


Dari hasil di atas, terlihat hasil pembacaan Sensor Suhu T1 dan T2. Karena memang ada 2 (dua) heater atau pemanas yang digunakan pada iTCLab. Dalam contoh pemrograman PID dengan arduino ini, kita fokus mengendalikan salah satu saja. Dalam contoh ini, pada heater 1 (pemanas 1), yang terbaca oleh Sensor T1. Sedangkan heater 2 atau pemanas 2 tidak kita kendalikan. Tampak dari hasil di atas, pembacaan sensor T1 menuju nilai Set Point (SP) yang kita harapkan. Sedangkan pembacaan sensor T2, tidak kita kendalikan. Membaca apa adanya akibat pengaruh pemanasan heater 1.