7 Ocak 2015 Çarşamba

ARDİUNO VE PROCESSING İLE BASİT BİR RADAR YAPMA



Günümüz teknolojisi her gün kendini yenilemekte ve bu nedenle çevremizde olan bütün elektronik eşyaların hepsi akıllı hale geldi. O eşyaları akıllı yapan şey yani onlara zekayı veren mikrodenetleyicilerdir. Eğer onlar olmasa o eşyalara şimdi olduğu gibi akıllı olmazlardı. Aslında akıllı diyoruz ama mikrodenetliyiclere aklı veren de yapması gereken görevleri veren de bizleriz. Onlar bizsiz bir hiçler aslında. Sadece onlar bizden çok daha hızlıdırlar iş yapma konusunda. Bu özelliği sayesinde etrafımızı bu elektronik eşyalar sardı.   

Piyasada bir çok Ardiuno kiti mevcuttur. Ben bu çalışmamda Ardiuno Uno kitini tercih ettim.
      

 Son zamanlarda en çok kullanılan bir mikrodenetleyici kiti olan Ardiuno ile basit radar projesi tasarladım. Bu çalışmada Ardiuno kullanmamın sebebi programlama dili basit ve kolay anlaşılır oluşu ve Ardiuno'nun kaynaklarına kolayca erişilebilir oluşundan dolayı bu çalışmamda Ardiuno kullanmayı tercih ettim. Aynı zaman da yeni keşfettiğim ara yüz tasarlama programı sayesinde bilgisayar ile Ardiuno arasında görsel iletişimi sağladım. Ardiuno kadar oldukça Processing programının dili basittir. Tabi zor yanları da vardır.



  Radar yapmak için nesne ile mesafe sensörü  arasında mesafe ölçmek lazım bunun için bize gerekli olan sensörümüz SRF04. Aşağıdaki resimde olan sensör SRF04 için bir örnektir. Üzerinde bir alıcı bir de verici sensör vardır. Mesafe sensörü mesafeyi ölçerken verici kısımdan bir ses sinyali gönderir ve sonra o ses sinyali nesneye çarpar ve alıcı sensöre geri döner işte bu ses sinyalinin nesneye gidiş ve geliş süresini ardiuno ile hesaplayarak nesne ile sensör arasındaki mesafeyi ölçeriz.

    
 
 

  Bu sensörün 4 adet pini mevcuttur. İkisi GND ve VCC dir. +5V ile beslenmiştir. Diğer ikisi ise TRIG ve ECHO pinidir. Bu pinler bize mesafeyi söyler. Çalışma yapısı şöyledir;


Zaman çizelgesi

  Yukarıdaki zaman diyagramında da görüldüğün gibi ilk olarak Ardiuno'dan mesafe sensörünün TRİG pinine 10us saniye zaman aralığında bir tane tetikleme sinyali gönderilir sonra sensörün verici kısmı sayesinde 8 darbelik 'sonic burst' ses sinyali ortama, ileriye doğru gönderilir. Sonraki kısım mesafe sensör'ün Echo pininden Ardiuno sayesinde dinlemesi gerekiyor sensör ile nesne arasındaki süreyi. Bu süre en erken 100us ile 10ms arasında olamalıdır. Eğer değilse mesafe sensörün önünde herhangi bir engel yok anlamına geliyor. Eğer engel ise Echo pininden aldığımız mesafeye dönüştürme zamanı geliyor demek. Verilecek olan kodda bu işlem verilmiş olacaktır.

  Buraya kadar sadece nesne ile mesafe sensörü arasında olan mesafeyi nasıl bulacağımız anlatmaya çalıştım. Şimdi biz eğer bir radar yapmak istiyorsak etrafa hakim olmalıyız yani etrafı 360 derece taramalıyız ve bunun için bize gerekli olan şey bir servo motor. Bu motor hakkında daha önce nasıl çalıştığını anlatmıştım SERVO MOTOR KONTROL-1 çalışmamda. Mesafe sensörü servo motor üstüne doğru şekilde yerleştirilmiştir. Benim elimdeki servo 180 derece döndüğünden sadece etrafı 180 derece tarayabildim.

Artık şimdi elimde hem nesne ile mesafe sensör arasındaki uzaklık sinyali hem de servonun hangi açıda durduğu hakkında bilgi var işte bunları Ardiuno Serial Port yardımıyla bilgisayara oradan Processing dili ile tasarlamış olduğum ara yüze gönderdim.


Ardiuno kodu;


#include<Servo.h>
#define ECHOPIN 7  // Pinleri önceden tanımladım
#define TRIGPIN 8

const int servoCikis=9;
int servosagsol=0;
Servo servoMotor ;
unsigned long anlik_mesafe=0;

void setup(){
      Serial.begin(9600);
      pinMode(ECHOPIN, INPUT);
      pinMode(TRIGPIN, OUTPUT);
      servoMotor.attach(servoCikis);
}

void loop(){

    servoMotor.write(0); // servo başlangı. konumına getirildir yani 0 dereceye.

    for(servosagsol=0;servosagsol<=179;servosagsol++){
         servoMotor.write(servosagsol); //servo soldan sağa git
         GonderPc(mesafem() , servosagsol);   // alt programa gönderdi.
         delay(5);
    } 

    for(servosagsol=179;servosagsol>=0;servosagsol--){
         servoMotor.write(servosagsol);//servo sağadan sola git
         GonderPc(mesafem() , servosagsol);   
         delay(5);
    }
         
}

void GonderPc (int DISTANCE , int POS){
   Serial.print("b");Serial.print(DISTANCE);
   Serial.print(","); Serial.println(POS);
   delay(100);
}

float mesafem(){
 
        digitalWrite(TRIGPIN,LOW);
        delayMicroseconds(2);
        digitalWrite(TRIGPIN,HIGH);
        delayMicroseconds(10);// Kaynaklara göre en az 10us saniye olamalı
        digitalWrite(TRIGPIN,LOW);
   
        float echo_zamani=pulseIn(ECHOPIN,HIGH);// 1 kalma süresi ölçüldü
                                                //engelle  arasındaki zaman   
       anlik_mesafe=echo_zamani/58; //cm çevirmek için 58 bölündü.
                                  
  return(anlik_mesafe);   

}

Processing Kodu;


import processing.serial.*;// serial port kütüphanesi eklendi

Serial benimport;  // tanımlama yapıldı.
int servpozisyon = 0; // SERVODAN GELEN DEĞER
int nesneMesafe = 0; // MESAFE SENSÖRÜNDEN GELEN DEĞER

void setup(){
  int r;
  int S_L = 1000;
  r = S_L / 2;
 
   size(1040,550);// AÇILAN PENCERENİN BOYUTU
     
   PFont benimFontum;
   benimFontum = createFont("Verdana", 16); // TEXT için yapılandırmalar. Karekterin boyutu ayarlanır değer degiştirilerek.
   textFont(benimFontum);
 
   benimport = new Serial(this, "COM7", 9600); // ÖN AYARLAR HABERLEŞME İÇİN
   benimport.bufferUntil('\n');
  
   background(100,0,255);   // ARKA PLAN RENGİM
   fill(10,200,300);
   ellipse(500,500,1000,1000);
   ellipse(500,500,900,900);
   ellipse(500,500,800,800);
   ellipse(500,500,700,700);
   ellipse(500,500,600,600);
   ellipse(500,500,500,500);
   ellipse(500,500,400,400);
  

   for (int i = 0; i <= 6; i++) {
     strokeWeight(2); // çizgileri kalınlaştırma
     stroke(0,120,0); // çizgilerin rengini ayarla
     line(r, r, r + cos(radians(180+(30*i)))*S_L /2, r + sin(radians(180+(30*i)))*S_L /2);
     fill(255, 255, 255);
     noStroke();
     text(Integer.toString(0+(30*i)), r + cos(radians(180+(30*i)))*S_L /2, r + sin(radians(180+(30*i)))*S_L /2, 60, 60); 
  }
 

  text("0 cm",   500, 480, 250, 50);
  text("10 cm",  500, 430, 250, 50);
  text("20 cm",  500, 380, 250, 50);
  text("30 cm",  500, 330, 250, 50);
  text("40 cm",  500, 280, 250, 50);
  text("50 cm",  500, 230, 250, 50);
  text("60 cm",  500, 190, 250, 50);
  text("70 cm",  500, 140, 250, 50);
  text("80 cm",  500, 90, 250,  50);
  text("90 cm",  500, 40, 250,  50);
 
   fill(247, 240, 25);//http://www.rapidtables.com/web/color/RGB_Color.htm
   noStroke(); //çizelecek nesnenin çizim rengini belirler
   text("http://muhhakanaydin.blogspot.com.tr", 335, 500, 400, 50);
   text("MUH. HAKAN AYDIN", 335, 520, 500, 40);
  
  fill(0);
  text("HEDEF", -450, -450);
  fill(30,20,30);
  ellipse(-460,-456,10,10);

}


void draw(){
         
        fill(255);
        text("AÇI: "    +Integer.toString(servpozisyon), 40, 500, 400, 25);   text("DERECE", 200, 500, 400, 50);   //Integer.toString(A); A sayınını Stringe çevir
        text("MESAFE: "+Integer.toString(nesneMesafe), 40, 520, 400, 25);  text("cm", 200, 520, 400, 50);       // text(string, x, y, genişlik, yükseklik)
       
 
        fill(30,20,30);// çizilecek oland daire içini fill komutu ile renklendir.
        translate(500,500);// yarım daire için merkezlendirme yapıldı
        point (0,0);
        ellipse(nesneMesafe * -1*cos(servpozisyon*PI/180) , -1*nesneMesafe * sin(servpozisyon*PI/180) , 5,5);  /* Mesafe ile sensöründen yansıyan engelin yeri daire belirlenir */   
      
    
}
void serialEvent (Serial benimport) {   // PC İLE ELEKTRONİK KARTIN HABERLEŞME PROGRAMI
 
  String gelen_datam = benimport.readStringUntil('\n');//Genellikle string ifadeler null(\n) karakteriyle sonlanır
                                                       // yeni string ifadesi geldiğinde eskiyle yeninin arasında bir ilişki kurmak için  
 
  if (gelen_datam != null) { // eger bitiş yoksa. String karakterleri null ile biter.
   
    gelen_datam = trim(gelen_datam); // whitespace kurtulmak için.
   
    String nesMesafe = gelen_datam.substring(1, gelen_datam.indexOf(",")); // STRİNG İÇİN BAŞLANGIÇ VE BİTİŞ PARAMETRESİ.    
                                                                  
    String servoPos = gelen_datam.substring(gelen_datam.indexOf(",")+1, gelen_datam.length()); //indexOf(","); virgül karakterin nerde oldugunu bulur. 
   
    servpozisyon = Integer.parseInt(servoPos);//Stringleri integere bir sayıya çervirmek

    nesneMesafe = 5*Integer.parseInt(nesMesafe);//için bu komutlar yazıldı yoksa üzerinde
                                              //işlem yapamazdık. 
                                         
                                        
  } 
  
}

Çalışma Videosu






 


Hiç yorum yok:

Yorum Gönder