Servo Motoru CCS kodlari ile nasil kontrol edebilirim?

Başlatan Digimensch, 01 Ekim 2006, 22:36:49

Digimensch

Ben su asagidaki devrede bulunan Servo motoru calistirmak , devir yönünü degistirmek istiyorum.

Bu is icin hazir bir kod değilde , nasil bir kod yazmam gerek bilgi verirseniz sevinirim.
Servo Motoroun Clock cikisi  PIC16F84'ün RB0 ucuna baglanmis.Simdi ben bu Biti 100 ms araliklarla high-low mu yapmam gerekli ki Servo Motor dönsün?
Bana CCS'de ne yapmam gerekli onu yazarsaniz sevinirim.

zafzaf82

servo motorun nasıl kontrol edileceğini bilmiyorum ama heralde isteğin söyle bi kod.
#include <16F84.h>

#fuses XT,NOWDT,NOPROTECT                 
#use delay(clock=4000000,RESTART_WDT)

#define ileri input(PIN_A0)
#define geri  input(PIN_A1)

#define low   output_low(PIN_B0)
#define high  output_high(PIN_B0)


void main()
{

   set_tris_b(0x00); // portb çıkış
   set_tris_a(0xFF); // porta giriş
   
   for(;;)
   {
   
      while(ileri==0) // ileri veya geri dönmesi için gecikmeler farklı galiba 
      {                 
      low;
      delay_ms(100); // degerleri salladım
      high;
      delay_ms(100);// degerleri salladım
      }
      
      while(geri==0)
      {
      low;
      delay_ms(100);// degerleri salladım
      high;
      delay_ms(100);// degerleri salladım
      }
   }
}
Mikroişlemci bi araçtır, amaç değil.....

Digimensch

@zafzaf82
hocam verdigin kod icin cok tesekkür ederim öncelikle.
Kodu denedim Proteus'da S1 anahtarini kapattigimda yani (Ileri)RA0 veya (Geri) RA1 bitlerini sase ettigimde Servo sadece 45° saga dönüyor baska hic bir funksiyon göstermiyor.
Acaba Servo motor icin gerekli Clock sinyallerdemi dikkat etmem gereken hususlar var?

zafzaf82

Digimensch dedim ya servo motoru nasıl kontrol edcegimi bilmiyorum delay_ms deki değerleri değiştirerek belki daha iyi sonuçlar elde edebilirsin.
Mikroişlemci bi araçtır, amaç değil.....

Digimensch

Evet
ileri icin
delay_ms(100);  satirini
delay_ms(1); sekilde

Geri icin
delay_ms(100); satirini
delay_ms(2);  sekilde  degistirince oldu.Simdide sadece Servo Motor 1 kez tur atiyor ve duruyor.
Acaba bu sorunu nasil asmam gerekiyor bilen arkadaslar cevap verirse sevinirim.

Digimensch


picusta

Bu bahsettiğin servo motor model servo motoru olmasın?
öyleyse PPM (Pulse Position Modulation) isminde bir olay var.
Mantığı motorun konumu darbenin uzunluğu ile orantılı.
1 ms'lik darbe verirsen en uca, 1,5ms'lik verirsen ortaya 2ms'lık verirsen diğer uca konumlanır. Darbeler arasındaki süre kritik değil, ortalama 20 ms boşluk olabiliyor.
Bu arada aynı bilgiyi forumda 3. kez veriyorum. Daha önce verdğim linki incele.


http://www.modelci.net/sayfa.php?s=19

Digimensch

@picusta
bendeki servo motor aynen senin su yukardaki sekildeki gibi.
Ben servo motorlari 380° dönüyor saniyordum.
Oysa bendeki Servo Motorun milini el ile döndürmeye calistim sadece 180° hareket kabiliyetine sahip.Bu Motoru bende bir Model dükkanindan almistim haklisin.
Amacim bu Motorlardan bir kac tane kullanarak hareketli bir mekanizma olusturmak.
Yukardaki bir Kod ile sadece ben yün degistirme yapabiliyorum.
Oysa ben bir Servo Motoru milim milim saga veya sola hareket ettirmek istiyorum.
Ben Servo Motoru yukardaki gibi bir PIC ve CCS kodu ile istedigim derecede döndürme islemini saglayabilirmiyim yoksa sadece servoyu balangic,orta ve son pozizyona getirmekten baska hareket ettirme sansim yokmu?
Bir ikinci sorumda
baslangic pozisaonuna getirmek icin 1ms'lik sinyal ugulamayi CCS'de
delay_ms(1);
ile yapiyorum fakat 1,5ms'lik sinyal uygulamayi nasil gerceklestirebilirim?
Birde Servoyu istedigim derecede döndürmek icin uygulamam gereken sinyal süresi ne olmalidir?
saygilarimla

CaFFeiNe


Digimensch

@CaFFeiNe
cok tesekkürler ise yaradi.
Ama servo motorlardan anlayan arkadaslar bana bilgi verebilirlermi ?
Acaba CCS kodu ile nasil sinyaller göndermeliyim ki , servo motoru belirli acilarda hareket ettirebileyim?
Yada bu islemi yapabilmek icin CCS'de özel funksiyonlar varmi?

Digimensch

Su asagidaki Kod ile bir adet Model Servo Motoru yukarda vermis oldugum Devreye göre calistirmak istedim.
#include <16F84.h>

#fuses XT,NOWDT,NOPROTECT
#use delay(clock=4000000,RESTART_WDT)

#define ileri input(PIN_A0)
#define geri  input(PIN_A1)
#define orta  input(PIN_A2)

#define low   output_low(PIN_B0)
#define high  output_high(PIN_B0)


void main()
{

   set_tris_b(0x00); 
   set_tris_a(0xFF); 

   for(;;)
   {

      while(ileri==0)
      {

      high;
      delay_us(1000);    // servoya 1ms'lik sinyal gönderiliyor
      low;
      }

      while(orta==0)
      {

      high;
      delay_us(1500);    // servoya 1ms'lik sinyal gönderiliyor
      low;
      }

      while(geri==0)
      {
      high;
      delay_us(2000);
      low;
      }
   }
}


Kod ISIS'de gayet güzel calisiyor.
Devreyi denemek icin hemen Boardda kurdum fakat Servo Motor cok kücük hareketlerden baska bir sey yapmiyor.
Yani Servo'nun mili basa,ortaya ve sona dogru gayet kücük hareketler ediyor.
Oysa ISIS'de  90° lik dönüsler yapiyor aynen yukardaki Animasyon Resimde oldugu gibi.
Gercek denemede neden sadece kücük kimildamalar oluyor olabilir?
Aca

Digimensch

Arkadaslar yukardaki sorumu yeniliyorum.
Alıntı yapılan: "Digimensch"
Kod ISIS'de gayet güzel calisiyor.
Devreyi denemek icin hemen Boardda kurdum fakat Servo Motor cok kücük hareketlerden baska bir sey yapmiyor.
Yani Servo'nun mili basa,ortaya ve sona dogru gayet kücük hareketler ediyor.
Oysa ISIS'de  90° lik dönüsler yapiyor aynen yukardaki Animasyon Resimde oldugu gibi.
Gercek denemede neden sadece kücük kimildamalar oluyor olabilir?
Aca

Yukardaki CCS Kodu ISIS'de Servo Motoru sag-sol-orta konumlarina getiriken gercek uygulamada Servo motorun mili sadece kücük kipirtilardan baska hareket etmiyor.
Bana CCS Ile nasil Servo Motor kontrol edebilirim bir örnek veya bilgi verirseniz sevinirim.
PWM sinyallerinden bahsediliyor bu PWM sinyalleri ben CCS ile 16F84'e nasil yaptirip bir Servo Motoru kontrol edebilirim?

picusta

PWM'e benziyor, ama tam değil. PWM kullanmak istiyorsan 84 yerine 628 kullansan donanım PWM kullanırdın, karar senin bu uygulamada gerek olmayabilir.
Küçük kumışdamalar ile kastın nedir?yani birkaç derecelik dönüşmü yoksa titreşim mi?

Aklıma şunlar geliyor:
-  delay_us fonksyonun çalışmasında sorun olabilir: Belki daha hızlı kristal kullanıyorsun. Veya CCS'de bir BUG.

-  Programında 20ms'lik ölü zaman bırakmıyorsun, bu yüzden sorun olabilir.
örneğin şöyle bişi ile değiştirmeyi  dene:

while( X ==0)
      {

      high;
      delay_us(XX);    // servoya XXms'lik sinyal gönderiliyor
      low;
      delay_us(20000); // 20ms'lik ölü zaman
       }



Bu servolar en güzeli timer interrupt rutini ile hallediyorsun. Bu kod çalışınca bide öyle denersin.

Digimensch

@picusta
hocam sorunu söyle hallettim fakat,
#include <16f84a.h>
#fuses XT,NOWDT,NOPROTECT
#use delay(clock=4000000)
#byte PORTB = 6
main(void)
{
int x;
SET_TRIS_B(0);
PORTB = 0;
for(x=0;x<=10;x++)
{
output_high(PIN_B0);
delay_us(100); // servoya 1ms'lik sinyal gönderiliyor
}
output_low(PIN_B0);
delay_ms(19000); 
}

Servo hangi posisyonda olursa olsun sola dönüyor.Dönme bitiyor ama hala motor sanki dönmeye devam edecekmis gibi sona geldigi halde zorlaniyor.Yani hala motor enerji aliyor.
Ama ne yaptimsa motoru aksi yönde yani saga dogru döndermeyi basaramadim.
Oysa 2ms lik sinyal verildiginde saga dönmesi gerek ama motor hep sola dönüyor.


Ben yukardaki resimde oldugu gibi Servoyu Devrede Button olmadigini varsayarak sira ile servo motoru
1ms'lik sinyal ugulayarak sola
1,5ms'lik sinyal ugulayarak ortaya
2ms'lik sinyal uygulayarak saga nasil dönderebilirim?
Ben söyle birsey yaptim fakat ISIS'de gayet iyi calisiyor gercek Denemede Motor sadece Sola sona kadar dönüyor ve orda kaliyor.
void main() 
{ 

   set_tris_b(0x00); 
   set_tris_a(0xFF); 

   for(;;) 
   { 
  
      high; 
      delay_us(1000);    // servoya 1ms'lik sinyal gönderiliyor "Sola"
      low; 
      delay_ms(1000); 
     
      high; 
      delay_us(1500);    // servoya 1,5ms'lik sinyal gönderiliyor  "Ortaya"
      low; 
      delay_ms(1000); 
     
       
      high; 
      delay_us(2000);    // servoya 2ms'lik sinyal gönderiliyor "Saga"
      low;
      delay_ms(1000); 
     
   } 
}


Bunun CCS'de yapilisi nasil olmali?

picusta

for(x=0;x<=10;x++)
{
output_high(PIN_B0);
delay_us(100); // servoya 1ms'lik sinyal gönderiliyor
}


çalışıyor

output_high(PIN_B0);
delay_us(1000);// servoya 1ms'lik sinyal gönderiliyor


çalışmıyormu?

CCS'te yaptığın gibi fonksyonu yazıyorsun. (veya interrupt yöntemi)
Nitekim simülasyonda çalıştı.
CCS'de belki built in fonksyonu vardır ama onu CCS kullanmadığım için bilmiyorum.

Servonun içinde bi sorun olmasın? Potansyometre sağlam dimi?