Translate

ARDUINO PID Control Tutorial Kendali Kecepatan Motor DC (RPM) dilengkapi Keypad 4x4 dan LCD 16x2

ARDUINO PID Control Tutorial Kendali Kecepatan Motor DC (RPM) dilengkapi Keypad 4x4 dan LCD 16x2


           Pada kesempatan kali ini saya akan menjelaskan mengenai bagaimana cara membuat sebuah alat yang bisa digunakan untuk pelatihan PID Control menggunakan Arduino. Alat ini difungsikan untuk mengendalikan kecepatan putaran motor (RPM) dengan menggunakan PWM yang merupakan output dari PID. alat ini dilengkapi dengan keypad 4x4 sebagai input pemilihan menu kemudian sebuah encoder untuk menghitung RPM serta sebuah LCD 16x2 sebagai penampilnya. device pengendali kecepatan motornya menggunakan driver modul L298N. untuk lebih jelasnya berikut adalah skema dan programnya.



a. Arduino Uno





b. Keypad Matrix 4x4





c. Motor DC + Encoder





c. Lcd 16x2 + I2C Shield





d. Modul Driver L298N






e. Program Arduino IDE

#include <Keypad.h>
#include <Wire.h>
#include <EEPROM.h>
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x3F, 16, 2);

volatile byte half_revolutions; //variabel tipe data byte
unsigned int rpmku; //variabel tipe data integer
unsigned long timeold; //variabel tipe data long

int kalibrasi;

char customKey;
const byte ROWS = 4;
const byte COLS = 4;

char keys[ROWS][COLS] = {
{'D', 'C', 'B', 'A'},
{'#', '9', '6', '3'},
{'0', '8', '5', '2'},
{'*', '7', '4', '1'}
};
byte rowPins[ROWS] = {4,5,6,7};
byte colPins[COLS] = {8,9,10,11};

int x = 0;

Keypad customKeypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS);

int speedx = 3;

float kp;
float nilaikp;
float ki;
float nilaiki;
float kd;
float nilaikd;
float sp;
float nilaisp;
float error,errorx,sumerr;
float p,i,d,pid,rpmfix;
float selisih;

void setup()
{
  lcd.begin();
  lcd.clear();
  lcd.noCursor();
 attachInterrupt(0, rpm_fun, RISING); //mengambil sinyal high pada pin 2
 half_revolutions = 0; //memberikan nilai 0 pada viariabel
 rpmku = 0;
 timeold = 0;
 kalibrasi = 0;

 pinMode(A0,OUTPUT);
 pinMode(A1,OUTPUT);
 pinMode(speedx,OUTPUT);
 pinMode(2,INPUT);
 
 digitalWrite(A0,HIGH);
 digitalWrite(A1,LOW);
}


void loop()
{
  customKey = customKeypad.getKey();

if(x == 0){
  lcd.setCursor(0,0);
  lcd.print("1.SET PID       ");
}

if(x == 1){
  lcd.setCursor(0,0);
  lcd.print("2.MULAI        ");
}

if(x == 2){
  lcd.setCursor(0,0);
  lcd.print("3.CEK PID     ");
}

 
  switch(customKey)
  {
  case '0' ... '9':
    break;
   
  case '#':
    break;

  case '*':
    break;
 
  case 'A':
  x++; 
    break;
   
  case 'B':
  x--;
    break;
   
  case 'C':
    break;
   
  case 'D':
  if(x == 0){
  lcd.clear();
  setkp();
  setki();
  setkd();
  setsp();
  cekpid();
  }
  if(x == 1){
  lcd.clear();
  mulai();
  }
  if(x == 2){
  lcd.clear();   
  cekpid();
  } 
    break;
  }
 
if(x > 2){
x = 0;
}

if(x < 0){
x = 2;
}
 
}

void setkp(){
  lcd.setCursor(0,0);
  lcd.print("SET KP     ");

  customKey = customKeypad.getKey();
 
  if(customKey >= '0' && customKey <= '9')
    {
      kp = kp * 10 + (customKey - '0');
      lcd.setCursor(0,1);
      lcd.print(kp);

    }
  
   if(customKey == 'A'){         
      lcd.clear();
      delay(1000);
      kp = kp/100;
      nilaikp = kp;     
      return;    
    }
   
    if(customKey == 'B'){         
      lcd.clear();
      delay(1000);
      kp = kp/1000;
      nilaikp = kp;     
      return;    
    }
   
    if(customKey == '*'){         
      lcd.clear();
      delay(1000);
      nilaikp = kp;     
      return;
    }

setkp();
}

void setki(){
  lcd.setCursor(0,0);
  lcd.print("SET KI     ");

  customKey = customKeypad.getKey();
 
  if(customKey >= '0' && customKey <= '9')
    {
      ki = ki * 10 + (customKey - '0');
      lcd.setCursor(0,1);
      lcd.print(ki);

    }
  
     if(customKey == 'A'){         
      lcd.clear();
      delay(1000);
      ki = ki/100;
      nilaiki = ki;     
      return;
    }
   
    if(customKey == 'B'){         
      lcd.clear();
      delay(1000);
      ki = ki/1000;
      nilaiki = ki;     
      return;
    }
  
    if(customKey == '*'){         
      lcd.clear();
      delay(1000);
      nilaiki = ki;     
      return;
    }

setki();
}

void setkd(){
  lcd.setCursor(0,0);
  lcd.print("SET KD     ");

  customKey = customKeypad.getKey();
 
  if(customKey >= '0' && customKey <= '9')
    {
      kd = kd * 10 + (customKey - '0');
      lcd.setCursor(0,1);
      lcd.print(kd);

    }
  
     if(customKey == 'A'){         
      lcd.clear();
      delay(1000);
      kd = kd/100;
      nilaikd = kd;     
      return;
    }
   
    if(customKey == 'B'){         
      lcd.clear();
      delay(1000);
      kd = kd/1000; 
      nilaikd = kd;     
      return;
    }
  
    if(customKey == '*'){         
      lcd.clear();
      delay(1000);
      nilaikd = kd;     
      return;
    }

setkd();
}

void setsp(){
  lcd.setCursor(0,0);
  lcd.print("SET SP     ");

  customKey = customKeypad.getKey();
 
  if(customKey >= '0' && customKey <= '9')
    {
      sp = sp * 10 + (customKey - '0');
      lcd.setCursor(0,1);
      lcd.print(sp);

    }
  
    if(customKey == '*'){         
      lcd.clear();
      delay(1000);
      nilaisp = sp;     
      return;
    }

setsp();
}

void cekpid(){

  lcd.setCursor(0,0);
  lcd.print("KP");
  lcd.print(nilaikp,2);
  lcd.print("-KI");
  lcd.print(nilaiki,2);
 
  lcd.setCursor(0,1);
  lcd.print("KD");
  lcd.print(nilaikd,2);
  lcd.print("-SP");
  lcd.print(nilaisp,2);
 
  customKey = customKeypad.getKey();
    
    if(customKey == '*'){         
      lcd.clear();
      delay(1000);   
      return;
    }
 
cekpid(); 
}

void mulai(){
   
analogWrite(speedx,pid);

  error = nilaisp - rpmfix;
  p = error * nilaikp;
  sumerr = error + errorx;
  i = nilaiki * sumerr;
  selisih = error - errorx;
  d = nilaikd * selisih;
  pid = p + i + d;

  if(pid < 0){
  pid = 0;
  }
 

  rpmku = 30*1000/(millis() - timeold)*half_revolutions; //mengaktifkan counter millis
  timeold = millis(); //hasil counter dimasukkan ke variabel timeold
  half_revolutions = 0; //reset variabel
 
  kalibrasi = (rpmku - 150)/109;  //rumus kalibrasi
  rpmfix = kalibrasi * 10;
 
  if(rpmfix > 2000){
  rpmfix = 0;
  } 
 
  //menampilkan nilai pada lcd
  lcd.setCursor(0, 0);
  lcd.print("RPM= ");
  lcd.print(rpmfix);
  lcd.print("       ");
  lcd.setCursor(0, 1);
  lcd.print("PID= ");
  lcd.print(pid);
  lcd.print("       ");
 
  delay(200);
  customKey = customKeypad.getKey();
    
    if(customKey == '*'){         
      lcd.clear();
      kp = 0;
      ki = 0;
      kd = 0;
      sp = 0;
      analogWrite(speedx,0);
      delay(1000);   
      return;
    }
   
errorx = error;   
mulai();
}


void rpm_fun(){
   half_revolutions++; //counter interupt
}



 
f. VIDEO HASILNYA

 








25 comments:

  1. This comment has been removed by the author.

    ReplyDelete
  2. Mas..
    Ada gambar rangkaiannya..?
    Saya mau coba..

    ReplyDelete
  3. This comment has been removed by the author.

    ReplyDelete
  4. ada circuit diagram boleh minta.. dan detail lebih lanjut berkenaan projek ini.. can send to my email. mohd.syafiq.fiq11@gmail.com

    ReplyDelete
  5. Mas boleh minta file librarynya dong, thx....

    ReplyDelete
  6. sangat mudah dipahami
    terimkasih bung

    ReplyDelete
  7. adagak bung tips input nilai kp,ki,dan kd yang tepat...?

    ReplyDelete
  8. mas , untuk variable x nya itu untuk nilai apa ya mas ?

    ReplyDelete
  9. Terima kasih. Gara2 postingan ini tugas kuliah saya tentang sistem kendali digital lancar. Semoga terus sukses untuk penulis blog ini tetap berbagi ilmu.

    Ijin Nitip blog juga tentang mikrokontrol yaa https://gescripter.blogspot.com/

    ReplyDelete
  10. eror mas , saya coba pakai codingnya , bisa bantu perbaikin erornya mas ?? terimakasih

    ReplyDelete
  11. Saludos desde colombia me puedes enviar el esquema a mi correo cristiansanta5@gmail.com

    ReplyDelete
  12. This comment has been removed by the author.

    ReplyDelete
  13. min boleh minta skema nya dong

    ReplyDelete
  14. Mas boleh minta gambar skematiknya ?
    Kirim ke hajamwuruk1957@gmail.com

    ReplyDelete
  15. mas, skematik rangkaiannya bagaimana ya? Bisa kirim ke khafitimronmuzaki@gmail.com. Terima kasih

    ReplyDelete
  16. halo mas, bisa liat rangkaiannya tidak?

    ReplyDelete
  17. mas mau tanya, kok setelah saya verify malah eror pada code "lcd.Begin"

    ReplyDelete
  18. Jika di buat untuk mengaktifkan relay pada limit rpm tertentu bisakah? Seperti otomatis suhu yg menyalahkan kipas

    ReplyDelete