Jumat, 15 April 2016

Cara Membuat Alat Ukur Kecepatan Putaran Motor DC Sederhana dengan Menggunakan Arduino

          selamat datang di blog Sharing Ilmu Mekatronika................................
          pada postingan kali ini akan dibahas tentang cara membuat alat ukur kecepatan motor dc dengan menggunakan arduino. Cara kerja alat ini sederhana sekali yaitu dengan menghitung jumlah putaran motor dc kemudian dibagi dengan nilai timer arduino. Dalam pembuatan alat digunakan sensor cahaya (LDR atau Photodioda) yang diatasnya dipasang sebuah led. Pada poros motor dc dipasang seperti baling-baling yang berputar sesuai putaran motor dc. Saat baling-baling tersebut menghalangi cahaya dari led menuju ke sensor maka jumlah  putaran motor dc dihitung tambah satu. Jumlah hitungan putaran motor dc akan di bagi dengan nilai timer internal arduino.
          Untuk membuat alat ukur kecepatan putaran motor dc ini diperlukan beberapa komponen yaitu:
  • led
  • R 330 ohm
  • R 10k ohm
  • trimpot 10k
  • photodioda
  • ic lm358
  • board Arduino dan Arduino IDE 
          Langkah pertama yang harus dilakukan adalah membuat rangkaian sensor cahaya beserta rangkaian komparator. Output dari Op-Amp dihubungkan ke pin arduino sebagai input. Berikut ini ditampilkan rangkaian sensor cahaya pada Gambar 1 dan rangkaian komparator pada Gambar 2.
Gambar 1. rangkaian sensor cahaya.

Gambar 2. rangkaian komparator.

          Pada rangkaian sensor cahaya posisi LED dan photodioda saling berhadapan. Pada Gambar 3 dapat dilihat rangkaian elektronika yang telah jadi.
Gambar 3. Rangkaian yang sudah siap.
          Langkah selanjutnya adalah membuat program pada arduino uno untuk alat ukur kecepatan motor dc. Tetapi, sebelumnya akan lebih baik jika kita membahas tentang timer pada arduino uno. Pada arduino terdapat beberapa function untuk timer diantaranya adalah:
  • delay() berfungsi untuk memberikan waktu tunda untuk eksekusi program pada baris selanjutnya dalam satuan detik.
  • delayMicrosecond() berfungsi untuk memberi tunda untuk eksekusi program pada baris selanjutnya dalam satuan mikro sekon. 
  • millis() berfungsi sebagai timer internal saat arduino mulai aktif dan akan terus menghitung hingga 50 hari. satuan dari nilai millis() adalah mili sekon.
  • micros() berfungsi sebagai timer internal saat arduino mulai aktif dan akan terus menghitung sampai 70 jam. satuan dari nilai micros() adalah mikro sekon.
          Baiklah, selanjutnya mari kita bahas program untuk alat ukur kecepatan putaran motor dc. Program yang ditulis pada arduino IDE adalah sebagai berikut:


int pin_counter = 7;

kode diatas adalah untuk inisialisasi pin arduino. maksud kode diatas adalah pin_counter adalah pin nomor 7 pada board arduino.

int counter = 0;
int kondisi_sekarang =0;
int kondisi_tadi =0;
int timer;
long rpm=0;
int x,y;

pada program ini terdapat beberapa variabel yang diperlukan seperti yang terlihat pada kode diatas.

void setup ()
{
    pinMode(pin_counter, INPUT); 
    Serial.begin(9600);
}

pada void setup dibuat kode untuk mengeklarasikan pin_counter (pin 7) sebagia pin input. pin input ini dihubungkan ke output Op-Amp. selain itu, dipanggil juga fungsi untuk komunikasi serial dimana tujuannya adalah untuk bisa mengakses serial monitor pada arduino IDE. Dengan mengakses serial monitor maka pembacaan pengukuran kecepatan motor dc dapat dilihat pada pc.

void loop ()
{   millis();

     berfungsi untuk mengaktifkan timer tipe millis pada arduino dengan satuan mili sekon.
    x= millis()/1000;

     x adalah nilai timer dalam satuan sekon.

    if (digitalRead(pin_counter)==HIGH)
    {
      kondisi_sekarang = 1;      
    }
    else
    {
      kondisi_sekarang= 0;
    }

     jika input pada pin_counter adalah high maka nilai kondisi_sekarang adalah 1. jika input pada pin_counter adalah low maka nilai kondisi_sekarang adalah 0.

    if(kondisi_sekarang!=kondisi_tadi)
    { 
        if(kondisi_sekarang==1)
        {
            counter++;
        }
    }

     jika nilai kondisi_sekarang tidak sama dengan nilai kondisi_tadi kemudian apabila nilai kondisi_sekarang adalah 1 maka nilai counter akan bertambah 1. Pada kode ini bisa diartikan bahwa nilai counter akan bertambah saat adalah perubahan sinyal input dari logika 0 ke logika 1 atau biasa dikenal sebagai rising edge. 

    kondisi_tadi=kondisi_sekarang;

     apabila eksekusi program telah sampai pada baris ini, maka nilai kondisi_sekarang akan berubah menjadi nilai kondisi_tadi. proses ini akan terjadi saat setiap proses looping dilakukan. 
   
    y= counter * 60;
    rpm = y/x;
    Serial.println(rpm);
    delay(10);


     kode terakhir pada program void loop ini adalah rumus untuk mendapat nilai kecepatan putaran motor dc dalam satuan RPM. y adalah nilai counter yang dikalikan dengan 60. tujuan dikalikan dengan 60 adalah untuk mendapat satuan menit pada nilai timer. sedangkan nilai rpm adalah nilai y dibagi nilai x. kemudian nilai rpm akan ditampilkan pada serial monitor arduino. kode delay (10) berfungsi memberi waktu tunda untuk masuk ke looping selanjutnya. 

          Pada saat program dijalankan bukalah serial monitor pada software arduino IDE untuk melihat hasil pembacaan pengukuran. berikut adalah langkah-langkah untuk membuka serial monitor pada arduino IDE:

  • pada arduino IDE pilihlah menu tools
  • kemudian pilih serial monitor
  • cara yang lebih singkatnya adalah dengan menekan tombol ctrl + shift + m. 
          Gambar 4 adalah contoh tampilan serial monitor saat dilakukan pengukuran kecepatan motor dc

Gambar 4. tampilan serial monitor saat pengukuran kecepatan motor dc.

          demikianlah penjelasan tentang membuat alat ukur kecepatan motor dc sederhana dengan menggunakan arduino. terima kasih telah membaca sharing ilmu kali ini semoga postingan ini bermanfaat. Mohon maaf apabila ada kesalahan dalam penulisan...

see you di postingan selanjutnya... mari saling berbagi ilmu.... :)





Senin, 11 April 2016

Membuat Robot Line Follower Digital 2 dengan kontrol PID (programming)

          Pada postingan kali ini kita akan membahas programming untuk robot line follower digital. postingan sebelumnya (Membuat Robot Line follower digital 1 (elektronik)), telah dijelaskan bahwa Robot Line follower Digital adalah Line follower yang menggunakan mikrokontroller untuk mengatur kecepatan motor dc berdasarkan pembacaan garis oleh sensor. Mikrokontroller yang digunakan adalah ATMega 16 yaitu mikrokontroller keluaran Atmel. Mikrokontroller tersebut harus diprogram terlebih dahulu sebelum digunakan. Software yang digunakan untuk memprogram ATMega 16 adalah Codevision AVR.

          Sebelum masuk lebih jauh tentang pemrograman Robot Line Follower dengan kontrol PID, terlebih dahulu akan dijelaskan hardware yang diperlukan untuk membuat robot tersebut. Hardware-hardware yang diperlukan antara lain:

  • ·         10 rangkaian sensor cahaya. 8 sensor untuk bagian depan robot dan  sensor untuk bagian kiri dan kanan belakang robot (lebih tepatnya sebelum roda belakang).
  • ·         Rangkaian driver motor dc, dianjurkan untuk membuat rangkaian driver mosfet karena dengan rangkaian mosfet ada efek pengereman saat diinputkan logika stop. Dengan adanya efek pengereman tersebut maka tidak ada sisa putaran motor dc saat motor dimatikan.
  • ·         Minimum system ATMega 16.
  • ·         2 motor dc + roda dan satu buah roda bebas untuk bagian depan robot.
  • ·         Body  robot Line follower. Bisa lihat referensi desain body robot di internet. pada Gambar 1 bisa dilihat contoh robot line follower digital.

Gambar 1. contoh Robot line Follower Digital
sumber: http://miduino-robot.com/


          Selanjutnya mari kita bahas gambaran kasar dari sistem kerja robot line follower digital dengan kontrol PID. Pada robot ini, output dari sensor cahaya langsung dihubungkan ke PORT A mikrokontroller kemudian mikrokontroller akan membaca dan mengolah data dari pembacaan ADC output sensor. Dari pengolahan data ADC tersebut akan diketahui sensor mana yang membaca garis hitam dan sensor mana yang membaca permukaan berwarna putih. Setelah diketahui sensor yang membaca garis hitam maka data error dari pembacaan garis akan diolah dengan kontrol PID. Output dari kontrol PID tersebut digunakan untuk mengatur kecepatan motor kiri dan motor kanan atau merubah arah putaran motor kiri atau motor kanan.

Lanjuuuut ke program mikrokontroller.........................

          okeee pada bagian ini akan ditampilkan tutorial program yang harus dibuat dan sedikit penjelasannya. Hal pertama yang dilakukan untuk mebuat program mikrokontroller adalah mengatur code wizard avr dengan memilih menu New kemudian pilih New project pada Codevision AVR. Kode wizard yang diatur untuk pemrograman bisa dilihat pada Gambar 2.




Gambar 2. Pengaturan Code Wizard AVR.

          Setelah pengaturan Code Wizard AVR selesai dilakukan maka tuliskan program pada lembar kerja Codevision AVR sebegai berikut:

#include <mega16.h>
#include <delay.h>
#include <lcd.h>
#include <stdio.h>
#include <delay.h>

program diatas adalah untuk memanggil library-library yang diperlukan untuk membuat program robot line follower digital ini.

#asm
.equ __lcd_port=0x18 ;PORTB
#endasm       // kode untuk menggunakan lcd


#define sensor_kanan PINC.0
#define sensor_kiri PINC.1
#define tombol1 PINC.3
#define tombol2 PINC.4
#define tombol3 PINC.5
#define tombol4 PINC.6
#define tombol5 PINC.7
#define motor_kiri OCR1A  
#define motor_kanan OCR1B
#define m1a PORTD.2
#define m1b PORTD.3
#define m2a PORTD.6
#define m2b PORTD.7

kode-kode diatas adalah untuk memberi nama pada pin-pin mikrokontroller. hal ini dilakukan untuk mempermudah memanggil pin-pin dan mempermudah saat mengganti pin yang digunakan untuk sensor_kanan, sensor_kiri, dan lain-lain. pada penamaan pin mikrokontroller perlu diketahui bahwa penulisan PIN digunakan apabila difungsikan sebagai input sedangkan penulisan PORT difungsikan sebagai output. misalnya ditulis PINC.3 berarti pin 3 pada PORT C berfungsi sebagai input, apabila ditulis PORTD.2 berarti pin 2 pada PORT D difungsikan sebagai output. simpel kan??????

int a,b,c,d,e,f,g,h,m=0,ref=100;
int error,error1,nil_pid,pwm,kode,x=0;

eeprom int Kp = 0;
eeprom int Ki = 0;
eeprom int Kd = 0;
eeprom int Ts= 0;
eeprom int Upper= 0;
eeprom int Lower= 0;
eeprom int Set_point=0;
eeprom int e0=  0;
eeprom int e1 = 0;
eeprom int e2 = 0;
eeprom int e3 = 0;
eeprom int e4 = 0;
eeprom int e5 = 0;
eeprom int e6 = 0;
eeprom int e7 = 0;
eeprom int e8 = 0;
char lcd_buff[33];

ini merupakan pendeklarasian variabel-variabel yang akan digunakan. beberapa tipe data yang digunakan adalah integer (int), dan character (char). pada kode diatas dapat dilihat bahwa pada beberapa variabel disimpan pada memori eeprom. hal ini bertujuan untuk menyimpan nilai variabel pada memori eeprom sehingga saat mikrokontroller dimatikan atau direset maka nilai variabel tersebut masih tersimpan.

#define ADC_VREF_TYPE 0x20
unsigned char read_adc(unsigned char adc_input)
{
ADMUX=adc_input | (ADC_VREF_TYPE & 0xff);
delay_us(10);
ADCSRA|=0x40;
while ((ADCSRA & 0x10)==0);
ADCSRA|=0x10;
return ADCH;
}

kode diatas adalah untuk memanggil fungsi ADC. kode ini akan muncul secara otomatis setelah ADC pada pengaturan Code Wizard diaktifkan.

void rem()      kode untuk pengereman (robot mundur). kode ini hanya
{               diaktifkan sesaat
m1a=0;m1b=1;
m2a=1;m2b=0;
motor_kiri=1023;
motor_kanan=1023;
}

void maju ()       kode untuk robot bergerak maju
{
m1a=1;m1b=0;
m2a=0;m2b=1;
motor_kiri=1023;
motor_kanan=1023;
}

void rem_kanan ()   kode untuk robot berputar ke kanan
{
m1a=0;m1b=1;
m2a=0;m2b=1;
motor_kiri=1023;
motor_kanan=1023;  
}

void rem_kiri ()    kode untuk robot berputar ke kiri 
{m1a=1;m1b=0; 
m2a=1;m2b=0;
motor_kiri=1023;
motor_kanan=1023;
}


void sensor()
{
            if(read_adc(0)>ref)a=0;
            else {a=1;}
            if(read_adc(1)>ref)b=0;
            else {b=1;}
            if(read_adc(2)>ref)c=0;
            else {c=1;}
            if(read_adc(3)>ref)d=0;
            else {d=1;}
            if(read_adc(4)>ref)e=0;
            else {e=1;}
            if(read_adc(5)>ref)f=0;
            else {f=1;}
            if(read_adc(6)>ref)g=0;
            else {g=1; }
            if(read_adc(7)>ref)h=0;
            else {h=1;}
}

fungsi sensor() digunakan untuk memberikan logika pada masing-masing pembacaan ADC sensor sehingga mudah diidentifikasi sensor yang berada di permukaan putih atau sensor yang berada digaris hitam.


void check_sensor()
{  lcd_clear();
    lcd_gotoxy(0,0);
    sprintf(lcd_buff,"%i, %i, %i, %i",read_adc(0),read_adc(1),read_adc(2),read_adc(3));
    lcd_puts(lcd_buff); 
     lcd_gotoxy(0,1);
    sprintf(lcd_buff,"%i, %i, %i, %i",read_adc(4),read_adc(5),read_adc(6),read_adc(7));
    lcd_puts(lcd_buff);  
    delay_ms(10);
   
   delay_ms(1000);
   lcd_gotoxy(0,1);
    sprintf(lcd_buff,"%i%i",sensor_kanan,sensor_kiri);
   lcd_puts(lcd_buff);   
   delay_ms(1000);
}   

fungsi check_sensor() ini sebenarnya tidak terlalu wajib untuk dituliskan. fungsi ini hanya digunakan untuk melihat apakah sensor yang digunakan bekerja dengan baik atau tidak.

void seting_awal ()  kode-kode ini diperlukan untuk melakukan 
{                    pengaturan pada parameter-parameter PID, 
                     kecepatan motor, error, dll.     
set:
Kp=Kp;
if(tombol1==0){Kp++;delay_ms(10);}
if(tombol2==0){Kp=Kp-1;delay_ms(10);}
if(Kp>100){Kp=0;delay_ms(10);}
if(Kp<0){Kp=100;delay_ms(10);}
lcd_clear();

lcd_gotoxy(0,1);
sprintf(lcd_buff,"Nilai Kp:%i",Kp);
lcd_puts(lcd_buff);
delay_ms(100);
if(tombol4==0)
{
delay_ms(150);goto set1;
}
if(tombol4==0)
{
delay_ms(150);goto set16;
}
if(tombol3==0) goto run;
else goto set;
//====================================
set1:
Ki=Ki;
if(tombol1==0) {Ki++;delay_ms(10);}
if(tombol2==0) {Ki=Ki-1;delay_ms(10);}
if(Ki>100){Ki=0;delay_ms(10);}
if(Ki<0) {Ki=100;delay_ms(10);}
lcd_clear();
lcd_gotoxy(0,1);
sprintf(lcd_buff,"Nilai Ki:%i.%i",Ki/10,Ki%10);
lcd_puts(lcd_buff);
delay_ms(100);
if(tombol4==0) {delay_ms(150);goto set2;}
if(tombol3==0){delay_ms(150);goto set;}
else
goto set1;
//======================================
set2:
Kd=Kd;
if(tombol1==0) {Kd=Kd+2;delay_ms(10);}
if(tombol2==0) {Kd=Kd-2;delay_ms(10);}
if(Kd>100){Kd=0;delay_ms(10);}
if(Kd<0) {Kd=100;delay_ms(10);}
lcd_clear();
lcd_gotoxy(0,1);
sprintf(lcd_buff,"Nilai Kd:%i",Kd);
lcd_puts(lcd_buff);
delay_ms(100);
if(tombol4==0) {delay_ms(150);goto set3;}
if(tombol3==0){delay_ms(150);goto set1;}
else
goto set2;
//========================================
set3:
Ts=Ts;
if(tombol1==0) {Ts++;delay_ms(10);}
if(tombol2==0) {Ts=Ts-1;delay_ms(10);}
if(Ts>100){Ts=0;delay_ms(10);}
if(Ts<0) {Ts=100;delay_ms(10);}
lcd_clear();
lcd_gotoxy(0,1);
sprintf(lcd_buff,"Time Sampling:%i ms",Ts);
lcd_puts(lcd_buff);
delay_ms(100);
if(tombol4==0) {delay_ms(150);goto set4;}
if(tombol3==0){delay_ms(150);goto set2;}
else
goto set3;
//=============================================
set4:
Set_point=Set_point;
if(tombol1==0) {Set_point=Set_point+5;delay_ms(10);}
if(tombol2==0) {Set_point=Set_point-5;delay_ms(10);}
if(Set_point>1023){Set_point=0;delay_ms(10);}
if(Set_point<0) {Set_point=1023;delay_ms(10);}
lcd_clear();
lcd_gotoxy(0,0);
lcd_putsf("Set Point");
lcd_gotoxy(0,1);
sprintf(lcd_buff,"Kec:%i",Set_point);
lcd_puts(lcd_buff);
delay_ms(100);
if(tombol4==0) {delay_ms(150);goto set5;}
if(tombol3==0){delay_ms(150);goto set3;}
else
goto set4;
//=================================================
set5:
Upper=Upper;
if(tombol1==0) {Upper=Upper+5;delay_ms(10);}
if(tombol2==0) {Upper=Upper-5;delay_ms(10);}
if(Upper>1023){Upper=0;delay_ms(10);}
if(Upper<0) {Upper=1023;delay_ms(10);}
lcd_clear();
lcd_gotoxy(0,1);
sprintf(lcd_buff,"Upper:%i",Upper);
lcd_puts(lcd_buff);
delay_ms(100);
if(tombol4==0) {delay_ms(150);goto set6;}
if(tombol3==0){delay_ms(150);goto set4;}
else
goto set5;
//====================================================
set6:
Lower=Lower;
if(tombol1==0) {Lower=Lower+5;delay_ms(10);}
if(tombol2==0) {Lower=Lower-5;delay_ms(10);}
if(Lower>1023){Lower=0;delay_ms(10);}
if(Lower<0) {Lower=1023;delay_ms(10);}
lcd_clear();
lcd_gotoxy(0,1);
sprintf(lcd_buff,"Lower:%i",Lower);
lcd_puts(lcd_buff);
delay_ms(100);
if(tombol4==0) {delay_ms(150);goto set7;
}
if(tombol3==0){delay_ms(150);goto set5;}
else
goto set6;
//========Menampilkan Eror-Eror===============
set7:
e0=e0;
if(tombol1==0) {e0++;delay_ms(10);}
if(tombol2==0) {e0=e0-1;delay_ms(10);}
if(e0>100){e0=0;delay_ms(10);}
if(e0<0) {e0=100;delay_ms(10);}
lcd_clear();
lcd_gotoxy(0,1);
sprintf(lcd_buff,"e0:%i",e0);
lcd_puts(lcd_buff);
delay_ms(100);
if(tombol4==0) {delay_ms(150);goto set8;}
if(tombol3==0){delay_ms(150);goto set6;}
else
goto set7;
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
//========Menampilkan Eror-Eror===============
set8:
e1=e1;
if(tombol1==0) {e1++;delay_ms(10);}
if(tombol2==0) {e1=e1-1;delay_ms(10);}
if(e1>100){e1=0;delay_ms(10);}
if(e1<0) {e1=100;delay_ms(10);}
lcd_clear();
lcd_gotoxy(0,1);
sprintf(lcd_buff,"e1:%i",e1);
lcd_puts(lcd_buff);
delay_ms(100);
if(tombol4==0) {delay_ms(150);goto set9;}
if(tombol3==0){delay_ms(150);goto set7;}
else
goto set8;
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
//========Menampilkan Eror-Eror===============
set9:
e2=e2;
if(tombol1==0) {e2++;delay_ms(10);}
if(tombol2==0) {e2=e2-1;delay_ms(10);}
if(e2>100){e2=0;delay_ms(10);}
if(e2<0) {e2=100;delay_ms(10);}
lcd_clear();
lcd_gotoxy(0,1);
sprintf(lcd_buff,"e2:%i",e2);
lcd_puts(lcd_buff);
delay_ms(100);
if(tombol4==0) {delay_ms(150);goto set10;}
if(tombol3==0){delay_ms(150);goto set8;}
else
goto set9;
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
//========Menampilkan Eror-Eror===============
set10:
e3=e3;
if(tombol1==0) {e3++;delay_ms(10);}
if(tombol2==0) {e3=e3-1;delay_ms(10);}
if(e3>100){e3=0;delay_ms(10);}
if(e3<0) {e3=100;delay_ms(10);}
lcd_clear();
lcd_gotoxy(0,1);
sprintf(lcd_buff,"e3:%i",e3);
lcd_puts(lcd_buff);
delay_ms(100);
if(tombol4==0) {delay_ms(150);goto set11;}
if(tombol3==0){delay_ms(150);goto set9;}
else
goto set10;
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
//========Menampilkan Eror-Eror===============
set11:
e4=e4;
if(tombol1==0) {e4++;delay_ms(10);}
if(tombol2==0) {e4=e4-1;delay_ms(10);}
if(e4>100){e4=0;delay_ms(10);}
if(e4<0) {e4=100;delay_ms(10);}
lcd_clear();
lcd_gotoxy(0,1);
sprintf(lcd_buff,"e4:%i",e4);
lcd_puts(lcd_buff);
delay_ms(100);
if(tombol4==0) {delay_ms(150);goto set12;}
if(tombol3==0){delay_ms(150);goto set10;}
else
goto set11;
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
//========Menampilkan Eror-Eror===============
set12:
e5=e5;
if(tombol1==0) {e5++;delay_ms(10);}
if(tombol2==0) {e5=e5-1;delay_ms(10);}
if(e5>100){e5=0;delay_ms(10);}
if(e5<0) {e5=100;delay_ms(10);}
lcd_clear();
lcd_gotoxy(0,1);
sprintf(lcd_buff,"e5:%i",e5);
lcd_puts(lcd_buff);
delay_ms(100);
if(tombol4==0) {delay_ms(150);goto set13;}
if(tombol3==0){delay_ms(150);goto set11;}
else
goto set12;
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
//========Menampilkan Eror-Eror===============
set13:
e6=e6;
if(tombol1==0) {e6++;delay_ms(10);}
if(tombol2==0) {e6=e6-1;delay_ms(10);}
if(e6>100){e6=0;delay_ms(10);}
if(e6<0) {e6=100;delay_ms(10);}
lcd_clear();
lcd_gotoxy(0,1);
sprintf(lcd_buff,"e6:%i",e6);
lcd_puts(lcd_buff);
delay_ms(100);
if(tombol4==0) {delay_ms(150);goto set14;}
if(tombol3==0){delay_ms(150);goto set12;}
else
goto set13;
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
//========Menampilkan Eror-Eror===============

set14:
e7=e7;
if(tombol1==0) {e7++;delay_ms(10);}
if(tombol2==0) {e7=e7-1;delay_ms(10);}
if(e7>100){e7=0;delay_ms(10);}
if(e7<0) {e7=100;delay_ms(10);}
lcd_clear();
lcd_gotoxy(0,1);
sprintf(lcd_buff,"e7:%i",e7);
lcd_puts(lcd_buff);
delay_ms(100);
if(tombol4==0) {delay_ms(150);goto set15;}
if(tombol3==0){delay_ms(150);goto set13;}
else
goto set14;

set15:
e8=e8;
if(tombol1==0) {e8++;delay_ms(10);}
if(tombol2==0) {e8=e8-1;delay_ms(10);}
if(e8>100){e8=0;delay_ms(10);}
if(e8<0) {e8=100;delay_ms(10);}
lcd_clear();
lcd_gotoxy(0,1);
sprintf(lcd_buff,"e8:%i",e8);
lcd_puts(lcd_buff);
delay_ms(100);
if(tombol4==0) {delay_ms(150);goto set16;}
if(tombol3==0){delay_ms(150);goto set14;}
else
goto set15;

set16:
 ref=ref;
 if(tombol1==0){ref=ref+5;delay_ms(10);}
 if(tombol2==0){ref=ref-5;delay_ms(10);}
 if(step>100){step=0;delay_ms(10);}
 if(step<0){step=100;delay_ms(10);}
 lcd_clear();
 lcd_gotoxy(0,0);
 sprintf(lcd_buff,"adc=%i",read_adc(0)) ;
 lcd_puts(lcd_buff);
 lcd_gotoxy(0,1);
 sprintf(lcd_buff,"ref:%i",ref);
 lcd_puts(lcd_buff);
 delay_ms(100);
if(tombol4==0) {delay_ms(150);goto run;}
if(tombol3==0){delay_ms(150);goto set15;}
else
goto set16;


//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
run:
lcd_clear();
lcd_gotoxy(1,0);
lcd_putsf("Save To EEPROM");
delay_ms(200);
Kp=Kp;Ki=Ki;Kd=Kd;Ts=Ts;Set_point=Set_point;Lower=Lower;Upper=Upper;
e0=e0;e1=e1;e2=e2;e3=e3;e4=e4;e5=e5;e6=e6;e7=e7;e8=e8;ref=ref;
}

program diatas akan sangat membantu dalam proses tuning untuk mendapatkan parameter yang pas untuk kontrol PID, error sensor, kecepatan motor, dan lain sebagainya.


void PID ()
{
sensor();
//***hitam=mati/0 &  putih=nyala/1
//=====sensor mengarah ke Kiri
if (((a==1&&b==1)&&(c==1&&f==1))&&((g==1&&h==1)&&(d==0&&e==0)) ) {error=e0;}
else if (((a==1&&b==1)&&(c==1&&f==1))&&((g==1&&h==1)&&(d==0&&e==1))) {error=-e1;}
else if (((a==1&&b==1)&&(c==0&&f==1))&&((g==1&&h==1)&&(d==0&&e==1))) {error=-e2;}
else if (((a==1&&b==1)&&(c==0&&f==1))&&((g==1&&h==1)&&(d==1&&e==1))) {error=-e3;}
else if (((a==1&&b==0)&&(c==0&&f==1))&&((g==1&&h==1)&&(d==1&&e==1))) {error=-e4;}
else if (((a==1&&b==0)&&(c==1&&f==1))&&((g==1&&h==1)&&(d==1&&e==1))) {error=-e5;}
else if (((a==0&&b==0)&&(c==1&&f==1))&&((g==1&&h==1)&&(d==1&&e==1))) {error=-e6;}
else if (((a==0&&b==1)&&(c==1&&f==1))&&((g==1&&h==1)&&(d==1&&e==1))) {error=-e7;}
else if (sensor_kanan==0) {kode=12;}
//=====sensor mengarah ke Kanan
else if (((a==1&&b==1)&&(c==1&&f==1))&&((g==1&&h==1)&&(d==0&&e==0))) {error=e0;}
else if (((a==1&&b==1)&&(c==1&&f==1))&&((g==1&&h==1)&&(d==1&&e==0))) {error=e1;}
else if (((a==1&&b==1)&&(c==1&&f==0))&&((g==1&&h==1)&&(d==1&&e==0))) {error=e2;}
else if (((a==1&&b==1)&&(c==1&&f==0))&&((g==1&&h==1)&&(d==1&&e==1))) {error=e3;}
else if (((a==1&&b==1)&&(c==1&&f==0))&&((g==0&&h==1)&&(d==1&&e==1))) {error=e4;}
else if (((a==1&&b==1)&&(c==1&&f==1))&&((g==0&&h==1)&&(d==1&&e==1))) {error=e5;}
else if (((a==1&&b==1)&&(c==1&&f==1))&&((g==0&&h==0)&&(d==1&&e==1))) {error=e6;}
else if (((a==1&&b==1)&&(c==1&&f==1))&&((g==1&&h==0)&&(d==1&&e==1))) {error=e7;}
else if (sensor_kiri==0) {kode=24;}
else if (((a==1&&b==1)&&(c==1&&f==1))&&((g==1&&h==1)&&(d==1&&e==1)))
{
if (kode==12)
{
error=-e8;
rem_kiri();
delay_ms(20);
}
else if (kode==24)
{
error=e8;
rem_kanan();
delay_ms(20);
}
}
maju();
nil_pid=((Kp*error)+((Ki/10)*(error+error1)*Ts)+((Kd/Ts)*(error-error1)));
error1=error;
//===== Hitung Kondisi Pertama=============
pwm=Set_point-(nil_pid);
if(pwm>Upper){pwm=Upper;}
if(pwm<Lower){pwm=Lower;}
motor_kanan=pwm;
//=====Hitung Kondisi Kedua===============
pwm=Set_point+(nil_pid);
if(pwm>Upper){pwm=Upper;}
if(pwm<Lower){pwm=Lower;}
motor_kiri=pwm;

delay_ms(Ts);
}

program diatas adalah untuk kontrol PID robot line follower digital. secara kasarnya, nilai error untuk sensor yang telah diatur pada saat pengaturan parameter-parameter akan diolah dengan rumus kontrol PID kemudian hasilnya akan digunakan untuk mengatur kecepatan putaran motor kiri dan motor kanan robot. apabila sensor yang berada di garis hitam adalah sensor kiri atau sensor kanan yang terletak di depan ban belakang robot maka nilai PID diabaikan dan robot akan langsung berputar arah ke kiri atau ke kanan. simpell!!!.


void tampil_data()
{ sensor();
lcd_gotoxy(0,1);
sprintf(lcd_buff,"%i%i%i%i%i%i%i%i",a,b,c,d,e,f,g,h);
lcd_puts(lcd_buff);

lcd_gotoxy(0,0);
sprintf(lcd_buff,"%i",error);
lcd_puts(lcd_buff);
lcd_gotoxy(4,0);
sprintf(lcd_buff,"R%i",motor_kiri);
lcd_puts(lcd_buff);
lcd_gotoxy(10,0);
sprintf(lcd_buff,"L%i",motor_kanan);
lcd_puts(lcd_buff);
lcd_gotoxy(15,0);
}

kode ini digunakan untuk menampilkan data seperti nilai error, identifikasi data sensor, dan nilai kecepatan motor kanan dan kiri.

void main(void)
{

PORTC=0xFF;
DDRC=0x00;

PORTD=0x00;
DDRD=0xFF;

TCCR1A=0xA3;
TCCR1B=0x0B;
TCNT1=0x0000;//PWM 16 bit//
OCR1A=0x3FF;
OCR1B=0x3FF;
TIFR=0;

ADMUX=ADC_VREF_TYPE & 0xff;
ADCSRA=0x87;
SFIOR&=0xEF;

// LCD module initialization
lcd_init(16);
seting_awal();
 lcd_clear();

program-program ini adalah program utama pada mikrokontroller yang berisi inisialisasi PORT, pengaturan timer untuk PWM, pengaturan untuk PWM, dan lain-lain.

while (1)
      {lcd_clear();       
       if(tombol5==0)
       {while(tombol5==0){
        check_sensor();}
       }
       else
       {
       tampil_data();
       PID();
       delay_ms(Ts);
       }
      }

program diatas adalah looping pada program mikrokontroller yang akan diulang secara terus menerus. pada program tersebut dapat dilihat bahwa saat tombol 5 ditekan maka dilakukan pengecekan pembacaan sensor. apabila tidak ditekan maka robot akan bergerak dengan kontrol PID.
        
          demikianlah postingan kali ini yang menjelaskan tentang program robot line follower digital dengan kontrol PID. mohon maaf apabila ada penulisan yang salah. semoga kita semua terus memiliki semangat yang tinggi untuk terus mempelajari hal baru. 


karena apabila tidak sanggup menahan lelahnya belajar maka siap-siaplah menghadapi sakitnya kebodohan.

terima kasih....................................