Kütüphanesiz Servo Motor Kullanımı ( Arduino, PIC )

Servo motorlar için arduinoda, genelde kütüphane kullanılır. Diğer dillerde de kütüphane kullanımına gereksinim duyuluyor.
Biraz dikkatli baktığınızda LED çalıştırmaktan farkı olmadığını görebileceksiniz.
Arduino ve diğer işlemciler ile yapılan, plastik robotik sistemlerde, genelde mini servo motor SG90 kullanılıyor. Bu tip motor, plastik dişlilere sahip olsa da MG (Metal Gear) Metal dişli olanları da vardır.

Bu motorları kontrol etmek için çalışma sistemine yakından bakalım.
Çalışma Sistemini, 1ms, 2ms arasında değişen HIGH seviyesini vermek ve sonrasında 20ms tamamlanasıya kadar LOW  seviyesinde beklemek, olarak özetleyebiliriz.

Resimdeki gibi -90, 0 ,+90 olmak üzere 180 derecelik bir hareket kabiliyeti vardır. Resimdeki açılar 0, 90, 180 diyor. Bunu nasıl kabul ederseniz o şekilde söyleyebilirsiniz.

Bu standart sistemdir. Gerçek devrede ise SG90 için 500us ve 2500us arasındadır.

Şimdi de mantık sırasına bakalım.
Öncelikle kaç derece dönmesini istiyorsak o kadar milisaniyeyi hesaplayıp,en küçük değer olan 1ms yi üzerine eklediğimizde HIGH seviyesini halletmiş olacağız. LOW seviyesi de 20ms den az olmamalı.
Arduino için örnek satır.
for (int i = 0; i <=3; i++) {
digitalWrite (motor1_pin,HIGH);
delayMicroseconds(1500);
digitalWrite (motor1_pin,LOW);
delay(20);
}

PICBASIC için örnek satır.  ( Arduinoda gerçek devrede For döngüsü 3 kez yetiyordu, fakat 12f683 ile yaptığımda yetmedi. 5 kez tekrar ettiğimde sorunsuz 0-180 derece arasında dönebiliyor.)
for tt=1 to 5
portb=%00000001
pauseus 1500
portb=%00000000
pause 20
next
Gönderilecek sinyalin 3 kez tekrarlanması ile doğru çalışma şartlarını sağlamış oluruz. 

Yukarıdaki satırlar ile motorunuz, resimden de gördüğünüz gibi, 90°  de duracaktır.
Bu satırlardaki iş yapma zamanını değiştirdiğinizde, aradaki dereceleri de ayarlayabilirsiniz. Mesela 1500us yerine 1200us verebilirsiniz. Ya da 1800us verebilirsiniz.Bununla birlikte şunu da göz ardı etmeyin belli bir pine bağlı kalmanıza gerek yok. Dijital olan tüm çıkışlara bağlayabilirsiniz. PWM pinine bağlamak zorunda değilsiniz. Yada yazılımsal pwm elde etmek zorunda değilsiniz. 

Şunu da unutmamalıyız. burada verilen delay 20 ya da pause 20, verdiğiniz komutun işlenme süresidir. Fakat bir kere değiştirdikten sonra tekrar konumu değiştirmek istiyorsanız bunu ne kadar sıklıkla yapabilirsiniz. Bunu da videoda görebileceğiniz gibi motor hızlı olmadığından verdiğiniz en uzun mesafe, iki nokta arası 0°-180° arasıdır. 0° den 180° ye gideceği süre bunda etkilidir. Bu süre de gerçek ölçümlerde 400ms civarındadır. Şayet 3° – 5° lik konum değişikliği yapıyorsanız elbette ki bu süre, 400ms den çok daha aşağı olacaktır. Bu sizin deneyiminize ve hassaslığınıza göre değişebilir. 
KÜTÜPHANEDE bu tip bir problem yoktu diyorsanız, mantık hepsinde aynıdır. Kütüphane ya bunu sizin için yapıyor, ya da daha kaba işlemlerde kullandığınız için bunu fark etmediniz.
Videoda bu durumu görebileceksiniz. İşlemci ne kadar hızlı olursa olsun motorun istenen noktaya gelmesi yavaş olacaktır ve işlemci beklemek zorundadır. 

Not: Bazı motorlar 20ms den fazla bir LOW seviyesi isteyebilir bu zamanı 25ms gibi düşünebilirsiniz. Bir yerlerde 20ms de bir yenilenmesi gerek dese de, 3 kez tekrarlanması, 0° den 180° ye direkt git dediğinizde bile yetiyor. Zaten örnek program satırlarımızda da 3 kez tekrarlama gösteriliyor. 

Bununla birlikte bir de motorlara güç verdiğinizde, başlangıç konumuna dönmek isteyebilir. Bunu engellemek için programın başında hangi pozisyonda kalmasını istiyorsanız o satırları yazıp. Başlangıç konumunu seçmiş olacaksınız.

Bu şekilde birden fazla motor kullanabilirsiniz. Fakat şunu da unutmayın, motor güç bağlantılarını arduinodan almayın. Çünkü bazı zamanlarda birden fazla motor kontrol etmek isteyebilirsiniz ve hepsinin birden hareket etmeye başladığını düşünürseniz arduinodan aldığınız güç yetmeyebilir. Motorlar için ayrı bir kaynak kullanacaksanız da, Proteus ta gördüğünüz çizimlerdeki gibi,  ikinci kaynağın, GND ucunu, İşlemcinizin ya da Arduinonun güç kaynağının GND sine bağlayın.

Ayrıca bunu da dikkate almanız lazım. Sıfır ve 180 derecede fark edebileceğiniz bir durum söz konusu. Özellikle arduinoda digitalwrite komutunun işlenmesi zamanı var. Komut seviyesi HIGH olurken ve LOW olurken komut gecikmesi de bu zamanın içerisindedir. Tam 1500us verdim, derken komutta birkaç us fazlalık olup tam sıfırda duramayabilir. Bundan dolayı kalibrasyon yapmanız gerekebilir. Bu süreyi en aza indirmek isterseniz, En iyisi Assembler ile yazmak. Bu, komut gecikmesini en aza indirir. Ya da arduino ile yazıyorsanız, portlara direkt komut vererek yazmanız bir nebze daha hızlı olur.  Yine de hassas işleriniz için kullanıyorsanız, kalibrasyon yapmanız gerekecektir.
KÜTÜPHANE kullansam bu olmazdı diyorsanız. Elbette onda da kalibrasyon ihtiyacı olacaktır. Sadece hassas ayar yapmadığınız için buna gerek duymamışınızdır.

KÜTÜPHANE KULLANSAM BUNLARA DİKKAT ETMEDEN ÇALIŞIRIM DİYORSUNUZDUR. Tabii ki dikkat etmeden çalışabilirsiniz. Fakat şunu unutmayın ki, Kütüphane kullansanız da hassas bir çalışma yapmadıysanız bunları fark etmemiş olabilirsiniz.
Mesela 0° ye gönderdiniz. acaba gerçekten 0° mi? Sadece son nokta olduğunu düşündüğünüz yere mi gidiyor. Bu programları kullanarak gerçek son noktayı ve başlangıç noktasını test edebilirsiniz. Çünkü süreyi siz belirliyorsunuz.

Burada videolardaki gerçek durumdan bahsetmek istiyorum. Videoda göreceğiniz üzere, proteus çalışması ile gerçek çalışma arasında zaman farkı bulunmaktadır. Bu zaman farkı elimizdeki servo motorların standart yapılara uymamasından kaynaklanıyor. Standartlar 1ms ve 2ms arasını işaret ediyor HIGH süresi için. Fakat motor ise 500us ve 2500us arası çalışmakta. Arduino kütüphanesini yazan kişi gerçek duruma göre yazdığından 544us ve 2400us arasında çalışacak şekilde sinyalini ayarlamış. Bu durum PICBASIC örneklerinde düzeltilmedi. Proteus standartlara göre çalıştığından, PICBASIC örnekleri proteus ile çalışmaktadır. Arduino ile çalışırken, servo_kontrol_3 programı proteus ile çalışacak şekilde bırakıldı. Sadece proteus ile denenebilir. Diğer Arduino programları ise ( servo_dene, servo_kontrol_4 ve servo_kontrol_5) düzeltme yapılarak gerçek motor üzerinde denendi.
Sizlerinde programlama yaparken kendi motorunuzun sınırlarını deneyerek bulmanız gerekebilir. Şayet SG90 kullanıyorsanız sınırlarınız bunlar. Yine de test etmeniz gerekirse arduino için servo_dene.ino programını kullanabilirsiniz.

POT ve SERVO MOTOR AYARI: 
Genelde örneklerde, servo motorlar, potansiyometre ile kontrol edilir. Bunu yapabilmek için işlemcinizin ADC girişi yani analog in girişi olmalı. Mesela  Arduino Unoda Analog girişler mevcut, 16F877A entegresinde de mevcut, 16F628 entegresinde mevcut değil. Her üç örnekte de potansiyometre kullanılmıştır. 16F628 e özel bir bağlantı ile potansiyometre konumu alınmıştır. RC zaman sabitesi ile hesaplama yapılmıştır.

16F628 için Bağlantı şeması :

Yukarıda ADC girişi olmayan 16F628 in PICBASIC pot komutu ile ölçülecek şemasını görüyorsunuz. Burada RC zamanı hesaplanarak potun hangi konumda olduğuna dair bilgiyi alabiliriz. Bu bilgi için küçük bir formül ile minimum ve maksimum değerlerini ayarlayabiliriz.

Mantığına bakacak olursak : PICBASIC Farklı değer döndürür. Örnek Program içerisinde nasıl yapıldığı açıklanmıştır.  
Öncelikle pot ucundan alınan değerin 0-1023 yani toplamda 1024 değer olduğunu biliyoruz.
Bizim ihtiyacımız 1ms ile 2ms arasındaki aralığı bulmak.
1024 sayısını 0-200 arasına getirdiğimizde potun minimum durumu=0,  maksimum durumu =200 olduğunda, buna göre  zamanı hesaplayabiliriz.
Neden 200 yaptık da 180 yapmadık? Birim zamandaki değişikliği bulacağımız için ve bu değişiklik maksimum 1000us olduğundan hesaplama kolaylığı getirecek olan 200 sayısına ulaşmak için yaptık. İsterseniz bu formülleri 180 dereceye göre ayarlayabilirsiniz. Fakat ondalıklar arduinoda sorun olmasa bile, PICBASIC için sorun olabilecektir.
200/1023=0.196 formülü ile birim pot değişimini bulabiliriz.
Bu ne işimize yarayacak.
POT üzerinden okuduğumuz değeri yani 0-1023 değerini bu değerle çarparak maksimum 200 olarak elde edebileceğiz.
Şunu demiştik 1000us en küçük değer 2000us en büyük değer. Aradaki fark 1000us dir.
Bunu da değişim miktarına böldüğümüzde değişim zamanını bulabiliriz.
1000us/200= 5us. Yani her birim değişim için 5us koymamız gerekiyor . Yani pot bize 50 derse 50*5us = 250us diyebiliriz. Bu değer bizim değişimimizi sağlıyordu. Fakat en küçük değer olan 1000us yi de bizim eklememiz gerekiyor. Çünkü işlem yapabileceğimiz aralık 1000us ile 2000us arasında olmalı.
O taktirde, son zaman verimiz 1000us+250us= 1250us olarak belirlenir.
Zamanı bulduk ne yapmalıyız. 
İlk baştaki gibi PORT HIGH yaptıktan sonra 1250us bekleyip PORT LOW yaptığımızda motor istediğimiz duruma gelecektir.

Tüm örnek programlara ve proteus çizimlerine buradan ulaşabilirsiniz.

Buradan PIC16F877 ADC kullanımına ait anlatıma ve C örneğine ulaşabilirsiniz. 

Buradan PICBASIC kullanılarak 16F877 ADC örneklerine ulaşabilirsiniz. 

Buradan Arduino için POT örneğine bakabilirsiniz.

Video içerisinde bir kaç bölüm vardır. Öncelikle Proteus üzerinde 16F628 ve 16F877 entegreleri ile yapılmış programların, proteus üzerinde çalışması ve sonrasında Arduino ile yapılmış programların, proteus ile çalışması ve gerçek devre ile çalışması anlatılmıştır.

Görebildiğiniz yanlışlıklar varsa buradan veya facebook üzerinden bildirirseniz, yanlış bilgiler düzeltilmiş olacaktır. 

Not: 34. dk da yapılan bir yanlış söylem var. Buradaki zaman milisaniye olacak, videoda 400 mikrosaniye denilmiş. bazen mikro saniye bazen milisaniye deniliyor. gerçek durum milisaniye dir.


 

 

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir