Arduino Tabanlı Robot Kol

 Bu yazıda arduino kullanarak nasıl robot kol yapabileceği ile ilgili bilgiler vereceğim. Mekanik kısımlardan bağımsız olarak yazılan bu yazı, projenin sadece elektronik ve yazılım kısımlarını içermektedir.

Gerekli malzemeler

  • Arduino 
  • Servo motor 
  • 10K potansiyometre 
  • Led
  • Breadboard
  • Push buton
  • Pulldown için uygun direnç
  • Seçilen lede uygun değerde direnç
  • Güç kaynağı
  • Jumper kablo

Önyazı

 Yapımından bahsedeceğim robot kol, manuel olarak kontrol edilebilmesinin yanı sıra kaydedilen hareketleri bir döngü içerisinde tekrar edebilmektedir. 

 Anlatımda Arduino UNO modeli ve diğer bileşenlerden beşer tane kullanılmıştır. İhtiyacınıza göre arduino modelini ve bileşenlerin sayılarını değiştirebilirsiniz.

Devre şeması

Devremiz nasıl çalışır?

    Sistem potansiyometrelerden aldığı veri doğrultusunda motorlara pwm sinyal göndererek çıkış mili pozisyonlarını belirlemektedir. Robot kol önceden belirlenen pozisyonlara, belirlenen sırayla gitmesi ve bunu bir döngü halinde yapması için fiziksel olarak programlanabilmektedir. Mevcut kod 20 pozisyona kadar izin vermektedir fakat bu sayı ihtiyaca göre arttırılabilir yada azaltılabilir. Robotumuzun tekrarlayacağı her hareket potansiyometreler ile belirlenir ve 1 numaralı buton ile kaydedilir. Tüm pozisyonlar kaydedildikten sonra 2 numaralı butona basılarak loop başlatılır. 

Servoların bağlanması

   Servo motorlar yapıları gereği genellikle 180 derecelik bir dönüş açısı ile sınırlıdırlar. İçerlerinde bulunan ve motorun çıkış dişlisine bağlı olan potansiyometrenin aldığı değere göre bulundukları konumu bilebilirler. Servo motorların 3 adet pini bulunmaktadır. Bu pinler GND, Power(Güç) ve Sinyal pinleridir. Motorların güç ve torak bağlantıları harici güç kaynağına yapıldıktan sonra sinyal pini arduino üzerinde seçilen dijital pinlere bağlanır ve karttan motora pwm sinyal gönderilerek servo motorların istenilen konuma gitmesi sağlanır. Servo motorun kaç volt ile çalışacağı ve tam yükte ne kadar akım çekeceği, üretici tarafından paylaşılan datasheet dosyasından öğrenilmeli ve ona göre güç kaynağı seçilmelidir. 
   Arduino kullanarak servo motorları kontrol edebilmek için <Servo.h> kütüphanesini kodumuza eklememiz gerekmektedir. Ardından "Servo servo1, servo2, servo3..." şeklinde servolar tanımlanır. Buradaki servox gibi isimler tanımladığımız servoların adlarıdır. Ardından setup fonksiyonu içerisinde servox.attach(servonun bağlı olduğu pin numarası); fonksiyonu ile hangi servonun hangi pine bağlı olduğu kod üzerinde tanımlanır. Servolara karttan veri gönderileceğinden servo pinleri, setup fonksiyonu içerisinde, pinMode() fonksiyonu kullanılarak çıkış pini olarak tanımlanmalıdır. 



Potansiyometrelerin bağlanması

   Potansiyometreler belirli değerlerdeki ayarlı dirençlerdir. Bir potansiyometrenin kenarlardaki bacakları o potansiyometrenin maksimum ve sabit dirençli halidir. Orta bacak ise potansiyometreyi çevirdiğimizde ayarladığımız direnci veren bacaktır. Yani 10Kohm'luk bir potansiyometrenin dış bacakları 10Kohm değerini, orta bacak ise çevirildiği oranda 0-10Kohm arası değerleri gösterecektir. 
   Arduino ile kullanılırken dış bacaklara güç ve toprak bağlantıları yapılır ve orta bacak arduino üzerinde bulunan analog pinlerden seçilen birine bağlanılır. Sistemimiz potansiyometreden gelen bilgilere göre hareket edeceğinden ötürü potansiyometrelerin pinleri setup fonksiyonu içerisinde giriş pini olarak tanımlanmalıdır.

Ledlerin bağlanması

    Ledler en temelde birer diyotturlar ve akımı tek yönlü geçirirler. Bu nedenle devreye led bağlarken (+) ve (-) uçlarına azami dikkat edilmesi gerekir. Aksi takdirde ledlere zarar verebiliriz. 
    Her reknte ledin farklı karakteristik özellikleri vardır ve farklı voltajlarda çalışır. Fakat projelerimizde ledlere ayrı güç kaynağı bağlamak mühendisliğin 3E kuralına uymayacağından ve gereksiz olduğundan çalışacağımız voltaja uygun bir direnç seçilerek devremizde kullanabiliriz. Kullanılacak direncin hesaplanması şu şekildedir; 
Direncin değeri = (Sistemimizdeki voltaj - Ledin voltajı) / Ledin akımı
    Ledin (+) ucu arduinonun seçilen herhangi bir dijital pinine bağlanır diğer ucu da (GND) hattına bağlanır. Bu bağlantı yapılırken seçtiğimiz direnç, ledin (+) yada (-) ucu ile seri bağlanmalıdır. Kodumuzda ledlerin bağlandığı pinler çıkış pini olarak tanımlanır. 

Butonların bağlanması

   Push butonlar genellikle 4 bacaklı olur ve bu bacakların ikişer tanesi birbirine bağlıdır ve diğer ikişer tane birbirine bağlı değildir. Bağlı olmayan bacaklar butona basıldığında birbirine bağlanır. 
   Butonumuzun temas etmeyen iki bacağından bir tanesi arduino üzerinde seçilen bir dijital pine diğeri ise arduinonun güç hattına bağlanır. Burada dikkat edilmesi gereken husus, butonun (+) bacağı aynı zamanda bir pulldown direnci ile (GND) hattına bağlanmalıdır. Çünkü butona basıldıktan sonra butonu oluşturan iletkenler arasında bir akım indüklenir ve buton bırakılsa bile karta bağlı pinimize akım göndermeye devam eder. Bağlayacağımız pulldown direnci kısa devreye sebebiyet vermeyecek kadar büyük, indüktif akımın topraklanmasına engel olmayacak kadar küçük olmalıdır. Bu projede 10K değerine sahip pulldown dirençleri kullanılmıştır. Devremiz butondan bilgi alacağından ötürü setup fonksiyonu içerisinde butonun bağlı olduğu pin giriş pini olarak tanımlanmalıdır. 

Robotu çalıştıracak arduino kodu

Kodun açıklamaları ve detaylar kod içerisinde yorum satırlarında belirtilmiştir. Bu kod clean bir kod olmaktan çok uzaktır fakat çalışmaktadır. Yakın zamanda daha düzgün bir kod yazıp yayınlayacağım. Bu koda buradan ulaşılabilir.



#include <Servo.h> // Servo kontrolü için gerekli kütüphaneyi ekliyoruz.

Servo servo1, servo2, servo3, servo4, servo5; // Servolarımızın isimlerini tanımlıyoruz.


const int led1 = 7; 
const int led2 = 8;
const int led3 = 9;  // Bu kısımda ledlerimizin isimlerini tanımladık.  
const int led4 = 10; // Bunun yerine define'da kullanılabilir.
const int led5 = 11;

const int buton1= 12;
const int buton2 = 13; // Butonlarımızı tanımladık.

const int pot1 = A0;
const int pot2 = A1;
const int pot3 = A2; // Potanslarımızı tanımladık. 
const int pot4 = A3;
const int pot5 = A4;

int buton1d = 0;  // Butonların aldığı değerlere göre artıp azalacak değişkeler
int buton2d = 0;  // tanımlıyoruz. Bu kodun ilerleyen kısımlarında karşımıza çıkacak.

int pot1d;
int pot1a;
int pot2d;
int pot2a;
int pot3d; // Potansların alacağı değerler için ve bunları açıya çevirmek için 
int pot3a; // gerekli değişkenleri tanımlıyoruz.
int pot4d;
int pot4a;
int pot5d;
int pot5a;

int servo1poz[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
int servo2poz[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
int servo3poz[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
int servo4poz[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
int servo5poz[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};

/* Yukarıdaki kısımda servoların pozisyonlarını tutacak diziyi tanımlıyoruz.
Buradaki değerleri ben sıfırdan başlattım ama siz istediğiniz değerden başlatabilirsiniz.
Ama ilerde göreceğimiz switch-case yapısı içerisinde burada belirttiğimiz değer önem arz
edecektir. */

int x = 0; /* 3 milyon satır sonra ihtiyacımız olan bir değişken tanımladık.
              Eskiden bu değişkenleri en başta tanımlamak gibi anlamsız bir huyum vardı.
              Size böyle yapmamanızı öneririm. */

void setup(){

  servo1.attach(2);
  servo2.attach(3);
  servo3.attach(4); // Servoların bağlı olduğu pinleri tanımladık.
  servo4.attach(5);
  servo5.attach(6);
  
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT); // Servo pinlerimizi çıkış pini olarak tanımladık.
  pinMode(5, OUTPUT);
  pinMode(6, OUTPUT);
  
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(led3, OUTPUT); // Ledlerin bağlı olduğu pinleri çıkış olarak tanımladık.
  pinMode(led4, OUTPUT);
  pinMode(led5, OUTPUT);
  
  pinMode(buton1, INPUT);
  pinMode(buton2, INPUT); // Butonları giriş olarak tanımladık.
  
  pinMode(pot1, INPUT);
  pinMode(pot2, INPUT);
  pinMode(pot3, INPUT); // Potansiyometreleri giriş olarak tanımladık.
  pinMode(pot4, INPUT);
  pinMode(pot5, INPUT);
 
     Serial.begin(9600); // Seri haberleşmeyi 9600 bant hızında başlattık.
   
  }
   
    void loop(){
   
    pot1d = analogRead(pot1); 
    pot1a = map(pot1d, 0, 1023, 0, 180);
    pot2d = analogRead(pot2);
    pot2a = map(pot2d, 0, 1023, 0, 180);
    pot3d = analogRead(pot3);
    pot3a = map(pot3d, 0, 1023, 0, 180); // Analog pinlerden aldığımız 0-1023 arası 
    pot4d = analogRead(pot4);            // değeri potxd değişkenlerine eşitledik
    pot4a = map(pot4d, 0, 1023, 0, 180); // potxd değerini map fonksiyonu ile
    pot5d = analogRead(pot5);            // 0-180 aralığına getirdik ve bu değeri
    pot5a = map(pot5d, 0, 1023, 0, 180); // potxa değişkenlerine eşitledik.
    
    servo1.write(pot1a);
    servo2.write(pot2a);
    servo3.write(pot3a);   // Servolara potxa değerine gitmelerini söyledik.
    servo4.write(pot4a);
    servo5.write(pot5a);

    Serial.println("buton2d");  // Ekrana buton2'ye bağlı değişkenin değerini
    Serial.println(buton2d);    // basacak kod.
         

          
      if(digitalRead(buton1) == HIGH && digitalRead(buton2) == LOW){
      
         // Eğer buton1'e basılıysa ve buton2 basılı değilse;

        buton1d++; // Buton1d'yi arttır.
        delay(300); // Kod servoların maksimum hızından hızlı çalışacağından araya
                    // delay ekliyoruz. 300ms bekletecek kod.
          
           switch(buton1d){ // Buton1d'nin değerine göre hareket eden switch fonksiyonu.
           /* Aşağıda case kısmı her buton1'e her basılışta hareketi kadetmektedir. 
           Aynı zamanda ledlerimize sinyal göndererek butona basıldığına dair görsel
           referans sağlamaktadır. */
         
           case 1:
             servo1poz[0] = pot1a;             
             servo2poz[0] = pot2a;             
             servo3poz[0] = pot3a;             
             servo4poz[0] = pot4a;             
             servo5poz[0] = pot5a;             
             digitalWrite(led2, HIGH);
             break;
           case 2:
             servo1poz[1] = pot1a;             
             servo2poz[1] = pot2a;             
             servo3poz[1] = pot3a;               
             servo4poz[1] = pot4a;                   
             servo5poz[1] = pot5a;                  
             digitalWrite(led3, HIGH);
             digitalWrite(led2, LOW);             
             break;
           case 3:
             servo1poz[2] = pot1a;             
             servo2poz[2] = pot2a;              
             servo3poz[2] = pot3a;             
             servo4poz[2] = pot4a;             
             servo5poz[2] = pot5a;             
             digitalWrite(led4, HIGH);
             digitalWrite(led3, LOW);
             break;
           case 4:
             servo1poz[3] = pot1a;            
             servo2poz[3] = pot2a;             
             servo3poz[3] = pot3a;             
             servo4poz[3] = pot4a;             
             servo5poz[3] = pot5a;
             digitalWrite(led5, HIGH);       
             digitalWrite(led4, LOW);      
             break;
           case 5:
             servo1poz[4] = pot1a;
             servo2poz[4] = pot2a;
             servo3poz[4] = pot3a;  
             servo4poz[4] = pot4a;
             servo5poz[4] = pot5a;
             digitalWrite(led2, HIGH);  
             digitalWrite(led5, LOW);
             digitalWrite(led3, HIGH);           
             break;
           case 6:
             servo1poz[5] = pot1a;
             servo2poz[5] = pot2a;
             servo3poz[5] = pot3a;  
             servo4poz[5] = pot4a;
             servo5poz[5] = pot5a;
             digitalWrite(led4, HIGH);  
             digitalWrite(led3, LOW);           
             break;
           case 7:
             servo1poz[6] = pot1a;
             servo2poz[6] = pot2a;
             servo3poz[6] = pot3a;  
             servo4poz[6] = pot4a;
             servo5poz[6] = pot5a;
             digitalWrite(led5, HIGH);  
             digitalWrite(led4, LOW);           
             break;
           case 8:
             servo1poz[7] = pot1a;
             servo2poz[7] = pot2a;
             servo3poz[7] = pot3a;  
             servo4poz[7] = pot4a;
             servo5poz[7] = pot5a;
             digitalWrite(led4, HIGH);  
             digitalWrite(led2, HIGH);
             digitalWrite(led5, LOW); 
             digitalWrite(led3, HIGH);          
             break;
           case 9:
             servo1poz[8] = pot1a;
             servo2poz[8] = pot2a;
             servo3poz[8] = pot3a;  
             servo4poz[8] = pot4a;
             servo5poz[8] = pot5a;
             digitalWrite(led2, HIGH);
             digitalWrite(led3, HIGH);
             digitalWrite(led4, LOW);
             digitalWrite(led5, HIGH);
             break;   
           case 10:
             servo1poz[9] = pot1a;
             servo2poz[9] = pot2a;
             servo3poz[9] = pot3a;  
             servo4poz[9] = pot4a;
             servo5poz[9] = pot5a;
             digitalWrite(led2, HIGH);
             digitalWrite(led3, HIGH);
             digitalWrite(led4, HIGH);
             digitalWrite(led5, HIGH);
             delay(300);
             digitalWrite(led2, LOW);
             digitalWrite(led3, LOW);
             digitalWrite(led4, LOW);
             digitalWrite(led5, LOW);
             delay(300);
             digitalWrite(led2, HIGH);
             digitalWrite(led3, HIGH);
             digitalWrite(led4, HIGH);
             digitalWrite(led5, HIGH);
             break;
           case 11:
             servo1poz[10] = pot1a;
             servo2poz[10] = pot2a;
             servo3poz[10] = pot3a;  
             servo4poz[10] = pot4a;
             servo5poz[10] = pot5a;
             digitalWrite(led3, LOW);
             digitalWrite(led4, LOW);
             digitalWrite(led5, LOW);
             break;           
           case 12:
             servo1poz[11] = pot1a;
             servo2poz[11] = pot2a;
             servo3poz[11] = pot3a;  
             servo4poz[11] = pot4a;
             servo5poz[11] = pot5a;
             digitalWrite(led3, HIGH);
             digitalWrite(led2, LOW);
             break;
           case 13:
             servo1poz[12] = pot1a;
             servo2poz[12] = pot2a;
             servo3poz[12] = pot3a;  
             servo4poz[12] = pot4a;
             servo5poz[12] = pot5a;
             digitalWrite(led4, HIGH);
             digitalWrite(led3, LOW);
             break;
           case 14:
             servo1poz[13] = pot1a;
             servo2poz[13] = pot2a;
             servo3poz[13] = pot3a;  
             servo4poz[13] = pot4a;
             servo5poz[13] = pot5a;
             digitalWrite(led5, HIGH);
             digitalWrite(led4, LOW);
             break;           
           case 15:
             servo1poz[14] = pot1a;
             servo2poz[14] = pot2a;
             servo3poz[14] = pot3a;  
             servo4poz[14] = pot4a;
             servo5poz[14] = pot5a;
             digitalWrite(led4, HIGH);
             digitalWrite(led3, HIGH);
             digitalWrite(led2, HIGH);
             break;
           case 16:
             servo1poz[15] = pot1a;
             servo2poz[15] = pot2a;
             servo3poz[15] = pot3a;  
             servo4poz[15] = pot4a;
             servo5poz[15] = pot5a;
             digitalWrite(led5, LOW);
             digitalWrite(led4, LOW);
             digitalWrite(led3, LOW);
             break;
           case 17:
             servo1poz[16] = pot1a;
             servo2poz[16] = pot2a;
             servo3poz[16] = pot3a;  
             servo4poz[16] = pot4a;
             servo5poz[16] = pot5a;
             digitalWrite(led2, LOW);
             digitalWrite(led3, HIGH);
             break;           
           case 18:
             servo1poz[17] = pot1a;
             servo2poz[17] = pot2a;
             servo3poz[17] = pot3a;  
             servo4poz[17] = pot4a;
             servo5poz[17] = pot5a;
             digitalWrite(led3, LOW);
             digitalWrite(led4, HIGH);
             break;
           case 19:
             servo1poz[18] = pot1a;
             servo2poz[18] = pot2a;
             servo3poz[18] = pot3a;  
             servo4poz[18] = pot4a;
             servo5poz[18] = pot5a;
             digitalWrite(led4, LOW);
             digitalWrite(led5, HIGH);
             break;
           case 20:
             servo1poz[19] = pot1a;
             servo2poz[19] = pot2a;
             servo3poz[19] = pot3a;  
             servo4poz[19] = pot4a;
             servo5poz[19] = pot5a;
             digitalWrite(led5, LOW);
             digitalWrite(led2, HIGH);
             delay(300); 
             digitalWrite(led3, HIGH);
             delay(300);
             digitalWrite(led4, HIGH);
             delay(300);
             digitalWrite(led5, HIGH);
             break;
           case 21:
             servo1poz[20] = pot1a;
             servo2poz[20] = pot2a;
             servo3poz[20] = pot3a;  
             servo4poz[20] = pot4a;
             servo5poz[20] = pot5a;
             digitalWrite(led5, LOW);
             digitalWrite(led4, LOW);
             digitalWrite(led3, LOW);
             break;
           case 22:
             servo1poz[21] = pot1a;
             servo2poz[21] = pot2a;
             servo3poz[21] = pot3a;  
             servo4poz[21] = pot4a;
             servo5poz[21] = pot5a;
             digitalWrite(led3, HIGH);
             break;
           case 23:
             servo1poz[22] = pot1a;
             servo2poz[22] = pot2a;
             servo3poz[22] = pot3a;  
             servo4poz[22] = pot4a;
             servo5poz[22] = pot5a;
             digitalWrite(led4, HIGH);
             break;
           case 24:
             servo1poz[23] = pot1a;
             servo2poz[23] = pot2a;
             servo3poz[23] = pot3a;  
             servo4poz[23] = pot4a;
             servo5poz[23] = pot5a;
             digitalWrite(led5, HIGH);
             break;
           case 25:
             servo1poz[24] = pot1a;
             servo2poz[24] = pot2a;
             servo3poz[24] = pot3a;  
             servo4poz[24] = pot4a;
             servo5poz[24] = pot5a;
             digitalWrite(led4, LOW);
             digitalWrite(led3, LOW);
             delay(300);
             digitalWrite(led3, HIGH);
             digitalWrite(led4, HIGH);
             digitalWrite(led2, LOW);
             digitalWrite(led5, LOW);
             delay(300);
             digitalWrite(led5, HIGH);
             digitalWrite(led2, HIGH);
             digitalWrite(led3, LOW);
             digitalWrite(led4, LOW);
             delay(300);
             digitalWrite(led3, HIGH);
             digitalWrite(led4, HIGH);
             digitalWrite(led5, LOW);
             digitalWrite(led2, LOW);
             delay(300);
             digitalWrite(led4, LOW);
             digitalWrite(led3, LOW);
             delay(300);
             digitalWrite(led3, HIGH);
             digitalWrite(led4, HIGH);
             digitalWrite(led2, LOW);
             digitalWrite(led5, LOW);
             delay(300);
             digitalWrite(led5, HIGH);
             digitalWrite(led2, HIGH);
             digitalWrite(led3, LOW);
             digitalWrite(led4, LOW);
             delay(300);
             digitalWrite(led3, HIGH);
             digitalWrite(led4, HIGH);
             digitalWrite(led5, LOW);
             digitalWrite(led2, LOW);
             delay(300);
           break;
            
         }
        
      }
      
      if(digitalRead(buton2) == HIGH && digitalRead(buton1) == LOW) {
      
         // Eğer buton2 basılı ve buton1 basılı değil ise; 
 
        buton2d++; // buton2d değişkenini 1 arttır.
               
      Serial.println("buton2'ye basildi"); // Görsel referans için ekrana bunu bas.
        Serial.println(buton2d); // Görsel referans için buton2d'nin değerini ekrana bas.
      }
      
     if(buton2d > 0 ) { // Eğer buton2d 0'dan büyük ise
      
      for(x = 0; x < buton1d ; x++){ 
      
      /* Yıllar önce tanımladığımız x değişkenini 0'dan başlat, x'in değeri buton1d'den
      küçük olduğu sürece bu döngüyü tekrarla ve her seferinde x'i 1 arttır. */


        if (buton1d > 25){
        
          buton1d = 25; // Eğer buton1d 25'ten büyük ise buton1d'yi 25'e eşitle.
          
                }
        
      
        servo1.write(servo1poz[x]);
        delay(500);
        servo2.write(servo2poz[x]);
        delay(500);
        servo3.write(servo3poz[x]); // Servolara önceden belirtilen konumlara
        delay(500);                 // gitmesini söyleyen kod.
        servo4.write(servo4poz[x]);
        delay(500);
        servo5.write(servo5poz[x]);
        delay(500);
        
         }
        }
      if (digitalRead(buton1) == HIGH && digitalRead(buton2) == HIGH ) {
        // Eğer iki butonda basılı ise
        
        digitalWrite(led1, LOW);
        digitalWrite(led2, LOW);
        digitalWrite(led3, LOW); // Tüm ledleri söndür.
        digitalWrite(led4, LOW);
        digitalWrite(led5, LOW);
        
        servo1.write(pot1a);
        servo2.write(pot2a);
        servo3.write(pot3a); // Servoları potans konumlarına getir. 
        servo4.write(pot4a);
        servo5.write(pot5a);
        
        x = 0;
                       // Değişkenleri sıfırla.
        buton1d = 0;
        buton2d = 0;
        }
        
     
       
     delay(100);       // 100ms bekle.
     }