PIC16F628A ile Servo Motoru Kontrol Etmek

Başlatan PIC16F, 05 Eylül 2016, 11:39:24

PIC16F

Servo Motora derece cinsinden komut vermek istiyorum...
Örneğin
servo_dondur(130); // yazdığım zaman servoyu 130 dereceye ayarlasın.

Arduino'daki gibi...
İnternette bu konuyu araştırdım ama istediğim türden bir kod bulamadım.

Bulduğum en iyi kod şuradakiydi:
http://embedded-lab.com/blog/lab-21-servo-motor-control/

Fakat daha fazlasını istiyorum...
Bu kodla yalnızca butona basılarak servo döndürülüyor.
Benim istediğimse servo için derece-tabanlı komut sistemi...

180 derece üzerinden olması şart değil.
50 olur,  40 olur , 9999 olur, fark etmez; yeter ki sonu olan bir birim olsun.

ete

Bu şekilde standart bir kod yaratmak zor. Çünki servo motor pul genişliği ile konum alır. Kimisi 0 dan 180 dereceye 2000 us de gelir kimisi 1800 us de gelir. Motor spesifikasyonuna göre parametre yada formül değiştirirsen basitçe bir fomül geliştirmek mümkün olabilir.
Örneğin simulasyonda da yer alan servo motor örneklerine bakacak olursak, 0 konumunda durması için 500 us lik bir puls gerekiyor. Aynı motoru 180 derece konumuna getirmek için ise 2000 us lik bir puls verilmesi gerekmekte. Kısaca 500us=0 derece , 2000us=180 derece. Bu durumda 180 derecelik açı değişimine karşılık değişen zaman miktarı 1500us dir. Bir derecelik açıya karşılık gereken zaman miktarı 1500/180=8,3333333us
O halde formül Puls=(ACI x 8,3333333)+500 şeklinde olacaktır.
Sen programdan açı girdiğin zaman bu formülde yerine koyup bulduğun Puls miktarı kadar motora puls verirsen motorun istediğin açıya gelecektir.

Ete

PIC16F

Puls nedir ?
Bir de servo motorun mevcut konumunu alabileceğim bir komut var mı ? (Arduino'daki servo.read() gibi)

ete

Puls motora vermen gereken HIGH puls süresidir.
Motor konumunu alabileceğin bir komut yok. Üstelik daha hangi derleyici üzerinden konuşuyoruz oda belli değil.
Ete


karacan451

http://www.micropik.com/PDF/SG90Servo.pdf

http://www.robotiksistem.com/servo_motor_ozellikleri.html



void servo (int ss){

if (ss==-90){
RB0=1;
delay_us(1000);
RB0=0;
delay_us(19000);
}

if (ss==45){
RB0=1; // +5v verdi
delay_us(1750);
RB0=0;// 0 volt verdi
delay_us(18250);
}

// böyle devam edersin

}


  Böyle fonksiyon yaparsan işlemcinin dahili pwn kullanmamış olursun. Veya Ete hocanın dediğini matematiksel formül yapabilirsin.
 
  Sen 54 derece açı vermek istersen  rb0=1; +5v 1800 mikro saniye verirsin sonra rb=0; 0 volt delay_us (20000-1800);
20000 olayı puls süresidir.

  Ben bunu basic dilinde yapmıştım. Simülasyonda gayet  güzel çalıştı bide gerçek hayatta denedim.   



PIC16F

#6
Alıntı yapılan: ete - 05 Eylül 2016, 14:45:45
Sen programdan açı girdiğin zaman bu formülde yerine koyup bulduğun Puls miktarı kadar motora puls verirsen motorun istediğin açıya gelecektir.

Her servo motorda puls/derece dengesi farklı ise
Diyelim 1500 puls verdim; formülü hesaplamak için kaç derece döndüğünü nasıl ölçebilirim ?


ete

Servo motorda pals adedi değil palsin genişliği açısal harekette rol oynar. Diğer bir parametrede o genlikteki sinyalin 20 Hzlik frekansla verilmesi gereğidir. İlk pulsi aldığında motor konum alır sonraki palslerde konumunu sürekli korur. Servo motorun kaç adet döndüğüne değil hangi konuma geldiğine bakılır genellikle.
Bahsini ettiğin iş step motorlarda uygulanabilecek bir sistemdir. Step motor puls başına açısal hızına bağlı olarak (genelde 1,8 derece/Puls dir) hareket eder. 1,8 derecelik motora 200 puls verince 1 tur atmış olur.
Ama servo motorlar farklıdır. Bana kalırsa önce motorları öğren sonra uygulama geliştir derim.
Ete

PIC16F

#8
Yaparak öğrenmeyi tercih ederim;


void servoDondur(int);
int derece = 0;
int i;
unsigned int puls;

void main() {
     TRISB = 0;
     portb=0;
     
     while(1){
              for(i = 0; i < 180; i++){
                    servoDondur(i);
                    delay_ms(10);
              }
     }

}

void servoDondur(int derece){
     puls = (derece*8.3333333)+500;
     portb.B0 = 1;
     delay_us(puls);
     portb.b0 = 0;
     delay_us(20000-puls);
}


delay_us fonksiyonuna parametre olarak puls değerini hesaplayıp verdiğimde hata veriyor. (Integer const expected (23. satır))
MikroC'de delay_us ve delay_ms fonksiyonları parametre olarak değişken almıyormuş sanırım.



Timer kullanmam gerekecek. Ama nasıl ?



karacan451





void servoDondur(int derece){
     int puls;
     puls = (derece*8.3333333)+500;
     portb.B0 = 1;
     delay_us(puls);
     portb.b0 = 0;
     delay_us(20000-puls);
}

int derece = 0;
int i;
unsigned int puls;

void main() {
     TRISB = 0;
     portb=0;
     
     while(1){
              for(i = 0; i < 180; i++){
                    servoDondur(i);
                    delay_ms(10);
              }
     }

}



PIC16F

Alıntı yapılan: karacan451 - 06 Eylül 2016, 13:46:36



void servoDondur(int derece){
     int puls;
     puls = (derece*8.3333333)+500;
     portb.B0 = 1;
     delay_us(puls);
     portb.b0 = 0;
     delay_us(20000-puls);
}

int derece = 0;
int i;
unsigned int puls;

void main() {
     TRISB = 0;
     portb=0;
     
     while(1){
              for(i = 0; i < 180; i++){
                    servoDondur(i);
                    delay_ms(10);
              }
     }

}




Aynı hatayı veriyor.

karacan451

#11



void servoDondur(int derece){
   
int puls;
     puls = (derece*8.3333333)+500;
     portb.B0 = 1;
     delay_us(puls);
     portb.b0 = 0;
     delay_us(20000-puls);
}





void main() {
     int i;
     TRISB = 0;
     portb=0;
     
     while(1){
              for(i = 0; i < 180; i++){
                    servoDondur(i);
                    delay_ms(10);
              }
     }

}



karacan451

#12
 Tekrar dene .Kodu düzenledim

PIC16F


karacan451

 Kendim bilgisayarıma  micro c kurdum. Dediğin gibi çalışmadı çünkü delay_us(değişken); ve delay_ms(değişken); kabul etmiyor. Adamlar bunun yerine Vdelay_ms(değişken); geçerli yapmışlar ve ayrıca  Vdelay_us(değişken); böyle kod yazdım yine aynı hatayı verdi.

Powered by EzPortal