Arduino ile Çizgi İzleyen ve Engelden Kaçan Robot Araba Yapımı

Merhabalar,
Arduino programlamada temel bazı uygulamalardan sonra sanırım otonom hareket eden araçlar yapımı seviyesine geçişteki ilk projelerden birisi çizgi takip robotu yapmaktır. Çizgi izleyen robotlar
endüstriyel alanlarda kullanımlarının yanı sıra AVM'lerdeki çocuk trenlerinde de sıkça karşımıza çıkıyor.
Temel olarak zemine göre kontrast arz eden bir hattı algılayan ve bu hattı ortalayacak şekilde itki sistemlerine kumanda eden bir araçtan bahsediyoruz. Kızılötesi sensörler vasıtası ile yere gönderilen sinyal dönüşte çarptığı yüzeyin rengine göre farklı şiddetlerde yansımaktadır. Sensör geri dönen sinyalin şiddetine göre çizgiyi algılamaktadır. Bazı sensörler analog çıkış verirken, daha pratik ve hızlı olması nedeni ile dijital sensörler daha çok tercih edilmektedir. Dijital sensörler, sensörün marka ve çeşidine göre beyaz üzerinde siyahı algılayınca 1 çıkışı veren veya tam tersi durumda 1 çıkışı veren sensörler olarak piyasada bulunmaktadır. TCRT5000 gibi sensörler buna örnek verilebilir. (datasheet'ine bakarak anlayabilirsiniz.)

Gerekli Malzemeler
-Bu proje için hazır satılan analog 4'lü çizgi sensörünün 3 adedini (plaket üzerinde tümleşik 5'li, 6'lı gibi sensörler de mevcut.) kullandım çünkü elimde bu vardı. TCRT5000 de kullanılabilir. Aslında temel olarak ne kadar çok sensör olursa hassasiyet o kadar iyi olacaktır ancak başlangıçta işleri basit tutmak hem kolay anlayıp uygulamamızı sağlar hem de olası olumsuzlukları azaltarak şevkinizin kırılmasını önleyecektir.
-Engelleri algılamak için 1 adet HCSR-04 Ultrasound Mesafe Ölçer
-1 adet motor sürücü kartı (ben L298 kullandım. Herhangi bir H köprülü sürücü kartı olabilir)
-4 adet 6v 250 RPM redüksiyonlu DC motor (yarışmalara katılmıyorsanız sarı ucuz motorlar iş görecektir.)
-Arduino kartı (Uno, Nano,Mega olabilir)
-Jumper kablo
-Araç şasesi (Ben buna para vermenin gereksiz olduğunu düşünüyorum ve evde işlemesi çok kolay olan rahatça kesilebilen, hafif ama dayanıklı reklamcılarda satılan Dekota isimli beyaz levhaları kullanıyorum)
-Kablo ve diğer ekipman
-Pil (9V'luk piller çok çabuk bittiği için ben eski model uçak lipo pillerimden kullanıyorum. 2S-7-8V olacak şekilde)
-Switch ON-OFF

Araç Şasesi
Yukarıda da belirttiğim gibi elinizdeki herhangi bir malzeme ile yapabilir veya hazır alabilirsiniz ancak hazır şasiler bence gereksiz pahalı. Dekota denen malzemeyi tavsiye ederim. Kesmesi ve delmesi çok kolay.
Öncelikle redüksiyonları motorların sığabileceği büyüklükte bir ölçüde levhadan kesiyoruz (Ör:16x12cm)

Sonra motorları aşağıdaki resimde olduğu gibi sıcak silikon ile sabitliyoruz. Sıcak silikon uygulamadan önce iki yüzeye de zımpara atarsanız daha sağlam yapışacaktır. Burada dikkat etmeniz gereken nokta motorların araç eksenine göre düz yapıştırılması. Yamuk olursa aracınız düz gidemez, sağa veya sola çeker. Bunu istemeyiz. O yüzden her zaman 3 ölçüp 1 kesiyoruz veya yapıştırıyoruz.

Gayet basit ve hızlı bir şekilde aracımızın şasesi hazır. Artık elektronikleri döşeyebiliriz. Ama yine önce ekipmanları doğru yerleştirmek için üzerine konumlandırıp yerlerine karar verdikten sonra kalemle işaretleyebilirisiniz.


Çizgi sensörünün IR algılayıcıları için aşağıdaki uzantıları yapıştırdım.


Sensörleri konumlandırdım. Burada dikkat edilecek nokta sensörlerin zeminden yüksekliğidir. Çünkü her sensörün kendine has bir optimal çalışma aralığı vardır. Bundan alçak veya yüksek olursa verim alamazsınız. Siz de kendi sensörünüzün mesafe kabiliyetine göre bu yerleşimi uygulayabilirsiniz.

Daha sonra motor sürücü kartını ve ultrasound sensörü tutacak servoyu sabitledim. L298 büyük ve nispeten ağır olmasına rağmen çok tercih ettiğim bir sürücü kartı çünkü bağlantıları yapması çok pratik ve arduinoya bu karttan VIN'den takat verebiliyoruz.


Yukarıdaki resimde ayrıca çizgi sensörlerinin kontrol kartı görülüyor. Bu modelde tornavida ile hassasiyet ayarı yapabiliyor ve zemin ve çizgimize göre sensörlerin kalibrasyonunu yapabiliyoruz.


Arduino kartımızı yerleştirip bağlantılarımızı tamamlıyoruz.


Bağlantı Şeması

Bağlantıları yukarıdaki şemaya göre yapabilirsiniz.Burada dikkat edilecek nokta L298'i ana pilimiz ile besliyoruz. Oradan aldığımız pil voltajını ve ground hattını Ardu VIN ve GND'ye girerek Arduyu da lipo ile beslemiş oluyoruz. 

Çalışma Prensibi ve Algoritma
Genellikle robotların ilk aşamasında karmaşıklığı azaltmak ve temel fonksiyonları önce başarıp sonra karmaşık kontrollere girmek yöntem olarak daha faydalıdır. Kaybolmanızı ve sıkılıp pes etmenizi önler. O yüzden bu çalışmada da çalışma prensibini basit tuttuk. Robotumuz çizgi sensörlerinden veri okuyacak ve orta sensör çizgiyi gördüğü sürece (bu örnekte çıkışı 1 olduğu sürece) dümdüz ileri gidecek. Eğer sağ sensör çizgi algılarsa bu sefer robot çizginin solunda kalmış demektir. O zaman sağa doğru komut verecek. Sol için ise tam tersi. Böylece robotumuz basitçe çizgiyi takip etmiş olacak. Bu algortimayı başardıktan sonra daha karmaşık ve daha çok sensörlü robotlar yapılabilir. Bu esnada ultrasound sensör de sürekli cisim arayacak ve önünde 10cmden daha yakın bir cisim tespit ederse robot duracak ve geri gidecek ve süreçler baştan başlayacak. Sanırım başlangıç için bu yeterli.

Arduino Kodu

//Çizgi İzleyen ve Engelden Kaçan Araba// 
//Blog: mucitpilot.blogspot.com
//Youtube: / MucitPilot

//#include<Servo.h> //servo kütüphanesini çağırıyoruz
//Servo serv; //Servoyu kullanmadığım için gölgeledim. isterseniz açabilirsiniz

#define SensorSol 12  //Çizgi sensörlerini tanımlıyoruz
#define SensorOrta 3
#define SensorSag 2

#define MotorL1 4  // motor pinlerini tanımlıyoruz
#define MotorL2 5 
#define MotorLE 6

#define MotorR1 7
#define MotorR2 8
#define MotorRE 9

int echoPin=11;  //Ultrasonik sensörün echo pini Arduino'nun 11.pinine
int trigPin=13; //Ultrasonik sensörün trig pini Arduino'nun 13.pinine tanımlandı.
long olcum; 
long cm; // sensörümüzden okuduğumuz uzaklık için değişken

boolean sagda=0; 
boolean solda=0;
boolean ortada=0;

void ileri(){  // Robotun ileri yönde hareketi için fonksiyon tanımlıyoruz.

  digitalWrite(MotorR1, HIGH); // Sağ motorun ileri hareketi aktif
  digitalWrite(MotorR2, LOW); // Sağ motorun geri hareketi pasif
  analogWrite(MotorRE, 80); // Sağ motorun hızı 

  digitalWrite(MotorL1, HIGH); // Sol motorun ileri hareketi aktif
  digitalWrite(MotorL2, LOW); // Sol motorun geri hareketi pasif
  analogWrite(MotorLE, 80); // Sol motorun hızı 
  
  
}
void sag(){ // Robotun yerinde sağa dönme hareketi için fonksiyon tanımlıyoruz.

  digitalWrite(MotorR1, LOW); // Sağ motorun ileri hareketi pasif
  digitalWrite(MotorR2, HIGH); // Sağ motorun geri hareketi aktif
  analogWrite(MotorRE, 250); // Sağ motorun hızı 

  digitalWrite(MotorL1, HIGH); // Sol motorun ileri hareketi aktif
  digitalWrite(MotorL2, LOW); // Sol motorun geri hareketi pasif
  analogWrite(MotorLE, 250); // Sol motorun hızı 
    
}

void sol(){ // Robotun yerinde sola dönme hareketi için fonksiyon tanımlıyoruz.

  digitalWrite(MotorR1, HIGH); // Sağ motorun ileri hareketi aktif
  digitalWrite(MotorR2, LOW); // Sağ motorun geri hareketi pasif
  analogWrite(MotorRE, 250); // Sağ motorun hızı 

  digitalWrite(MotorL1, LOW); // Sol motorun ileri hareketi pasif
  digitalWrite(MotorL2, HIGH); // Sol motorun geri hareketi aktif
  analogWrite(MotorLE, 250); // Sol motorun hızı 
  
}
void dur(){ // Robotun durması için fonksiyon tanımlıyoruz.

  digitalWrite(MotorR1, HIGH);
  digitalWrite(MotorR2, LOW);
  digitalWrite(MotorRE, LOW);

  digitalWrite(MotorL1, HIGH);
  digitalWrite(MotorL2, LOW);
  digitalWrite(MotorLE, LOW);
  
}
void geri(){ // Robotun geri hareketi için fonksiyon tanımlıyoruz.

  digitalWrite(MotorR1, LOW); // Sağ motorun ileri hareketi pasif
  digitalWrite(MotorR2, HIGH); // Sağ motorun geri hareketi aktif
  analogWrite(MotorRE, 100); // Sağ motorun hızı

  digitalWrite(MotorL1, LOW); // Sol motorun ileri hareketi pasif
  digitalWrite(MotorL2, HIGH); // Sol motorun geri hareketi aktif
  analogWrite(MotorLE, 100); // Sol motorun hızı
  
}

void setup() {  //programımız başlıyor. Burası 1 defa çalışacak
 //pinlerimizin I/O durumunu tanımlıyoruz
  pinMode(echoPin, INPUT);
  pinMode(trigPin, OUTPUT);
  
  pinMode(SensorSol, INPUT);
  pinMode(SensorOrta, INPUT);
  pinMode(SensorSag, INPUT);

  pinMode(MotorR1, OUTPUT); 
  pinMode(MotorR2, OUTPUT);

  pinMode(MotorL1, OUTPUT);
  pinMode(MotorL2, OUTPUT);


  Serial.begin(9600); // Bilgisayara veri göndermek için iletişim başlatıyoruz
  
}

void loop() {

//ultrasound sensör için gerekli işlemler
digitalWrite(trigPin, LOW); // sensör ilk başta ses yollamasın
delayMicroseconds(5);
digitalWrite(trigPin, HIGH); // Burada ses dalgasını yolluyoruz
delayMicroseconds(10);
digitalWrite(trigPin, LOW); // Tek bir ses dalgası yolladık
olcum = pulseIn(echoPin, HIGH); // Eğer ses geri dönerse echo pinine geri dönecektir.
// Burada geçen süreyi hesaplıyoruz.
cm= olcum /29.1/2; // ölçüm değerini zamandan -> CM’ye çeviriyoruz 


//eğer 10cmden yakında bir cisim ölçmüş ise
if (cm <10){

    dur(); //duruyor
    delay(250);
    geri(); //geri gidiyor
    delay(1000);

  }


//çizgi sensörlerinden veri okuyp hangisinin çizgiyi gördüğüne bakıyoruz. Bizim sensörlerimiz //çizgiyi görünce 1 çıkışı veriyor.
 if(digitalRead(SensorSol) == 0 && digitalRead(SensorOrta) == 1 && digitalRead(SensorSag) == 0){  // Orta sensör çizgiyi gördüğünde robot ileri gitsin.
    ileri();
  }

 else if(digitalRead(SensorSol) == 0 && digitalRead(SensorOrta) == 1 && digitalRead(SensorSag) == 1){  //Orta ve Sağ sensör çizgiyi gördüğünde robot sağa dönsün.
    sag();
  }
  
  else if(digitalRead(SensorSol) == 0 && digitalRead(SensorOrta) == 0 && digitalRead(SensorSag) == 1){  //Sadece  Sağ sensör çizgiyi gördüğünde robot sağa dönsün.
    sag();
  }

  else if(digitalRead(SensorSol) == 1 && digitalRead(SensorOrta) == 0 && digitalRead(SensorSag) == 0){  // Sadece sol sensör çizgiyi gördüğünde robot sola dönsün.
    sol();
  }

   else if(digitalRead(SensorSol) == 1 && digitalRead(SensorOrta) == 1 && digitalRead(SensorSag) == 0){  // Sol sensör çizgiyi gördüğünde robot sola dönsün.
    sol();
  }

  else if(digitalRead(SensorSol) == 0 && digitalRead(SensorOrta) == 0 && digitalRead(SensorSag) == 0){  // sensör görmüyorsa robot çizgiyi bulana kadar ileri gitsin.
    ileri();
  }

 else { //yukarıdaki şartların dışında dursun
  dur();
 }




Test Videosu





Yorumlar

  1. merhaba hayirli isler. elin koluna saglik cok guzel olmus
    sayenizde bilgi sahibi olmak. tesekkurler. bir istegin olursa cekilme.
    bende yardimi severim. 30 senedir elektronikle ugrasmak. hobbi olarak. robot yapmak. sayenizde
    allah isinizi rast getirsin. isvecten selamlar. bahaddin ates. kod degerlendim. hata vermedi.
    tesekkurler adresim- kizilkader@hotmail.com

    YanıtlaSil
  2. merhaba .elin koluna saglik yaptiginiz robotlar hepsi. calisiyor
    harika sayenizde. busuru robot yaptim. deniyecem.tesekurler
    allah size boll kazanclar versin

    YanıtlaSil

Yorum Gönder

Bu blogdaki popüler yayınlar

QTR-8A Kızılötesi Çizgi Sensörü Kullanımı ve Basit PID Çizgi İzleyen Robot Yapımı

A4988 Step Motor Sürücü Kartı ile NEMA Step Motor Kullanımı

Arduino ile ESP8266 Kullanımı ve İnternet Erişimi Serisi -1 (İnternet Üzerinden Veri Çekme)