Anda di halaman 1dari 21

Membuat Robot Line Follower Sederhana

A. Mekanika

Bagian utama badan robot terbuat dari plat alumunium. Untuk gearbox dan motor
menggunakan bagian dari mainan tamiya. Dan bagian badan lainnya adalah PCB dan
bahan acrilic.
Pada bagian roda menggunakan gearbox dari tamiya. Gearbox ini berguna untuk
menaikan torsi dari motor yang mempunyai torsi lemah.

B. Elektronika
1. Sensor
Untuk rangkaian elektronika sensor menggunakan 8 sensor proximity dengan
output tegangan analog yang kemudian akan dijadikan input oleh mikrokontroler
sebagai input untuk PORT ADC. Rangkaian proximity sendiri sederhananya terdiri
dari bagian transmitter (dalam hal ini LED) dan receiver (dalam hal ini
Endang Rusiana >> wangready@yahoo.com
Januari 2012

Page 1

phototransistor). Cara kerjanya, ketika LED menyala, maka akan memantul di


permukaan arena yang berwarna putih dan garis hitam. Respon terhadap warna putih,
pantulan cahaya akan sempurna. Sedangkan terhadap warna hitam pantulan intensitas
cahaya berkurang. Hal itu akan mempengaruhi aktivasi dari phototransistor yang
mempunyai prinsip kerja sebagai saklar sederhana, jika ada cahaya maka tersambung,
jika tidak ada cahaya maka tidak tersambung.

Dari rangkaian di atas, jika mengenai warna putih maka output tegangan akan
lebih kecil daripada output tegangan sensor-mengenai warna hitam yang memberikan
pantulan dengan intensitas cahaya rendah.

Rangkaian lainnya yang mempunyai prinsip sebagai sensor adalah rangkaian push
button yang kelak berguna untuk melakukan setting pada robot.

Endang Rusiana >> wangready@yahoo.com


Januari 2012

Page 2

Terdapat empat buah push button yang masing-masing berguna sebagai tombol
enter, cancel, arah_plus, dan arah_minus. Cara kerjanya adalah pada keadaan awalnya
titik pb1..4 diberi tegangan high atau 5V oleh mikrokontroller dan keadaan tersebut
dibaca juga oleh mikrokontroler. Sehingga data pada keadaan tersebut terbaca logic 1
oleh mikrokontroller. Jika tombol ditekan, maka otomatis jalur pb1..4 akan terhubung
dengan ground. Sehingga otomatis tegangan di jalur tersebut menjadi 0V dan oleh
mikrokontroller akan terbaca sebagai logic 0. Begitulah mikrokontroler membedakan
kondisi tombol tidak ditekan dan ditekan.
2. Prosesor
Rangkaian prosesor disini menggunakan sistem minimum dari ATMega32.
Berikut schematicnya.

Dalam mikrokontroller inilah algoritma program akan dimasukan. Mengolah data


dari input sensor sehingga menghasilkan output ke aktuator.
3. Aktuator
Aktuator disini adalah motor DC. Untuk menggerakan motor DC diperlukan
sebuah rangkaian motor driver yang biasa disebut H-bridge. Rangkaian ini berguna
untuk mengontrol motor yang mempunyai tegangan operasi yang lebih besar.

Endang Rusiana >> wangready@yahoo.com


Januari 2012

Page 3

Dalam rangkaian ini kita gunakan H-bridge dalam kemasan IC yaitu L298.
Berikut rangkaian untuk L298.

Disini yang termasuk aktuator juga adalah speaker yang berguna sebagai indikator
dari push button.

4. Regulator Voltase
Rangkaian ini berguna untuk menurunkan tegangan batere yang dibutuhkan untuk
mikrokontroler dan rangkaian sensor. Dikarenakan tegangan batere lebih dari 5V,
sedangkan tegangan yang dibutuhkan mikrokontroler dan sensor 5V. Dalam hal ini
digunakan regulator LM2576 yang mempunyai kapasitas arus 3A.

Berikut keseluruhan dari rangkaian elektronika.

Endang Rusiana >> wangready@yahoo.com


Januari 2012

Page 4

C. Algoritma & Pemrograman


Algoritma kontrol yang digunakan yaitu PID. Sensor yang dibaca dikonversi kedalam
angka-angka yang akan menjadi input PID. Di PID data diolah sehingga mempunyai
output berupa PWM (pulse width modulation) yang akan mengatur kecepatan motor
sebagai responnya terhadap garis. Berikut persamaan PID dalam bentuk matematis.

Kp: Proportional gain, a tuning parameter


Ki: Integral gain, a tuning parameter
Kd: Derivative gain, a tuning parameter
e: Error = SP PV
t: Time or instantaneous time (the present)
Berikut pseudo code dari persamaan di atas.
previous_error = setpoint - process_feedback
integral = 0
start:
Endang Rusiana >> wangready@yahoo.com
Januari 2012

Page 5

wait(dt)
error = setpoint - process_feedback
integral = integral + (error*dt)
derivative = (error - previous_error)/dt
output = (Kp*error) + (Ki*integral) + (Kd*derivative)
previous_error = error
goto start

Berikut kode utama yang saya buat dengan menggunakan WinAVR+AVR Studio 4
dengan bahasa C.
#include
#include
#include
#include
#include
#include
#include
#include

<avr/io.h>
<avr/pgmspace.h>
<util/delay.h>
"lcd_lib.h"
<stdio.h>
//untuk sprintf
<stdlib.h> //untuk rand
<avr/eeprom.h>
"wangready_tone_lib.h"

#define ADC_VREF_TYPE 0x40


// Read the AD conversion result
unsigned int read_adc(unsigned char adc_input)
{
ADMUX=adc_input | (ADC_VREF_TYPE & 0xff);
// Delay needed for the stabilization of the ADC input voltage
_delay_us(10);
// Start the AD conversion
ADCSRA|=0x40;
// Wait for the AD conversion to complete
while ((ADCSRA & 0x10)==0);
ADCSRA|=0x10;
return ADCW;
}
#define RPWM OCR1A
#define LPWM OCR1B
uint8_t buff[33];
void nada_enter()
{
nada_c1(32);
nada_f1(32);
nada_a1(8);
}
void nada_cancel()
{
nada_a1(32);
nada_f1(32);
nada_c1(8);
}
void nada_plus()
{
Endang Rusiana >> wangready@yahoo.com
Januari 2012

Page 6

nada_c1(8);
}
void nada_minus()
{
nada_g1(8);
}
void music()
{
//8d1 8- 8d1 8- 16g1 16- 16g1 16- 16#f1 16- 8d1 8- 8d1 8- 8d1 8d1
nada_d1(8);
jeda(8);
nada_d1(8);
jeda(8);
nada_g1(16);
jeda(16);
nada_g1(16);
jeda(16);
nada_f1_kres(16);
jeda(16);
nada_d1(8);
jeda(8);
nada_d1(8);
jeda(8);
nada_d1(8);
nada_d1(8);
}
unsigned char get_button(unsigned char select)
{
switch(select)
{
case 1:
if((PINB&0b00001000)==0)
{
nada_enter();
return(1); //OK
}
else return(0);
break;
case 2:
if((PINB&0b00000100)==0)
{
nada_plus();
return(1); // +
}
else return(0);
break;
case 3:
if((PINB&0b00000010)==0)
{
nada_minus();
return(1); // }
else return(0);
break;
case 4:
if((PINB&0b00000001)==0)
{
Endang Rusiana >> wangready@yahoo.com
Januari 2012

Page 7

nada_cancel();
return(1); //cancel
}
else return(0);
break;
}
}
// additional custom LCD characters
const uint8_t panah_kanan[8] PROGMEM=
{
0b00000000,//back slash
0b00011000,
0b00011110,
0b00011111,
0b00011110,
0b00011000,
0b00000000,
0b00000000
};
const uint8_t panah_kiri[8] PROGMEM=
{
0b00000000,//back slash
0b00000011,
0b00001111,
0b00011111,
0b00001111,
0b00000011,
0b00000000,
0b00000000
};
const uint8_t blank[8] PROGMEM=
{
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000
};
float EEMEM var_Kp;
float EEMEM var_Ki;
float EEMEM var_Kd;
unsigned int EEMEM var_Ts ;
unsigned char EEMEM var_max_speed;
float Kp;
float Ki;
float Kd;
unsigned int Ts;
unsigned char max_speed;
Endang Rusiana >> wangready@yahoo.com
Januari 2012

Page 8

#define pnh_kiri_char 1
#define pnh_kanan_char 2
void init_char()
{
LCDdefinechar(blank,0);
LCDdefinechar(panah_kiri,1);
LCDdefinechar(panah_kanan,2);
}
void disp_max_speed()
{
LCDclr();//clears LCD
LCDGotoXY(0,0);
LCDsendChar(pnh_kiri_char);
LCDGotoXY(15,0);
LCDsendChar(pnh_kanan_char);
LCDGotoXY(0,1);
LCDsendChar('-');
LCDGotoXY(15,1);
LCDsendChar('+');
LCDGotoXY(2,0);
sprintf(buff,"Set Maxspeed");
LCDstring(buff,12);
_delay_ms(300);
if(get_button(1) == 1)//jika OK
{
while(get_button(4)==0)
{
if(get_button(2)==1)max_speed += 5;
if(get_button(3)==1)max_speed -= 5; //-

//+

LCDclr();//clears LCD
LCDGotoXY(1,1);
sprintf(buff,"Max Speed=%d", max_speed);
LCDstring(buff,13);
_delay_ms(1);
}
eeprom_write_byte(&var_max_speed,max_speed);
}
}
void disp_Kp()
{
LCDclr();//clears LCD
LCDGotoXY(15,0);
LCDsendChar(pnh_kanan_char);

Endang Rusiana >> wangready@yahoo.com


Januari 2012

Page 9

LCDGotoXY(0,1);
LCDsendChar('-');
LCDGotoXY(15,1);
LCDsendChar('+');
LCDGotoXY(4,0);
sprintf(buff,"Set Kp");
LCDstring(buff,6);
_delay_ms(300);
if(get_button(1) == 1)//jika OK
{
while(get_button(4)==0)
{
if(get_button(2)==1)Kp += 1;
if(get_button(3)==1)Kp -= 1;

//+
//-

LCDclr();//clears LCD
LCDGotoXY(4,1);
sprintf(buff,"Kp=%2.2f", Kp);
LCDstring(buff,8);
_delay_ms(1);
}
eeprom_write_float(&var_Kp,Kp);
}
}
void disp_Ki()
{
LCDclr();//clears LCD
LCDGotoXY(0,0);
LCDsendChar(pnh_kiri_char);
LCDGotoXY(15,0);
LCDsendChar(pnh_kanan_char);
LCDGotoXY(0,1);
LCDsendChar('-');
LCDGotoXY(15,1);
LCDsendChar('+');
LCDGotoXY(4,0);
sprintf(buff,"Set Ki");
LCDstring(buff,6);
_delay_ms(300);
if(get_button(1) == 1)//jika OK
{
while(get_button(4)==0)
{
if(get_button(2)==1)Ki += 0.1;
if(get_button(3)==1)Ki -= 0.1;

//+
//-

Endang Rusiana >> wangready@yahoo.com


Januari 2012

Page 10

LCDclr();//clears LCD
LCDGotoXY(4,1);
sprintf(buff,"Ki=%2.2f", Ki);
LCDstring(buff,8);
_delay_ms(1);
}
eeprom_write_float(&var_Ki,Ki);
}
}
void disp_Kd()
{
LCDclr();//clears LCD
LCDGotoXY(0,0);
LCDsendChar(pnh_kiri_char);
LCDGotoXY(15,0);
LCDsendChar(pnh_kanan_char);
LCDGotoXY(0,1);
LCDsendChar('-');
LCDGotoXY(15,1);
LCDsendChar('+');
LCDGotoXY(4,0);
sprintf(buff,"Set Kd");
LCDstring(buff,6);
_delay_ms(300);
if(get_button(1) == 1)//jika OK
{
while(get_button(4)==0)
{
if(get_button(2)==1)Kd += 0.1;
if(get_button(3)==1)Kd -= 0.1;

//+
//-

LCDclr();//clears LCD
LCDGotoXY(4,1);
sprintf(buff,"Kd=%2.2f", Kd);
LCDstring(buff,8);
_delay_ms(1);
}
eeprom_write_float(&var_Kd,Kd);
}
}
void disp_Ts()
{
LCDclr();//clears LCD
LCDGotoXY(0,0);
LCDsendChar(pnh_kiri_char);
LCDGotoXY(15,0);
Endang Rusiana >> wangready@yahoo.com
Januari 2012

Page 11

LCDsendChar(pnh_kanan_char);
LCDGotoXY(0,1);
LCDsendChar('-');
LCDGotoXY(15,1);
LCDsendChar('+');
LCDGotoXY(4,0);
sprintf(buff,"Set Ts");
LCDstring(buff,6);
_delay_ms(300);
if(get_button(1) == 1)//jika OK
{
while(get_button(4)==0)
{
if(get_button(2)==1)Ts++;
if(get_button(3)==1)Ts--;

//+
//-

LCDclr();//clears LCD
LCDGotoXY(4,1);
sprintf(buff,"Ts=%ums", Ts);
LCDstring(buff,8);
_delay_ms(1);
}
eeprom_write_word((void *)&var_Ts,Ts);
}
}
unsigned int sens[8];
unsigned int treshold = 200;
unsigned char warna_garis;
unsigned int EEMEM var_sens[8];
unsigned char EEMEM var_warna_garis;
unsigned int compare_var_uint_high(unsigned int A, unsigned int B)
{
if(A>=B)return(A);
else if(B>A)return(B);
}
unsigned int compare_var_uint_low(unsigned int A, unsigned int B)
{
if(A<=B)return(A);
else if(B<A)return(B);
}
void auto_calibrate()
{
unsigned char i;
LCDclr();//clears LCD
LCDGotoXY(0,0);
Endang Rusiana >> wangready@yahoo.com
Januari 2012

Page 12

LCDsendChar(pnh_kiri_char);
LCDGotoXY(15,0);
LCDsendChar(pnh_kanan_char);
LCDGotoXY(0,1);
LCDsendChar('-');
LCDGotoXY(15,1);
LCDsendChar('+');
LCDGotoXY(1,0);
sprintf(buff,"Autocalibrate");
LCDstring(buff,13);
_delay_ms(300);
if(get_button(1) == 1)//jika OK
{
LCDclr();
LCDGotoXY(0,0);
sprintf(buff,"Tekan 'Cancel'");
LCDstring(buff,33);
LCDGotoXY(0,1);
sprintf(buff,"untuk mengakhiri");
LCDstring(buff,33);
for(i=0;i<8;i++)
{
sens[i] = 500;
}
if(warna_garis == 1)//garis putih adc kecil
{
while(get_button(4)==0)
{
for(i=0;i<8;i++)
{
sens[i] =
compare_var_uint_low(sens[i],read_adc(i));
eeprom_write_word(&var_sens[i],sens[i]);
}
}
for(i=0;i<8;i++)
{
sens[i] += treshold;
eeprom_write_word(&var_sens[i],sens[i]);
}
}
else if(warna_garis == 0)//garis hitam adc besar
{
while(get_button(4)==0)
{
for(i=0;i<8;i++)
{
sens[i] =
compare_var_uint_high(sens[i],read_adc(i));
eeprom_write_word(&var_sens[i],sens[i]);
Endang Rusiana >> wangready@yahoo.com
Januari 2012

Page 13

}
}
for(i=0;i<8;i++)
{
sens[i] -= treshold;
eeprom_write_word(&var_sens[i],sens[i]);
}
}
}
}
void tipe_garis()
{
LCDclr();//clears LCD
LCDGotoXY(0,0);
LCDsendChar(pnh_kiri_char);
LCDGotoXY(15,0);
LCDsendChar(pnh_kanan_char);
LCDGotoXY(0,1);
LCDsendChar('-');
LCDGotoXY(15,1);
LCDsendChar('+');
LCDGotoXY(2,0);
sprintf(buff,"Tipe Garis");
LCDstring(buff,10);
_delay_ms(300);
if(get_button(1) == 1)//jika OK
{
while(get_button(4)==0)
{
if(get_button(2)==1)warna_garis = 1;
if(get_button(3)==1)warna_garis
= 0;

//+
//-

LCDclr();//clears LCD
if(warna_garis == 0)
{
LCDGotoXY(4,1);
sprintf(buff,"Hitam");
LCDstring(buff,5);
}
else if(warna_garis == 1)
{
LCDGotoXY(4,1);
sprintf(buff,"Putih");
LCDstring(buff,5);
}

//hitam

//putih

_delay_ms(300);
}
eeprom_write_byte(&var_warna_garis,warna_garis);
Endang Rusiana >> wangready@yahoo.com
Januari 2012

Page 14

}
}
unsigned char sensor(unsigned char urut)
{
if(warna_garis == 0) //hitam adc besar
{
if(read_adc(urut) > sens[urut])return(1);
else return(0);
}
else if(warna_garis == 1)//putih adc kecil
{
if(read_adc(urut) < sens[urut])return(1);
else return(0);
}
}
void cek_sensor()
{
unsigned char i,buff_sens;
LCDclr();//clears LCD
LCDGotoXY(0,0);
LCDsendChar(pnh_kiri_char);
LCDGotoXY(15,0);
LCDsendChar(pnh_kanan_char);
LCDGotoXY(0,1);
LCDsendChar('-');
LCDGotoXY(15,1);
LCDsendChar('+');
LCDGotoXY(2,0);
sprintf(buff,"Cek Sensor");
LCDstring(buff,10);
_delay_ms(300);
if(get_button(1) == 1)//jika OK
{
while(get_button(4)==0)
{
LCDclr();
for(i=0;i<8;i++)
{
LCDGotoXY((7-i), 1);
if(sensor(i))
{
LCDsendChar('1');
}else
{
LCDsendChar('0');
}
}
Endang Rusiana >> wangready@yahoo.com
Januari 2012

Page 15

_delay_ms(300);
}
}
}
void menu()
{
unsigned char count_menu=0,i;
akhir:
LCDclr();//clears LCD
LCDGotoXY(5,0);
sprintf(buff,"Z-Jet");
LCDstring(buff,6);
LCDGotoXY(3,1);
sprintf(buff,"System-On");
LCDstring(buff,9);
music();
LCDclr();//clears LCD
LCDGotoXY(5,0);
sprintf(buff,"Run!!!");
LCDstring(buff,6);
for(i=0;i<8;i++)
{
LCDGotoXY(i,1);
LCDsendChar(pnh_kiri_char);
}
for(i=8;i<16;i++)
{
LCDGotoXY(i,1);
LCDsendChar(pnh_kanan_char);
}
if(get_button(1) == 1)//jika OK
{
while(1)
{
if((get_button(2) == 1) && (count_menu <
8))count_menu++;
if((get_button(3) == 1) && (count_menu >
0))count_menu--;
switch(count_menu)
{
case 0:
disp_Kp();
break;
case 1:
disp_Ki();
Endang Rusiana >> wangready@yahoo.com
Januari 2012

Page 16

break;
case 2:
disp_Kd();
break;
case 3:
disp_Ts();
break;
case 4:
disp_max_speed();
break;
case 5:
auto_calibrate();
break;
case 6:
tipe_garis();
break;
case 7:
cek_sensor();
break;
case 8: LCDclr();//clears LCD
LCDGotoXY(0,0);
LCDsendChar(pnh_kiri_char);\
LCDGotoXY(0,1);
LCDsendChar('-');
LCDGotoXY(15,1);
LCDsendChar('+');
LCDGotoXY(4,0);
sprintf(buff,"Start");
LCDstring(buff,5);
if(get_button(1) == 1)goto akhir;
_delay_ms(300);
break;
}
}
}
}
void init_var()
{
unsigned char i;
max_speed
= eeprom_read_byte(&var_max_speed);
Kp
= eeprom_read_float(&var_Kp);
Ki
= eeprom_read_float(&var_Ki);
Kd
= eeprom_read_float(&var_Kd);
Ts
= eeprom_read_word(&var_Ts);
for(i=0;i<8;i++)sens[i] = eeprom_read_word(&var_sens[i]);
warna_garis = eeprom_read_byte(&var_warna_garis);
}
int last_sens;
int _SP()
{
//sensor dari kanan ke kiri
//1 0 0 0 0 = -4
//1 1 0 0 0 = -3
Endang Rusiana >> wangready@yahoo.com
Januari 2012

Page 17

//0
//0
//0
//0
//0
//0
//0

1
1
0
0
0
0
0

0
1
1
1
0
0
0

0
0
0
1
1
1
0

0
0
0
0
0
1
1

=
=
=
=
=
=
=

-2
-1
0
1
2
3
4

if((sensor(0)==1)&&(sensor(1)==0)&&(sensor(2)==0)&&(sensor(3)==0)
&&(sensor(4)==0)){last_sens = -4; return(-4);}
else
if((sensor(0)==1)&&(sensor(1)==1)&&(sensor(2)==0)&&(sensor(3)==0)
&&(sensor(4)==0))return(-3);
else
if((sensor(0)==0)&&(sensor(1)==1)&&(sensor(2)==0)&&(sensor(3)==0)
&&(sensor(4)==0))return(-2);
else
if((sensor(0)==0)&&(sensor(1)==1)&&(sensor(2)==1)&&(sensor(3)==0)
&&(sensor(4)==0))return(-1);
else
if((sensor(0)==0)&&(sensor(1)==0)&&(sensor(2)==1)&&(sensor(3)==0)
&&(sensor(4)==0))return(0);
else
if((sensor(0)==0)&&(sensor(1)==0)&&(sensor(2)==1)&&(sensor(3)==1)
&&(sensor(4)==0))return(1);
else
if((sensor(0)==0)&&(sensor(1)==0)&&(sensor(2)==0)&&(sensor(3)==1)
&&(sensor(4)==0))return(2);
else
if((sensor(0)==0)&&(sensor(1)==0)&&(sensor(2)==0)&&(sensor(3)==1)
&&(sensor(4)==1))return(3);
else
if((sensor(0)==0)&&(sensor(1)==0)&&(sensor(2)==0)&&(sensor(3)==0)
&&(sensor(4)==1)){last_sens = 4; return(4);}
else return(last_sens);
}
int last_SP;
float P,I,D;
void PID()
{
float PID;
int speed_kanan, speed_kiri;
while(get_button(4)==0)//cancel
{
P = _SP();
I += _SP();
D = _SP() - last_SP;
PID = (Kp * (float)P) + (Ki * (float)I) + (Kd * (float)D);
last_SP = _SP();
_delay_ms((double)Ts);
speed_kanan = (int)max_speed + (int)PID;
Endang Rusiana >> wangready@yahoo.com
Januari 2012

Page 18

speed_kiri

= (int)max_speed - (int)PID;

if

(speed_kanan > max_speed)speed_kanan =

max_speed;
else if
(max_speed));
if
else if

(speed_kanan < (-(max_speed)))speed_kanan = ((speed_kiri > max_speed)speed_kiri = max_speed;


(speed_kiri < (-(max_speed)))(-(max_speed));

if(speed_kanan>=0)
{
RPWM = (unsigned char)speed_kanan;
PORTD = 0b00000000;
}
else
{
PORTD = 0b00001000;
RPWM = 255 + (unsigned char)speed_kanan;
}
if(speed_kiri>=0)
{
LPWM = (unsigned char)speed_kiri;
PORTD += 0b00000000;
}
else
{
PORTD += 0b00000100;
LPWM = 255 + (unsigned char)speed_kiri;
}
//LCDGotoXY(0,0);
//sprintf(buff,"%d=%d",(unsigned char)speed_kiri,(unsigned
char)speed_kanan);
//LCDstring(buff,16);
}
RPWM = 0;
LPWM = 0;
}
int main(void)
{
PORTB
= 0xFF;
DDRD = 0xFF;
//
//
//
//
//
//
//

Timer/Counter 1 initialization
Clock source: System Clock
Clock value: 15.625 kHz
Mode: Ph. correct PWM top=0x00FF
OC1A output: Non-Inv.
OC1B output: Non-Inv.
Noise Canceler: Off

Endang Rusiana >> wangready@yahoo.com


Januari 2012

Page 19

// Input Capture on Falling Edge


// Timer1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=0xA1;
TCCR1B=0x05;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;
// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
SFIOR=0x00;
// ADC initialization
// ADC Clock frequency: 1000.000 kHz
// ADC Voltage Reference: AVCC pin
ADMUX=ADC_VREF_TYPE & 0xff;
ADCSRA=0x84;
tone_wr_init();
LCDinit();//init LCD bit, dual line, cursor right
LCDcursorOFF();
init_char();
init_var();
while(1)
{
menu();
PID();
}
return 0;
}

Endang Rusiana >> wangready@yahoo.com


Januari 2012

Page 20

Daftar Pustaka
http://en.wikipedia.org/wiki/PID_controller
http://insansainsprojects.wordpress.com/2008/06/05/h-bridge-driver-kontrolarah-motor/
http://www.societyofrobots.com/mechanics_gears.shtml
Line Tracker Robot using AVR Microcontroller Created by Hendawan
Soebhakti on Desember 2007
http://wangready.wordpress.com

Endang Rusiana >> wangready@yahoo.com


Januari 2012

Page 21