Benim bu çalışmada kullanacağım TowerPro markalı servo motordur. Servo motorun 3 adet kablosu bulunur;
* Kırmızı kablo VCC(4.5V-6V)
* Kahve rengi GND
* TURUNCU Data
Servo motorun çalıştırılması için periyodu sabit olmalıdır yani 20ms gibi. Bu 20 ms periydun içinde biz darbenin lojik 1 kalma süresini sınırları içinde ayarlarsak motor istediğimiz yöne sürebiliriz. Örneğin; Data ucuna 0.5 ms bir lojik 1 uygulayalım sonra 19.5ms lojik 0 uygulayalım motor sola doğru hareket edecektir. Bunu devamlı yaparsak motor sola gidecek ver orada kitlenecektir. Bu işlemler ortaya ve sağa doğru hareketler içinde geçerlidir.
Ben bu çalışmamda yapmak istediğim şey şimdilik motor önce -90 derece gidecek ve +10 derece arta arta +90 dereceye kadar gidecek.
Devre şeması
MikroC kodumuz; Kod yeterince açıktır ve yanlarında açıklamaları yazdım. Biraz göz atarsanız mantığını anlayabilirsiniz.
#include "built_in.h" // hi(), lo(), komutlarını kullanmak için
# define servo PORTD.RD0 // servo motor için çıkışı ayarlanır PORTD.RD0
char say = 1, secilen_hiz = 1, secilen_poz = 0;
unsigned poz;
const int rc_poz_limit = 12500; // PWM maksimum limit 2.5ms
const int rc_poz_min = 2400; // PWM minimum limit 0.5ms
unsigned servo_pwm; // ne kadar lojik 1 kalacağını belirler.
unsigned short servo_idx = 0; // Bunun neden kullandığı sonraki projede daha açık anlayacaksınız
bit servo1_on;
bit bayrak;
unsigned rc_poz_interrupt = 53035; // TMR1 için ön değer
unsigned short adc_deg;
void interrupt()
{
if (pir1.tmr1if){ // tmr1 kesmesi oluştu
if (!bayrak){
if (servo_idx == 0 && servo1_on) servo = 1;
rc_poz_interrupt = 65535 - servo_pwm;
tmr1h = hi(rc_poz_interrupt);
tmr1l = lo(rc_poz_interrupt);
}
if (bayrak){
if (servo_idx == 0 && servo1_on) servo = 0;
rc_poz_interrupt = 65535 - rc_poz_limit + servo_pwm;
tmr1h = hi(rc_poz_interrupt);
tmr1l = lo(rc_poz_interrupt);
if (++servo_idx > 7) servo_idx = 0;
}
bayrak = !bayrak;// 20ms elde etmek için bu işlem yapıldı
pir1.TMR1IF = 0;
}
}
void init()
{
TRISD =0x00; // PORTD çıkış olarak yönlendirildi
PORTD =0x00; // PORTD sıfırlandı
delay_ms(300);
tmr1h = hi(rc_poz_interrupt); // TMR1 için ön değer yüklendi
tmr1l = lo(rc_poz_interrupt);
pie1.TMR1IE = 1; // TMR1 kesmesi aktif edildi
t1con.TMR1ON = 1; // TMR1 zamanlayıcısı çalıştırıldı
RCON.IPEN = 0; // Çevresel kesme maskelemeleri iptal edildi
INTCON.GIE = 1; // Kesmeler aktif edildi
INTCON.PEIE = 1; // Çevresel kesmeler aktif edildi
bayrak = 0;
servo1_on = 1;
servo = 0; // servo ilk anda çalışmıyor.
servo_pwm = 2400; // bütün servoların başlangıç pozisyonları
}
void pozisyon(unsigned poz, unsigned short hiz) // servonun pozisyonunu ayarlama
{
unsigned short i;
while(servo_pwm < poz){
servo_pwm++;
for(i = 0; i < hiz; i++) delay_us(100);
}
while(servo_pwm > poz){
servo_pwm--;
for(i = 0; i < hiz; i++) delay_us(100);
}
}
void main() { // ana program
init(); // init() altprogramı çalıştırılıyor
delay_ms(500);
while(1){ // sonsuz döngü
say=1;
while(say < 9)
{
delay_ms(100);
poz = (55,56 * secilen_poz) + 2400;
pozisyon(poz, secilen_hiz);
say++;
}
secilen_poz = secilen_poz + 10; // servo pozisyonları 10 derece artırıldı
if (secilen_poz > 180) secilen_poz = 0; // pozisyon 180 ( ya da +90 )
} // dereceyi aştı ise 0 derece
}
SONUC
Kaynak
*MikroC ve PIC18F4550 kitabı
*http://320volt.com/picbasic-dersleri-pic-basic-pro-ile-pic-programlama-12/
*http://embedded-lab.com/blog/?p=4653
*http://www.fatiherdem.net/hobi-servo-surelim/
Hiç yorum yok:
Yorum Gönder