Pada kesempatan kali ini saya akan menjelaskan mengenai bagaimana cara membuat sebuah alat yang bisa memonitor dan mengendalikan suhu menggunakan PID Control, alat ini menggunakan sensor thermocouple tipe K dan sensor asap. untuk fiturnya yaitu alat ini dapat diatur waktunya kapan dia ON dan OFF serta bisa disetting setpoint suhunya. untuk lebih jelasnya berikut adalah daftar komponen dan programnya.
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <max6675.h>
#define DS3231_I2C_ADDRESS 0x68
LiquidCrystal_I2C lcd(0x27, 20, 4);
int soPin = 7;
int thermoCS = 6;
int thermoCLK = 5;
int urutan;
int so1Pin = 10;
int CS1Pin = 9;
int CLK1Pin= 8;
int ledM = 11;
int ledH = 13;
int buzzer = 12;
MAX6675 thermocouple(thermoCLK, thermoCS, soPin);
MAX6675 thermocouple1(CLK1Pin, CS1Pin, so1Pin);
int btset = A1;
int btup = A2;
int btdown = A3;
int btok = 2;
int btback = 4;
int ssr = 3;
int mark = 0;
int kipasx;
int x;
int btsetx;
int btupx;
int btdownx;
int btokx;
int btbackx;
int jam;
int asap;
int temp1;
int temp2;
int jamku;
float suhusp;
int modeku;
int menitku;
float kp = 1.15;
float ki = 0.67;
float kd = 0.15;
float p,i,d,suhu,pid;
float error,errorx,sumerr;
float sp;
float pidku;
byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
// Convert normal decimal numbers to binary coded decimal
byte decToBcd(byte val)
{
return( (val/10*16) + (val%10) );
}
// Convert binary coded decimal to normal decimal numbers
byte bcdToDec(byte val)
{
return( (val/16*10) + (val%16) );
}
void setup()
{
lcd.begin();
lcd.clear();
lcd.noCursor();
pinMode(buzzer,OUTPUT);
pinMode(ledM,OUTPUT);
pinMode(ledH,OUTPUT);
pinMode(ssr,OUTPUT);
pinMode(btset,INPUT_PULLUP);
pinMode(btup,INPUT_PULLUP);
pinMode(btdown,INPUT_PULLUP);
pinMode(btok,INPUT_PULLUP);
pinMode(btback,INPUT_PULLUP);
Wire.begin();
Serial.begin(9600);
// DS3231 seconds, minutes, hours, day, date, month, year
setDS3231time(0,0,0,6,5,10,18);
}
void setDS3231time(byte second, byte minute, byte hour, byte dayOfWeek, byte
dayOfMonth, byte month, byte year)
{
// sets time and date data to DS3231
Wire.beginTransmission(DS3231_I2C_ADDRESS);
Wire.write(0); // set next input to start at the seconds register
Wire.write(decToBcd(second)); // set seconds
Wire.write(decToBcd(minute)); // set minutes
Wire.write(decToBcd(hour)); // set hours
Wire.write(decToBcd(dayOfWeek)); // set day of week (1=Sunday, 7=Saturday)
Wire.write(decToBcd(dayOfMonth)); // set date (1 to 31)
Wire.write(decToBcd(month)); // set month
Wire.write(decToBcd(year)); // set year (0 to 99)
Wire.endTransmission();
}
void readDS3231time(byte *second,
byte *minute,
byte *hour,
byte *dayOfWeek,
byte *dayOfMonth,
byte *month,
byte *year)
{
Wire.beginTransmission(DS3231_I2C_ADDRESS);
Wire.write(0); // set DS3231 register pointer to 00h
Wire.endTransmission();
Wire.requestFrom(DS3231_I2C_ADDRESS, 7);
// request seven bytes of data from DS3231 starting from register 00h
*second = bcdToDec(Wire.read() & 0x7f);
*minute = bcdToDec(Wire.read());
*hour = bcdToDec(Wire.read() & 0x3f);
*dayOfWeek = bcdToDec(Wire.read());
*dayOfMonth = bcdToDec(Wire.read());
*month = bcdToDec(Wire.read());
*year = bcdToDec(Wire.read());
}
void displayTime()
{
// retrieve data from DS3231
readDS3231time(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month,
&year);
lcd.setCursor(0,0);
// send it to the serial monitor
lcd.print(hour, DEC);
// convert the byte variable to a decimal number when displayed
lcd.print(":");
if (minute<10)
{
lcd.print("0");
}
lcd.print(minute, DEC);
lcd.print(":");
if (second<10)
{
lcd.print("0");
}
lcd.print(second, DEC);
}
void loop()
{
digitalWrite(ssr,HIGH);
asap = analogRead(A0);
temp1 = thermocouple.readCelsius();
temp2 = thermocouple1.readCelsius();
lcd.setCursor(0,1);
lcd.print("SUHU1 : ");
lcd.print(temp1 );
lcd.print(" 'C ");
lcd.setCursor(0,2);
lcd.print("SUHU2 : ");
lcd.print(temp2);
lcd.print(" 'C ");
lcd.setCursor(0,3);
lcd.print("ASAP: ");
lcd.print(asap);
lcd.print(" ");
btsetx = digitalRead(btset);
if(btsetx == 0){
delay(200);
lcd.clear();
pilih();
}
if(modeku == 1){
delay(200);
lcd.clear();
setmanual();
setDS3231time(0,0,0,6,5,10,18);
mulaimanu();
}
if(modeku == 2){
delay(200);
lcd.clear();
setDS3231time(0,0,0,6,5,10,18);
suhusp = 32.2;
urutan = 1;
mulaioto();
suhusp = 48.8;
urutan = 2;
mulaioto();
suhusp = 54.4;
urutan = 3;
mulaioto();
suhusp = 65.5;
urutan = 4;
mulaioto();
}
//displayTime();
delay(1000);
}
void pilih(){
btokx = digitalRead(btok);
btbackx = digitalRead(btback);
lcd.setCursor(5,0);
lcd.print("PILIH MODE");
lcd.setCursor(0,2);
lcd.print("MANUAL OTOMATIS");
if(btokx == 0){
delay(1000);
lcd.clear();
modeku = 2;
return;
}
if(btbackx == 0){
delay(1000);
lcd.clear();
modeku = 1;
return;
}
pilih();
}
void setmanual(){
lcd.setCursor(0,0);
lcd.print("PILIH JAM: ");
lcd.print(jamku);
lcd.print(" ");
lcd.setCursor(0,1);
lcd.print("PILIH MENIT: ");
lcd.print(menitku);
lcd.print(" ");
lcd.setCursor(0,2);
lcd.print("PILIH SUHU: ");
lcd.print(suhusp);
lcd.print(" ");
if(jamku < 0){
jamku = 0;
}
if(suhusp < 0){
suhusp = 0;
}
btsetx = digitalRead(btset);
btupx = digitalRead(btup);
btdownx = digitalRead(btdown);
btokx = digitalRead(btok);
btbackx = digitalRead(btback);
if(btupx == 0){
delay(200);
menitku = menitku + 30;
}
if(btdownx == 0){
delay(200);
menitku = menitku - 30;
}
if(menitku > 30){
jamku++;
menitku = 0;
}
if(menitku < 0){
menitku = 0;
jamku--;
}
if(btokx == 0){
delay(200);
suhusp = suhusp + 0.5;
}
if(btbackx == 0){
delay(200);
suhusp = suhusp - 0.5;
}
if(btsetx == 0){
delay(200);
lcd.clear();
return;
}
setmanual();
}
void mulaimanu(){
btokx = digitalRead(btok);
btbackx = digitalRead(btback);
if((btbackx == 0)&&(btokx == 0)){
lcd.clear();
delay(1000);
modeku = 0;
return;
}
analogWrite(ssr,pidku);
error = suhusp - temp1;
p = error * kp;
sumerr = error + errorx;
i = ki * sumerr;
d = kd * (error - errorx) ;
pid = p + i + d;
if(pid < 1){
pid = 0;
}
if(pid > 255){
pid = 255;
}
pidku = 255 - pid;
lcd.setCursor(11,3);
lcd.print(jamku);
lcd.print(".");
lcd.print(menitku);
lcd.print("/");
lcd.print(suhusp);
asap = analogRead(A0);
temp1 = thermocouple.readCelsius();
temp2 = thermocouple1.readCelsius();
lcd.setCursor(14,1);
lcd.print(pid);
lcd.print(" ");
lcd.setCursor(14,0);
lcd.print("MANUAL");
lcd.setCursor(0,1);
lcd.print("SUHU1: ");
lcd.print(temp1);
lcd.print(" 'C ");
lcd.setCursor(0,2);
lcd.print("SUHU2: ");
lcd.print(temp2);
lcd.print(" 'C ");
lcd.setCursor(0,3);
lcd.print("ASAP: ");
lcd.print(asap);
lcd.print(" ");
displayTime();
delay(1000);
if((hour == jamku)&&(minute == menitku)){
lcd.clear();
delay(1000);
modeku = 0;
return;
}
if(asap < 500){
digitalWrite(ledH,HIGH);
digitalWrite(ledM,LOW);
digitalWrite(buzzer,LOW);
}
if(asap > 500){
digitalWrite(ledH,LOW);
digitalWrite(ledM,HIGH);
digitalWrite(buzzer,HIGH);
}
errorx = error;
mulaimanu();
}
void mulaioto(){
btokx = digitalRead(btok);
btbackx = digitalRead(btback);
if((btbackx == 0)&&(btokx == 0)){
lcd.clear();
delay(1000);
modeku = 0;
return;
}
analogWrite(ssr,pidku);
error = suhusp - temp1;
p = error * kp;
sumerr = error + errorx;
i = ki * sumerr;
d = kd * (error - errorx) ;
pid = p + i + d;
if(pid < 1){
pid = 0;
}
if(pid > 255){
pid = 255;
}
pidku = 255 - pid;
lcd.setCursor(11,3);
lcd.print("1");
lcd.print(".");
lcd.print("30");
lcd.print("/");
lcd.print(suhusp);
asap = analogRead(A0);
temp1 = thermocouple.readCelsius();
temp2 = thermocouple1.readCelsius();
lcd.setCursor(14,1);
lcd.print(pid);
lcd.print(" ");
lcd.setCursor(14,0);
lcd.print("OTO");
lcd.print(urutan);
lcd.setCursor(0,1);
lcd.print("SUHU1: ");
lcd.print(temp1);
lcd.print(" 'C ");
lcd.setCursor(0,2);
lcd.print("SUHU2: ");
lcd.print(temp2);
lcd.print(" 'C ");
lcd.setCursor(0,3);
lcd.print("ASAP: ");
lcd.print(asap);
lcd.print(" ");
displayTime();
delay(1000);
if((hour == 1)&&(minute == 30)){
lcd.clear();
delay(1000);
modeku = 0;
return;
}
if(asap < 500){
digitalWrite(ledH,HIGH);
digitalWrite(ledM,LOW);
digitalWrite(buzzer,LOW);
}
if(asap > 500){
digitalWrite(ledH,LOW);
digitalWrite(ledM,HIGH);
digitalWrite(buzzer,HIGH);
}
errorx = error;
mulaioto();
}