phnx etche
semua yang ku tahu ku tulis disini
Rabu, 27 Oktober 2010
photo dioda
Dioda peka cahaya adalah jenis dioda yang berfungsi mendektesi cahaya. Berbeda dengan dioda biasa, komponen elektronika ini akan mengubah menjadi arus listrik. Cahaya yang dapat dideteksi oleh dioda peka cahaya ini mulai dari cahaya inframerah, cahaya tampak, ultra ungu sampai dengan sinar-X. Aplikasi dioda peka cahaya mulai dari penghitung kendaraan di jalan umum secara otomatis, pengukur cahaya pada kamera serta beberapa peralatan dibidang medis.
Alat yang mirip dengan dioda peka adalah transistor foto (phototransistor). Transistor foto ini pada dasarnya adalah jenis transistor bipolar yang menggunakan kontak (junction) base- collector untuk menerima cahaya.
Komponen ini mempunyai sensitivitas yang lebih baik jika dibandingkan dengan dioda peka cahaya. Hal ini disebabkan karena electron yang ditimbulkan oleh foton cahaya pada junction ini diinjeksikan di bagian Base dan diperkuat di bagian kolektornya. Namun demikian, waktu respons dari transistor foto secara umum akan lebih lambat dari pada dioda peka cahaya.
line follower
Pada project kali ini kita akan membahas cara membuat robot line tracker yang dapat bergerak mengikuti track berupa garis hitam setebal ± 2 cm. Garis hitam tersebut disusun membentuk sejumlah persimpangan-persimpangan. Robot diprogram untuk dapat menghitung jumlah persimpangan yang sudah dilaluinya, kemudian belok sesuai dengan arah yang diinginkan. Untuk membaca garis, robot dilengkapi dengan sensor proximity yang dapat membedakan antara garis hitam dengan lantai putih. Sensor proximity ini dapat dikalibrasi untuk menyesuaikan pembacaan sensor terhadap kondisi pencahayaan ruangan. Sehingga pembacaan sensor selalu akurat.
Agar pergerakan robot menjadi lebih halus, maka kecepatan robot diatur sesuai dengan kondisi pembacaan sensor proximity. Jika posisi robot menyimpang dari garis, maka robot akan melambat. Namun jika robot tepat berada diatas garis, maka robot akan bergerak cepat. Robot juga dapat kembali ke garis pada saat robot terlepas sama sekali dari garis. Hal ini bisa dilakukan karena robot selalu mengingat kondisi terakhir pembacaan sensor. Jika terakhir kondisinya adalah disebelah kiri garis, maka robot akan bergerak ke kanan, demikian pula sebaliknya.
Gambar 1. Robot Line Tracker
Sensor Proximity
Sensor proximity bisa kita buat sendiri. Prinsip kerjanya sederhana, hanya memanfaatkan sifat cahaya yang akan dipantulkan jika mengenai benda berwarna terang dan
akan diserap jika mengenai benda berwarna gelap. Sebagai sumber cahaya kita gunakan LED (Light Emiting Diode) yang akan memancarkan cahaya merah. Dan untuk menangkap pantulan cahaya LED, kita gunakan photodiode. Jika sensor berada diatas garis hitam maka photodioda akan menerima sedikit sekali cahaya pantulan. Tetapi jika sensor berada diatas garis putih maka photodioda akan menerima banyak cahaya pantulan. Berikut adalah ilustrasinya :
Gambar 2. Prinsip Kerja Sensor Proximity
Gambar Photodioda
Sifat dari photodioda adalah jika semakin banyak cahaya yang diterima, maka nilai resistansi diodanya semakin kecil. Dengan melakukan sedikit modifikasi, maka besaran resistansi tersebut dapat diubah menjadi tegangan. Sehingga jika sensor berada diatas garis hitam, maka tegangan keluaran sensor akan kecil, demikian pula sebaliknya. Berikut adalah gambar rangkaian sensor proximity yang digunakan pada robot ini :
Gambar LM339N (IC comparator)
Gambar 3. Rangkaian Sensor Proximity
Agar dapat dibaca oleh mikrokontroler, maka tegangan sensor harus disesuaikan dengan level tegangan TTL yaitu 0 – 1 volt untuk logika 0 dan 3 – 5 volt untuk logika 1. Hal ini bisa dilakukan dengan memasang operational amplifier yang difungsikan sebagai komparator. Output dari photodiode yang masuk ke input inverting op-amp akan dibandingkan dengan tegangan tertentu dari variable resistor VR. Tegangan dari VR inilah yang kita atur agar sensor proximity dapat menyesuaikan dengan kondisi cahaya ruangan.
Gambar 4. Posisi Pemasangan Sensor Proximity Pada Robot
Sensor proximity terdiri dari 6 pasang LED dan photodiode yang disusun sedemikian rupa sehingga jarak antara satu sensor dengan yang lainnya lebih kecil dari lebar garis hitam. Perhatikan gambar berikut :
Gambar 5. Jarak Antar Sensor Proximity
Rancangan Mekanik Robot
Gambar 6. Mekanik Robot
Algoritma Pergerakan Robot
Sebelum membuat program, maka kita perlu mendefinisikan seluruh kemungkinan pembacaan sensor proximity. Dengan demikian kita dapat menentukan pergerakan robot yang tujuannya adalah menjaga agar robot selalu berada tepat diatas garis. Berikut adalah beberapa kemungkinan pembacaan garis oleh sensor proximity :
Gambar 7. Kemungkinan Posisi Sensor Proximity Pada Line
Setelah mengetahui kemungkinan-kemungkinan posisi sensor, maka selanjutnya harus
didefinisikan aksi dari setiap kondisi tersebut. Perhatikan tabel berikut ini :
Tabel 1. Aksi Pergerakan Robot
Lapangan Uji Coba
Lapangan berupa garis-garis hitam diatas lantai berwarna putih. Garis hitam disusun
membentuk banyak persimpangan. Ukuran tiap kotak adalah 30 cm x 30 cm. Ketebalan garis hitam
adalah 3 cm. Garis hitam ini bisa dibuat menggunakan isolasi hitam kemudian ditempel pada lantai
atau kertas karton berwarna putih.
Gambar 8. Lapangan Uji Coba
Driver Motor DC
Untuk menggerakkan dua buah motor dc, digunakan IC H-Bridge Motor Driver L298, yang mampu memberikan arus maksimum sebesar 1A ke tiap motor. Input L298 ada 6 jalur, terdiri dari input data arah pergerakan motor dan input untuk PWM (Pulse Width Modulation). Untuk mengatur kecepatan motor, pada input PWM inilah akan diberikan lebar pulsa yang bervariasi dari mikrokontroler.
Gambar L298 (Driver Motor)
Gambar 10. Rangkaian Driver Motor DC
Untuk menentukan arah pergerakan motor maka pada input L298 harus diberikan kondisi
sesuai dengan tabel berikut :
Tabel 2. Tabel Kebenaran Driver Motor
AVR Microcontroller
Sebagai ”otak” robot digunakan mikrokontroler AVR jenis ATmega8535 yang akan membaca
data dari sensor proximity, mengolahnya, kemudian memutuskan arah pergerakan robot.
Gambar 11. Mikrokontroler ATmega8535
Pada robot line track ini, keluaran sensor proximity dihubungkan ke PortD.0 dan PortD.5 pada mikrokontroler. Sedangkan driver motor dihubungkan ke PortC.0 s/d PortC.5 seperti terlihat pada gambar berikut :
Gambar 12. Mikrokontroler ATmega8535
Membuat Source Code
Source code secara lengkap dapat dilihat pada Lampiran A. Source code dibuat dengan
menggunakan software CodeVisionAVR dengan langkah-langkah sebagai berikut :
1. Jalankan CodeVisionAVR, kemudian klik File -> New, Pilih Project
2. “Do you want to use the CodeWizardAVR?” Klik Yes
3. Pilih Chip yang digunakan, chip : ATmega8535L, clock : 4.000000 MHz
4. Lakukan setting sebagai berikut :
Port : Port B sebagai Output dan Port A sebagai Input Pullup
Timers : Timer 0 dengan Clock Value 10,800 KHz, aktifkan Overflow Interrupt
5. Klik File -> Generate, Save and Exit
6. Buatlah source code seperti pada Lampiran A.
7. Setelah selesai membuat source code, klik Setting -> Programmer
8. Pilih AVR Chip Programmer Type : Kanda System STK200+/300 dan pilih Printer Port pada
LPT1 : 378h
9. Klik Project -> Configure, kemudian pilih menu After Make dan aktifkan Program the Chip. Klik OK jika sudah.
PERHATIAN ! Jangan mengubah setting apapun pada menu ini. Jika salah memilih,
chip Anda tidak bisa digunakan lagi !!
10. Untuk meng-compile project, klik Project -> Make
11. Jika tidak ada error maka file siap didownload ke chip. Pastikan koneksi kabel downloader
dan chip sudah terpasang dengan benar.
12. Nyalakan power supply dan klik Program. Tunggu hingga proses download selesai.
Penjelasan Source Code
Berikut adalah penjelasan tiap bagian dari source code.
1. Membuat definisi port yang digunakan sebagai berikut :
#define SkiXX PINA.0 // Sensor kiri terluar
#define SkiX PINA.1 // Sensor kiri luar
#define Ski PINA.2 // Sensor kiri tengah
#define Ska PINA.3 // Sensor kanan tengah
#define SkaX PINA.4 // Sensor kanan luar
#define SkaXX PINA.5 // Sensor kanan terluar
#define EnKi PORTB.1 // Enable L298 untuk motor kiri
#define dirA_Ki PORTB.2 // Direction A untuk motor kiri
#define dirB_Ki PORTB.3 // Direction B untuk motor kiri
#define EnKa PORTB.0 // Enable L298 untuk motor kanan
#define dirC_Ka PORTB.4 // Direction C untuk motor kanan
#define dirD_Ka PORTB.5 // Direction D untuk motor kanan
2. Menentukan library yang digunakan :
#include // Library untuk chip ATmega8535
#include // Library delay
3. Membuat variable sebagai pengingat kondisi pembacaan sensor line terakhir.
bit x;
4. Membuat ISR Timer 0 / Interrupt Service Routine Timer 0.
ISR ini digunakan untuk menghasilkan pulsa PWM untuk mengendalikan motor kiri dan kanan melalui bit EnKi dan EnKa.
ISR Timer 0 dieksekusi secara periodik ketika Timer 0 overflow. Lamanya tergantung nilai Timer/Counter 0 (TCNT0).
Periode pulsa ditentukan oleh TCNT0. Nilai maksimumnya 0xFF atau 255d.
Duty cycle PWM untuk motor kiri ditentukan oleh nilai lpwm. Maksimum 255.
Duty cycle PWM untuk motor kanan ditentukan oleh nilai rpwm. Maksimum 255.
unsigned char xcount,lpwm,rpwm; // Definisi variable
// Timer 0 overflow interrupt service routine
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
// Place your code here
xcount++; // xcount=xcount+1
if(xcount<=lpwm)EnKi=1; // EnKi=1 jika xcount <= lpwm else EnKi=0; // EnKi=0 jika xcount > lpwm
if(xcount<=rpwm)EnKa=1; // EnKa=1 jika xcount <= rpwm else EnKa=0; // EnKa=0 jika xcount > rpwm
TCNT0=0xFF; // Timer0 Value Menentukan periode pulsa PWM
}
5. Membuat sub rutin agar robot bergerak maju
void maju()
{
dirA_Ki=1;dirB_Ki=0; // Motor kiri maju
dirC_Ka=1;dirD_Ka=0; // Motor kanan maju
}
6. Membuat sub rutin agar robot belok ke kiri
void belok_kiri()
{
unsigned int i;
lpwm=50; rpwm=50; // Kecepatan pelan
delay_ms(60); // Robot dimajukan sedikit
dirA_Ki=0;dirB_Ki=1; // Motor kiri mundur
dirC_Ka=1;dirD_Ka=0; // Motor kanan maju
for(i=0;i<=1000;i++) while (!SkiXX ||!SkiX) {}; for(i=0;i<=1000;i++) while ( SkiXX || SkiX) {}; lpwm=0; rpwm=0; // Robot berhenti } Pada program diatas, tampak ada 2 “for while” yang masing-masing diulang 1000 kali untuk memastikan bahwa sensor benar-benar membaca sebuah garis, bukan noda atau kotoran yang ada di lapangan. for(i=0;i<=1000;i++) while (!SkiXX ||!SkiX) {}; Robot akan terus belok kiri selama sensor SkiXX=0 atau SkiX=0 (sensor berada diatas garis hitam) for(i=0;i<=1000;i++) while ( SkiXX || SkiX) {}; Selanjutnya robot tetap belok kiri selama sensor SkiXX=1 atau SkiX=1 (sensor berada diatas permukaan putih). 7. Membuat sub rutin agar robot belok ke kanan void belok_kanan() { unsigned int i; lpwm=50; rpwm=50; // Kecepatan pelan delay_ms(60); // Robot dimajukan sedikit dirA_Ki=1;dirB_Ki=0; // Motor kiri maju dirC_Ka=0;dirD_Ka=1; // Motor kanan mundur for(i=0;i<=1000;i++) while (!SkaXX ||!SkaX) {}; for(i=0;i<=1000;i++) while ( SkaXX || SkaX) {}; lpwm=0; rpwm=0; // Robot berhenti } 8. Membuat sub rutin membaca line unsigned char sensor; void scan_rule1() { maju(); // Robot bergerak maju sensor=PIND; // PIND diberi nama sensor sensor&=0b00111111; // sensor di-AND-kan dengan 0b00111111 switch(sensor) { case 0b00111110: rpwm=0; lpwm=200; x=1; break; case 0b00111100: rpwm=50; lpwm=200; x=1; break; case 0b00111101: rpwm=75; lpwm=200; x=1; break; case 0b00111001: rpwm=100; lpwm=200; x=1; break; case 0b00111011: rpwm=150; lpwm=200; x=1; break; case 0b00110011: rpwm=200; lpwm=200; break; case 0b00110111: rpwm=200; lpwm=150; x=0; break; case 0b00100111: rpwm=200; lpwm=100; x=0; break; case 0b00101111: rpwm=200; lpwm=75; x=0; break; case 0b00001111: rpwm=200; lpwm=50; x=0; break; case 0b00011111: rpwm=200; lpwm=0; x=0; break; case 0b00111111: break; if(x) {lpwm=50; rpwm=0; break;} else {lpwm=0; rpwm=50; break;} } } Variabel x ini berfungsi sebagai pengingat posisi terakhir robot terhadap garis. Jika robot berada di kanan garis, maka x=0. Jika robot berada di kiri garis, maka x=1. Ketika robot lepas dari track, maka program akan membaca kondisi variable x, sehingga dapat ditentukan arah gerak robot agar robot dapat kembali ke garis, seperti terlihat pada instruksi berikut : if(x) {lpwm=50; rpwm=0; break;} else {lpwm=0; rpwm=50; break;} Jika x=1 maka robot belok kanan, jika x=0 maka robot belok kiri. 9. Membuat sub rutin membaca persimpangan void scan_count(unsigned char count) { unsigned int i; unsigned char xx=0; while(xx
#include
#define enka PORTB.0 // Enable L298 untuk motor kiri
#define enki PORTB.1 // Direction A untuk motor kiri
#define dirA PORTB.2 // Direction B untuk motor kiri
#define dirB PORTB.3 // Enable L298 untuk motor kanan
#define dirC PORTB.4 // Direction C untuk motor kanan
#define dirD PORTB.5 // Direction D untuk motor kanan
#define skaxx PINA.0
#define skax PINA.1
#define ska PINA.2
#define ski PINA.3
#define skix PINA.4
#define skixx PINA.5
bit x;
unsigned char Y=0,rpwm,lpwm;
// Timer 0 overflow interrupt service routine
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
// Place your code here
Y++;
if(Y<=rpwm)enka=1; else enka=0; if(Y<=lpwm)enki=1; else enki=0; TCNT0=0xFF; } void maju() { //enka=1;enki=1; dirA=1;dirB=0; dirC=1;dirD=0; } unsigned char sensor; void scan_line() { maju(); // Robot bergerak maju sensor=PINA; // PINA diberi nama sensor sensor&=0b11111111; // sensor di-AND-kan dengan 0b01111110 switch(sensor) { case 0b11111110: lpwm=30; rpwm=100; x=1; break; case 0b11111100: lpwm=40; rpwm=100; x=1; break; case 0b11111101: lpwm=50; rpwm=100; x=1; break; case 0b11111001: lpwm=60; rpwm=90; x=1; break; case 0b11111011: lpwm=80; rpwm=90; x=1; break; case 0b11110011: lpwm=100; rpwm=100; break; //tngh case 0b11110111: lpwm=90; rpwm=80; x=0; break; case 0b11100111: lpwm=90; rpwm=60; x=0; break; case 0b11101111: lpwm=100; rpwm=50; x=0; break; case 0b11001111: lpwm=100; rpwm=40; x=0; break; case 0b11011111: lpwm=100; rpwm=30; x=0; break; case 0b11111111: break; if(x==0) { lpwm=255; rpwm=0; break; } else if (x==1) { lpwm=0; rpwm=255; break; } } } // Declare your global variables here void main(void) { // Declare your local variables here // Input/Output Ports initialization // Port A initialization // Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In // State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T PORTA=0x00; DDRA=0x00; // Port B initialization // Func7=Out Func6=Out Func5=Out Func4=Out Func3=Out Func2=Out Func1=Out Func0=Out // State7=0 State6=0 State5=0 State4=0 State3=0 State2=0 State1=0 State0=0 PORTB=0x00; DDRB=0xFF; // Port C initialization // Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In // State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T PORTC=0x00; DDRC=0x00; // Port D initialization // Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In // State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T PORTD=0x00; DDRD=0x00; // Timer/Counter 0 initialization // Clock source: System Clock // Clock value: 500.000 kHz // Mode: Normal top=FFh // OC0 output: Disconnected TCCR0=0x02; TCNT0=0x00; OCR0=0x00; // Timer/Counter 1 initialization // Clock source: System Clock // Clock value: Timer 1 Stopped // Mode: Normal top=FFFFh // OC1A output: Discon. // OC1B output: Discon. // Noise Canceler: Off // Input Capture on Falling Edge // Timer 1 Overflow Interrupt: Off // Input Capture Interrupt: Off // Compare A Match Interrupt: Off // Compare B Match Interrupt: Off TCCR1A=0x00; TCCR1B=0x00; TCNT1H=0x00; TCNT1L=0x00; ICR1H=0x00; ICR1L=0x00; OCR1AH=0x00; OCR1AL=0x00; OCR1BH=0x00; OCR1BL=0x00; // Timer/Counter 2 initialization // Clock source: System Clock // Clock value: Timer 2 Stopped // Mode: Normal top=FFh // OC2 output: Disconnected ASSR=0x00; TCCR2=0x00; TCNT2=0x00; OCR2=0x00; // External Interrupt(s) initialization // INT0: Off // INT1: Off // INT2: Off MCUCR=0x00; MCUCSR=0x00; // Timer(s)/Counter(s) Interrupt(s) initialization TIMSK=0x01; // Analog Comparator initialization // Analog Comparator: Off // Analog Comparator Input Capture by Timer/Counter 1: Off ACSR=0x80; SFIOR=0x00; // Global enable interrupts #asm("sei") while (1) { // Place your code here scan_line(); }; }
Agar pergerakan robot menjadi lebih halus, maka kecepatan robot diatur sesuai dengan kondisi pembacaan sensor proximity. Jika posisi robot menyimpang dari garis, maka robot akan melambat. Namun jika robot tepat berada diatas garis, maka robot akan bergerak cepat. Robot juga dapat kembali ke garis pada saat robot terlepas sama sekali dari garis. Hal ini bisa dilakukan karena robot selalu mengingat kondisi terakhir pembacaan sensor. Jika terakhir kondisinya adalah disebelah kiri garis, maka robot akan bergerak ke kanan, demikian pula sebaliknya.
Gambar 1. Robot Line Tracker
Sensor Proximity
Sensor proximity bisa kita buat sendiri. Prinsip kerjanya sederhana, hanya memanfaatkan sifat cahaya yang akan dipantulkan jika mengenai benda berwarna terang dan
akan diserap jika mengenai benda berwarna gelap. Sebagai sumber cahaya kita gunakan LED (Light Emiting Diode) yang akan memancarkan cahaya merah. Dan untuk menangkap pantulan cahaya LED, kita gunakan photodiode. Jika sensor berada diatas garis hitam maka photodioda akan menerima sedikit sekali cahaya pantulan. Tetapi jika sensor berada diatas garis putih maka photodioda akan menerima banyak cahaya pantulan. Berikut adalah ilustrasinya :
Gambar 2. Prinsip Kerja Sensor Proximity
Gambar Photodioda
Sifat dari photodioda adalah jika semakin banyak cahaya yang diterima, maka nilai resistansi diodanya semakin kecil. Dengan melakukan sedikit modifikasi, maka besaran resistansi tersebut dapat diubah menjadi tegangan. Sehingga jika sensor berada diatas garis hitam, maka tegangan keluaran sensor akan kecil, demikian pula sebaliknya. Berikut adalah gambar rangkaian sensor proximity yang digunakan pada robot ini :
Gambar LM339N (IC comparator)
Gambar 3. Rangkaian Sensor Proximity
Agar dapat dibaca oleh mikrokontroler, maka tegangan sensor harus disesuaikan dengan level tegangan TTL yaitu 0 – 1 volt untuk logika 0 dan 3 – 5 volt untuk logika 1. Hal ini bisa dilakukan dengan memasang operational amplifier yang difungsikan sebagai komparator. Output dari photodiode yang masuk ke input inverting op-amp akan dibandingkan dengan tegangan tertentu dari variable resistor VR. Tegangan dari VR inilah yang kita atur agar sensor proximity dapat menyesuaikan dengan kondisi cahaya ruangan.
Gambar 4. Posisi Pemasangan Sensor Proximity Pada Robot
Sensor proximity terdiri dari 6 pasang LED dan photodiode yang disusun sedemikian rupa sehingga jarak antara satu sensor dengan yang lainnya lebih kecil dari lebar garis hitam. Perhatikan gambar berikut :
Gambar 5. Jarak Antar Sensor Proximity
Rancangan Mekanik Robot
Gambar 6. Mekanik Robot
Algoritma Pergerakan Robot
Sebelum membuat program, maka kita perlu mendefinisikan seluruh kemungkinan pembacaan sensor proximity. Dengan demikian kita dapat menentukan pergerakan robot yang tujuannya adalah menjaga agar robot selalu berada tepat diatas garis. Berikut adalah beberapa kemungkinan pembacaan garis oleh sensor proximity :
Gambar 7. Kemungkinan Posisi Sensor Proximity Pada Line
Setelah mengetahui kemungkinan-kemungkinan posisi sensor, maka selanjutnya harus
didefinisikan aksi dari setiap kondisi tersebut. Perhatikan tabel berikut ini :
Tabel 1. Aksi Pergerakan Robot
Lapangan Uji Coba
Lapangan berupa garis-garis hitam diatas lantai berwarna putih. Garis hitam disusun
membentuk banyak persimpangan. Ukuran tiap kotak adalah 30 cm x 30 cm. Ketebalan garis hitam
adalah 3 cm. Garis hitam ini bisa dibuat menggunakan isolasi hitam kemudian ditempel pada lantai
atau kertas karton berwarna putih.
Gambar 8. Lapangan Uji Coba
Driver Motor DC
Untuk menggerakkan dua buah motor dc, digunakan IC H-Bridge Motor Driver L298, yang mampu memberikan arus maksimum sebesar 1A ke tiap motor. Input L298 ada 6 jalur, terdiri dari input data arah pergerakan motor dan input untuk PWM (Pulse Width Modulation). Untuk mengatur kecepatan motor, pada input PWM inilah akan diberikan lebar pulsa yang bervariasi dari mikrokontroler.
Gambar L298 (Driver Motor)
Gambar 10. Rangkaian Driver Motor DC
Untuk menentukan arah pergerakan motor maka pada input L298 harus diberikan kondisi
sesuai dengan tabel berikut :
Tabel 2. Tabel Kebenaran Driver Motor
AVR Microcontroller
Sebagai ”otak” robot digunakan mikrokontroler AVR jenis ATmega8535 yang akan membaca
data dari sensor proximity, mengolahnya, kemudian memutuskan arah pergerakan robot.
Gambar 11. Mikrokontroler ATmega8535
Pada robot line track ini, keluaran sensor proximity dihubungkan ke PortD.0 dan PortD.5 pada mikrokontroler. Sedangkan driver motor dihubungkan ke PortC.0 s/d PortC.5 seperti terlihat pada gambar berikut :
Gambar 12. Mikrokontroler ATmega8535
Membuat Source Code
Source code secara lengkap dapat dilihat pada Lampiran A. Source code dibuat dengan
menggunakan software CodeVisionAVR dengan langkah-langkah sebagai berikut :
1. Jalankan CodeVisionAVR, kemudian klik File -> New, Pilih Project
2. “Do you want to use the CodeWizardAVR?” Klik Yes
3. Pilih Chip yang digunakan, chip : ATmega8535L, clock : 4.000000 MHz
4. Lakukan setting sebagai berikut :
Port : Port B sebagai Output dan Port A sebagai Input Pullup
Timers : Timer 0 dengan Clock Value 10,800 KHz, aktifkan Overflow Interrupt
5. Klik File -> Generate, Save and Exit
6. Buatlah source code seperti pada Lampiran A.
7. Setelah selesai membuat source code, klik Setting -> Programmer
8. Pilih AVR Chip Programmer Type : Kanda System STK200+/300 dan pilih Printer Port pada
LPT1 : 378h
9. Klik Project -> Configure, kemudian pilih menu After Make dan aktifkan Program the Chip. Klik OK jika sudah.
PERHATIAN ! Jangan mengubah setting apapun pada menu ini. Jika salah memilih,
chip Anda tidak bisa digunakan lagi !!
10. Untuk meng-compile project, klik Project -> Make
11. Jika tidak ada error maka file siap didownload ke chip. Pastikan koneksi kabel downloader
dan chip sudah terpasang dengan benar.
12. Nyalakan power supply dan klik Program. Tunggu hingga proses download selesai.
Penjelasan Source Code
Berikut adalah penjelasan tiap bagian dari source code.
1. Membuat definisi port yang digunakan sebagai berikut :
#define SkiXX PINA.0 // Sensor kiri terluar
#define SkiX PINA.1 // Sensor kiri luar
#define Ski PINA.2 // Sensor kiri tengah
#define Ska PINA.3 // Sensor kanan tengah
#define SkaX PINA.4 // Sensor kanan luar
#define SkaXX PINA.5 // Sensor kanan terluar
#define EnKi PORTB.1 // Enable L298 untuk motor kiri
#define dirA_Ki PORTB.2 // Direction A untuk motor kiri
#define dirB_Ki PORTB.3 // Direction B untuk motor kiri
#define EnKa PORTB.0 // Enable L298 untuk motor kanan
#define dirC_Ka PORTB.4 // Direction C untuk motor kanan
#define dirD_Ka PORTB.5 // Direction D untuk motor kanan
2. Menentukan library yang digunakan :
#include
#include
3. Membuat variable sebagai pengingat kondisi pembacaan sensor line terakhir.
bit x;
4. Membuat ISR Timer 0 / Interrupt Service Routine Timer 0.
ISR ini digunakan untuk menghasilkan pulsa PWM untuk mengendalikan motor kiri dan kanan melalui bit EnKi dan EnKa.
ISR Timer 0 dieksekusi secara periodik ketika Timer 0 overflow. Lamanya tergantung nilai Timer/Counter 0 (TCNT0).
Periode pulsa ditentukan oleh TCNT0. Nilai maksimumnya 0xFF atau 255d.
Duty cycle PWM untuk motor kiri ditentukan oleh nilai lpwm. Maksimum 255.
Duty cycle PWM untuk motor kanan ditentukan oleh nilai rpwm. Maksimum 255.
unsigned char xcount,lpwm,rpwm; // Definisi variable
// Timer 0 overflow interrupt service routine
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
// Place your code here
xcount++; // xcount=xcount+1
if(xcount<=lpwm)EnKi=1; // EnKi=1 jika xcount <= lpwm else EnKi=0; // EnKi=0 jika xcount > lpwm
if(xcount<=rpwm)EnKa=1; // EnKa=1 jika xcount <= rpwm else EnKa=0; // EnKa=0 jika xcount > rpwm
TCNT0=0xFF; // Timer0 Value Menentukan periode pulsa PWM
}
5. Membuat sub rutin agar robot bergerak maju
void maju()
{
dirA_Ki=1;dirB_Ki=0; // Motor kiri maju
dirC_Ka=1;dirD_Ka=0; // Motor kanan maju
}
6. Membuat sub rutin agar robot belok ke kiri
void belok_kiri()
{
unsigned int i;
lpwm=50; rpwm=50; // Kecepatan pelan
delay_ms(60); // Robot dimajukan sedikit
dirA_Ki=0;dirB_Ki=1; // Motor kiri mundur
dirC_Ka=1;dirD_Ka=0; // Motor kanan maju
for(i=0;i<=1000;i++) while (!SkiXX ||!SkiX) {}; for(i=0;i<=1000;i++) while ( SkiXX || SkiX) {}; lpwm=0; rpwm=0; // Robot berhenti } Pada program diatas, tampak ada 2 “for while” yang masing-masing diulang 1000 kali untuk memastikan bahwa sensor benar-benar membaca sebuah garis, bukan noda atau kotoran yang ada di lapangan. for(i=0;i<=1000;i++) while (!SkiXX ||!SkiX) {}; Robot akan terus belok kiri selama sensor SkiXX=0 atau SkiX=0 (sensor berada diatas garis hitam) for(i=0;i<=1000;i++) while ( SkiXX || SkiX) {}; Selanjutnya robot tetap belok kiri selama sensor SkiXX=1 atau SkiX=1 (sensor berada diatas permukaan putih). 7. Membuat sub rutin agar robot belok ke kanan void belok_kanan() { unsigned int i; lpwm=50; rpwm=50; // Kecepatan pelan delay_ms(60); // Robot dimajukan sedikit dirA_Ki=1;dirB_Ki=0; // Motor kiri maju dirC_Ka=0;dirD_Ka=1; // Motor kanan mundur for(i=0;i<=1000;i++) while (!SkaXX ||!SkaX) {}; for(i=0;i<=1000;i++) while ( SkaXX || SkaX) {}; lpwm=0; rpwm=0; // Robot berhenti } 8. Membuat sub rutin membaca line unsigned char sensor; void scan_rule1() { maju(); // Robot bergerak maju sensor=PIND; // PIND diberi nama sensor sensor&=0b00111111; // sensor di-AND-kan dengan 0b00111111 switch(sensor) { case 0b00111110: rpwm=0; lpwm=200; x=1; break; case 0b00111100: rpwm=50; lpwm=200; x=1; break; case 0b00111101: rpwm=75; lpwm=200; x=1; break; case 0b00111001: rpwm=100; lpwm=200; x=1; break; case 0b00111011: rpwm=150; lpwm=200; x=1; break; case 0b00110011: rpwm=200; lpwm=200; break; case 0b00110111: rpwm=200; lpwm=150; x=0; break; case 0b00100111: rpwm=200; lpwm=100; x=0; break; case 0b00101111: rpwm=200; lpwm=75; x=0; break; case 0b00001111: rpwm=200; lpwm=50; x=0; break; case 0b00011111: rpwm=200; lpwm=0; x=0; break; case 0b00111111: break; if(x) {lpwm=50; rpwm=0; break;} else {lpwm=0; rpwm=50; break;} } } Variabel x ini berfungsi sebagai pengingat posisi terakhir robot terhadap garis. Jika robot berada di kanan garis, maka x=0. Jika robot berada di kiri garis, maka x=1. Ketika robot lepas dari track, maka program akan membaca kondisi variable x, sehingga dapat ditentukan arah gerak robot agar robot dapat kembali ke garis, seperti terlihat pada instruksi berikut : if(x) {lpwm=50; rpwm=0; break;} else {lpwm=0; rpwm=50; break;} Jika x=1 maka robot belok kanan, jika x=0 maka robot belok kiri. 9. Membuat sub rutin membaca persimpangan void scan_count(unsigned char count) { unsigned int i; unsigned char xx=0; while(xx
#include
#define enka PORTB.0 // Enable L298 untuk motor kiri
#define enki PORTB.1 // Direction A untuk motor kiri
#define dirA PORTB.2 // Direction B untuk motor kiri
#define dirB PORTB.3 // Enable L298 untuk motor kanan
#define dirC PORTB.4 // Direction C untuk motor kanan
#define dirD PORTB.5 // Direction D untuk motor kanan
#define skaxx PINA.0
#define skax PINA.1
#define ska PINA.2
#define ski PINA.3
#define skix PINA.4
#define skixx PINA.5
bit x;
unsigned char Y=0,rpwm,lpwm;
// Timer 0 overflow interrupt service routine
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
// Place your code here
Y++;
if(Y<=rpwm)enka=1; else enka=0; if(Y<=lpwm)enki=1; else enki=0; TCNT0=0xFF; } void maju() { //enka=1;enki=1; dirA=1;dirB=0; dirC=1;dirD=0; } unsigned char sensor; void scan_line() { maju(); // Robot bergerak maju sensor=PINA; // PINA diberi nama sensor sensor&=0b11111111; // sensor di-AND-kan dengan 0b01111110 switch(sensor) { case 0b11111110: lpwm=30; rpwm=100; x=1; break; case 0b11111100: lpwm=40; rpwm=100; x=1; break; case 0b11111101: lpwm=50; rpwm=100; x=1; break; case 0b11111001: lpwm=60; rpwm=90; x=1; break; case 0b11111011: lpwm=80; rpwm=90; x=1; break; case 0b11110011: lpwm=100; rpwm=100; break; //tngh case 0b11110111: lpwm=90; rpwm=80; x=0; break; case 0b11100111: lpwm=90; rpwm=60; x=0; break; case 0b11101111: lpwm=100; rpwm=50; x=0; break; case 0b11001111: lpwm=100; rpwm=40; x=0; break; case 0b11011111: lpwm=100; rpwm=30; x=0; break; case 0b11111111: break; if(x==0) { lpwm=255; rpwm=0; break; } else if (x==1) { lpwm=0; rpwm=255; break; } } } // Declare your global variables here void main(void) { // Declare your local variables here // Input/Output Ports initialization // Port A initialization // Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In // State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T PORTA=0x00; DDRA=0x00; // Port B initialization // Func7=Out Func6=Out Func5=Out Func4=Out Func3=Out Func2=Out Func1=Out Func0=Out // State7=0 State6=0 State5=0 State4=0 State3=0 State2=0 State1=0 State0=0 PORTB=0x00; DDRB=0xFF; // Port C initialization // Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In // State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T PORTC=0x00; DDRC=0x00; // Port D initialization // Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In // State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T PORTD=0x00; DDRD=0x00; // Timer/Counter 0 initialization // Clock source: System Clock // Clock value: 500.000 kHz // Mode: Normal top=FFh // OC0 output: Disconnected TCCR0=0x02; TCNT0=0x00; OCR0=0x00; // Timer/Counter 1 initialization // Clock source: System Clock // Clock value: Timer 1 Stopped // Mode: Normal top=FFFFh // OC1A output: Discon. // OC1B output: Discon. // Noise Canceler: Off // Input Capture on Falling Edge // Timer 1 Overflow Interrupt: Off // Input Capture Interrupt: Off // Compare A Match Interrupt: Off // Compare B Match Interrupt: Off TCCR1A=0x00; TCCR1B=0x00; TCNT1H=0x00; TCNT1L=0x00; ICR1H=0x00; ICR1L=0x00; OCR1AH=0x00; OCR1AL=0x00; OCR1BH=0x00; OCR1BL=0x00; // Timer/Counter 2 initialization // Clock source: System Clock // Clock value: Timer 2 Stopped // Mode: Normal top=FFh // OC2 output: Disconnected ASSR=0x00; TCCR2=0x00; TCNT2=0x00; OCR2=0x00; // External Interrupt(s) initialization // INT0: Off // INT1: Off // INT2: Off MCUCR=0x00; MCUCSR=0x00; // Timer(s)/Counter(s) Interrupt(s) initialization TIMSK=0x01; // Analog Comparator initialization // Analog Comparator: Off // Analog Comparator Input Capture by Timer/Counter 1: Off ACSR=0x80; SFIOR=0x00; // Global enable interrupts #asm("sei") while (1) { // Place your code here scan_line(); }; }
Langganan:
Komentar (Atom)