Gambar 1. Posisi sensor pada grid line follower |
void inisialisasiPort(void)
{
int Pins[11] = {sensor1, sensor2, sensor3, sensor4, pinStart, 9, 10, A0, A1, A2, A3} ;
for (int i = 0; i < 12; i++)
{
if (i <= 4 )
{
pinMode(Pins[i], INPUT_PULLUP);
}
else
{
pinMode(Pins[i], OUTPUT);
digitalWrite(Pins[i], HIGH);
}
}
while (digitalRead(pinStart)==1)
{}
}
Penjelasan kode program inisialisasi port di atas :
#define pinStart 13
Kode
program ”#define <nama> <pin>’ di atas bertujuan untuk
mengganti nama pin dengan nama yang lebih mudah untuk diingat. Contoh, agar lebih nyaman menggunakan
Selain
itu jika ingin mengganti pin yang akan digunakan cukup dengan mengganti
pin pada kode ‘define <nama> <pin>’ saja dari pada harus
mengganti nama pin pada semua kode yang telah di-tulis.
void inisialisasiPort(void)
{
//Program inisialisasi port Arduino Uno
}
Prosedur
inisialisasiPort di atas bertujuan untuk menjalankan blok kode program
yang ditulis dalam prosedur tersebut, jika prosedur tersebut dipanggil
maka semua blok kode program didalamnya akan dieksekusi atau dikerjakan.
int Pins[11] = {sensor1, sensor2, sensor3, sensor4, pinStart, 9, 10, A0, A1, A2, A3} ;
Kode program ini merupakan array dari
semua pin Arduino Uno yang akan digunakan. Penulis lebih suka
menggunakan teknik ini karena lebih singkat dalam melakukan inisialisasi
port dari pada menuliskan kode inisialisasi setiap port yang
mengakibatkan penulisan program bisa lebih panjang.
for (int i = 0; i < 12; i++)
{
if (i <= 4 )
{
pinMode(Pins[i], INPUT_PULLUP);
}
else
{
pinMode(Pins[i], OUTPUT);
digitalWrite(Pins[i], HIGH);
}
while (digitalRead(pinStart)==1)
{}
}
Program di atas digunakan untuk menentukan port yang akan digunakan sebagai output atau input.
Caranya adalah melakukan inisialisasi dengan perintah
‘pinMode(<pin>, <output atau input>)’ dari nama pin yang
disebut pada array dengan cara menggunakan perintah loop ‘for’ sebanyak jumlah pin yang digunakan.
pinMode(Pins[i], OUTPUT);
Kode program untuk menentukan bahwa pin Arduino yang digunakan sebagai input atau output. Pins[i] merupakan data array pin Arduino Uno. Jika tidak menggunakan array langsung saja ditulis pin yang digunakan.
digitalWrite(Pins[i], HIGH);
Merupakan kode program untuk membuat pin Arduino menjadi 1 atau pada pin tersebut akan mengeluarkan tegangan hampir +5Volt.
while (digitalRead(pinStart)==1)
{}
Kode program while di atas berarti saat nilai pinStart adalah 1 maka program akan berhenti pada while terus menurus sampai nilai variabel pinStart bernilai 0. Pada rangkaian grid line follower pin Arduino 13 terhubung pada tombol push button yang digunakan untuk menjalankan grid line follower.
Kode Program Pembacaan Sensor1, Sensor2 dan Sensor3 pada Arduino Uno
Di bawah ini adalah adalah contoh program pembacaan semua sensor pada grid line follower :
Panjelasan kode program pembacaan sensor pada Arduino Uno
diletakan pada posisi kanan, sensor2 di posisi tengan, sensor3 pada
posisi kiri. Sudut pandang sensor dilihat dari atas. Variabel ‘pinStart’
menunjukan pin pada Arduino Uno yang dihunungkan pada pin13 dan pada
gambar rangkaian pin 13 terhubung dengan saklar push button untuk menjalankan line follower.
Rangkaian sensor dibuat sedemikikian rupa sehingga jika sensor photodiode mendeteksi adanya garis putih maka output komparator menjadi 0 atau mendekati 0 sehingga memberikan inputan 0 pada rangkaian Arduino Uno.
Penulis membuat semua program pembacaan sensor adalah aktif low dimana
jika ada inputan 0 dari rangkaian sensor maka berarti program
menganggap bahwa pada rangkaian sensor tersebut telah mendeteksi garis
putih.
fungsi pembacaan sensor dengan nilai balik yang memuat data hasil
pembacaan sensor1, sensor2 dan sensor3 yang semuanya merupakan sensor
garis.
Pembacaan
sensor dilakukan satu persatu setiap pin yaitu : sensor1 dibaca,
kemudian sensor2 dibaca lalu sensor3 dibaca. Hasil pembacaan setiap
sensor digabung menjadi satu kesatuan dalam nilai 8 bit sehingga lebih
mudah untuk dibuat kode program percabangan ‘if’ untuk menentukan
kecepatan motor atau untuk tujuan lainnya.
Contoh
: data = digitalRead(sensor1);, saat sensor1 bernilai 0 maka penulis
membuatnya menjadi bernilai 0b00000110. Nilai 0b00000110 menandakan
sensor1 bernilai 0 yang berarti bahwa yang mendeteksi garis putih adalah
sensor1, sensor 2 dan 3 lainnya bernilai 1 karena dianggap belum
dilakukan pembacaan sensor atau dianggap tidak melakukan pendeteksian
garis putih. Jika sensor1 tidak mendeteksi garis putih atau bernilai 1
maka variabel data dibuat bernilai 0b00000111. Jika sensor1, sensor2 dan
sensor3 mendeteksi adanya garis putih maka variabel data dibuat
bernilai 0b00000000. Jika sensor 2 dan 3 saja yang mendeteksi garis maka
variabel data dibuat bernilai 0b00000001
Urutan pembacaan sensor pada program di atas adalah sbb :
- Dilakukan pembacaan pada sensor1, jika output rangkaian
sensor1 bernilai 0 (mendeteksi adanya garis putih) maka variabel ‘data’
menjadi 0 dan variabel ‘nilai’ dibuat menjadi 0b00000110, jika output rangkaian sensor1 bernilai 1 (tidak mendeteksi adanya garis putih) maka variabel ‘data’ bernilai 1 dan variabel nilai dibuat bernilai 0b00000111. - Kemudian
program membaca sensor2, jika rangkaian sensor2 mengeluarkan bit
0(mendeteksi garis putih) maka variabel ‘data’ bernilai 0 dan variabel
‘nilai’ dibuat menjadi 0b00000101 yang di ‘and’ kan dengan variabel
nilai pada pembacaan sensor1, sehingga bisa ditulis menjadi nilai =
nilai & 0b00000101.
Jika sensor2 tidak membaca garis putih maka variabel data otomatis akan
bernilai 1 dan variabel nilai menjadi 0b00000111 di ‘and’ kan dengan
variabel pembacaan sensor1 sehingga bisa ditulis menjadi nilai = nilai & 0b00000111. - Kemudian
program membaca sensor3, jika rangkaian sensor3 mengeluarkan bit 0
(mendeteksi garis putih) maka variabel ‘data’ bernilai 0 dan variabel
‘nilai’ dibuat menjadi 0b00000011 yang di ‘and’ kan dengan variabel
nilai pada pembacaan sensor2, sehingga bisa ditulis menjadi nilai =
nilai & 0b00000011.
Jika sensor3 tidak membaca garis putih maka variabel data otomatis akan
bernilai 1 dan variabel nilai menjadi 0b00000111 di ‘and’ kan dengan
variabel pembacaan sensor1 sehingga bisa ditulis menjadi nilai = nilai & 0b00000111. - Setelah
sensor 1, 2, 3 dibaca dan variabel ‘nilai’ dari hasil pembacaan
masing-masing sensor digabung maka variabel nilai tersebut dikembalikan
pada fungsi ”uint_8 bacaSensor()) dengan kode program ”return nilai; ‘
sehingga bisa dilakukan pembacaan sensor cukup dengan contoh kode
program ‘dataSensor = bacaSensor() ;’ yang hasil dari pembacaan sensor
disimpan pada variabel ‘dataSensor’.
Pembacaan data sensor4 (counter grid) dilakukan saat vector interrupt timer overflow karena hasilnya lebih cepat dibanding menuliskannya pada loop karena pada loop program
harus menunggu program lain selesai dikerjakan sebelum kode pemanggilan
fungsi pembacaan sensor dieksekusi. Jika kode pembacaan sensor4 ditulis
pada vector interrupt timer overflow, kode program akan selalu dieksekusi saat terjadi overflow pada counter yang
selalu terjadi secara periodik dan cepat. Selain itu jika program masih
mengerjakan program lain program akan melakukan interupsi dan
mengerjakan pembacaan sensor lalu akan kembali ke program semula.
Pemanggilan kode fungsi pembacaan sensor pada vector interupsi timer/counter2 mode overflow dapat dituliskan menjadi :
ISR(TIMER2_OVF_vect)
{
dataSensor = bacaSensor() ;
}
Pembacaan sensor counter grid ini berbeda dari penjelasan sebelumnya karena untuk menghitung grid atau
persimpangan tidak bisa menggunakan metode pembacaan biasa seperti
pembacaan sensor garis putih yang telah dijelaskan sebelumnya karena
sensor harus menghitung satu garis putih yang dilewati sebagai satu
hitungan, jika menggunakan pembacaan biasa, mikrokontroler akan
menghitung banyak sekali pada satu persimpangan yang dilewati.
Penghitungan persimpangan dapat dilakukan menggunakan fitur external interrupt pada Arduino dimana program menghitung satu hitungan jika saat mikrokontroler mendeteksi ada perubahan logika 1 menjadi 0 atau 0 menjadi 1 pada terminal atau pin external interrupt tergantung pada pilihan konfigurasi. Penulis tidak menggunakan fitur tersebut karena dapat dibuat programnya tanpa menggunakan pin external interrupt tetapi kerjanya sangat mirip dengan external interrupt sehingga dapat menghemat pin external interrupt untuk tujuan lainnya. Kode program pembacaan persimpangan grid ditulis pada vector interrupt timer/counter2 yang telah dijelaskan di atas.
Berikut contoh penulisan program pembacaan sensor grid counter :
volatile uint8_t flipflop =1, temp=0, counter=0;
ISR(TIMER2_OVF_vect)
{
dataSensor = bacaSensor() ;
temp =digitalRead(sensor4) ;
if (temp == 1)
{
if (flipflop == 0)
{
flipflop = 1 ;
counter++ ;
}
}
if (temp == 0)
flipflop = 0;
}
Penjelasan kode program pembacaan sensor grid counter
Variabel global flipflop dan temp memiliki kode volatile didepannya bertujuan agar variabel global tersebut dapat diakses oleh blok kode program pada vector interrupt, karena tanpa kode volatile’ variabel global tidak dapat dibaca oleh kode program pada blok vector interrupt.
- Variabel global flipflop diberi nilai logika 1, variabel global temp dan counter diberi nilai logika 0.
- Hasil pembacaan sensor4 disimpan pada variabel temp dengan perintah temp = digitalRead(sensor4);
- Jika variabel temp (hasil pembacaan sensor4) bernilai 1 dan jika variabel flipflop bernilai 0, maka variabel flipflop diberi logika 1 dan variabel counter akan dijumlahkan dengan 1 dengan perintah counter++. Sebelum ada persimpangan yang dilewati penjumlahan variable counter tidak akan dilakukan karena tidak memenuhi persyaratan kondisi.
- Jika sensor4 mendeteksi adanya persimpangan maka variabel temp (hasil pembacaan sensor4) akan bernilai 0 dan variabel flipflop akan
dibuat menjadi 0. Selama sensor masih mendeteksi adanya persimpangan
(garis putih belum dilewati sepenuhnya) maka kondisi variabel flipflop dan temp akan selalu 0 yang menyebabkan penjumlahan variabel counter dengan 1 tidak bisa dilakukan. - Saat persimpangan sudah terlewati (sensor4 tidak mendeteksi garis persimpangan) maka variabel temp akan bernilai 1 sehingga kondisi variabel temp bernilai 1 dan variabel flipflop bernilai 0 tepenuhi lalu variabel flipflop dibuat lagi bernilai 1 dan variabel counter ditambah dengan 1. Hal ini menyebabkan variabel counter bernilai 1. Setelah itu variabel counter tidak akan ditambah dengan 1 jika tidak melewati persimpangan lagi.
- Setiap melewati persimpangan variabel counter akan selalu ditambahkan dengan 1. dan variabel counter inilah yang dijadikan sebagai acuan sebagai perhitungan jumlah persimpangan atau grid yang telah dilalui.
#define pinStart 13
#define sensor3 2
#define sensor2 7
#define sensor1 11
#define sensor4 12
volatile uint8_t dataSensor = 0, temp = 0, flipflop = 1, counter = 0;
void inisialisasiPort(void)
{
for (int i = 0; i < 12; i++)
{
if (i <= 4 )
{
pinMode(Pins[i], INPUT_PULLUP);
}
else
{
pinMode(Pins[i], OUTPUT);
digitalWrite(Pins[i], HIGH);
}
}
while (digitalRead(pinStart)==1)
{}
TCCR1A = 0b10100011; //phase correct PWM
TCCR1B = 0b00001100;
TCCR2B = 0b00000011; //source clock / 32
TIMSK2 = 0b00000001 ;
sei ();
ISR(TIMER2_OVF_vect)
{
dataSensor = bacaSensor() ;
temp =digitalRead(sensor4) ;
if (temp == 1)
{
if (flipflop == 0)
{
flipflop = 1 ;
counter++ ;
}
}
if (temp == 0)
flipflop = 0;
}
uint8_t bacaSensor()
{
uint8_t data, nilai = 0;
data = digitalRead(sensor1);
if (data == 0)
{ nilai = 0b000000110; }
if (data == 1)
{ nilai = 0b00000111; }
data = digitalRead(sensor2);
if (data == 0)
{ nilai = 0b00000101 & nilai; }
if (data == 1)
{ nilai = 0b00000111 & nilai; }
data = digitalRead(sensor3);
if (data == 0)
{ nilai = 0b00000011 & nilai; }
if (data == 1)
{nilai = 0b00000111 & nilai; }
return nilai;
}
- Konsep Kerja Grid Line Follower
- Cara Kerja PWM Arduino Uno untuk pengaturan kecepatan motor dc
- Interrupt timer untuk pembacaan sensor garis
- Kode Program Pembacaan Sensor Garis
- Mekanik dan pergerakan Grid Line Follower
- Kode Lengkap Grid Line Follower
- PCB dan Rangkaian Grid Line Follower
EoF