Şimdi Ara

PIC16F877A ile ESC sürme YARDIM !!!! ( PWM yada PPM )sin

Daha Fazla
Bu Konudaki Kullanıcılar: Daha Az
3 Misafir - 3 Masaüstü
5 sn
9
Cevap
1
Favori
1.639
Tıklama
Daha Fazla
İstatistik
  • Konu İstatistikleri Yükleniyor
0 oy
Öne Çıkar
Sayfa: 1
Giriş
Mesaj
  • Merhaba arkadaşlar,

    bir proje kapsamında elimdeki pic16f877a ile turnigy brushed 20a esc (fırçalı 20A esc) var. bunlarla uzaktan kumandalı yüksek torku olan bir motor ile araba yapıyoruz. araçın motoj işlemleri hallettim. sıra kodlayama geçti. ancak burda takıldım. sizlerden yardım isitiyorum.

    şimdi internnetten araştırdığım kadarıyla esc ler pwm ile çalışıyor. çok fazla örnek inceledim. pwm biliyorum yani. esc ler genel olarak 50hz(20ms) lik frekans ile çalıyorlar genellikle. Ve çoğunlukla escleri servo motor sürme tekniği ile sürülüyor. hobi ile uğraşan bir çok arkadaş bilir millet genellikle esc'leri pic yada mikrodenetleyiciler ile değilde uzaktan kumandaının recever'ları ile sürüyor.(yani bildiğiniz yap boz, kabloları bağla çalıştır) Bu sebeble olcakki pic ile esc sürme ile iligli pek kaynak bulamadim nette gerek türkçe gerekse yabancı sitelerde.

    şimdi öğrendiğim kdarıyla iki yöntem var PWM ve PPM
    PWM: periyot anında başlıyor ve istediğimiz duty_cycle() kadar artıyoruz.
    PPM: ancak ppm peryot içersinde anlık darbe vuruyor ve sönuyor, bunu defalarca yapıyor.

     PIC16F877A ile ESC sürme YARDIM !!!! ( PWM yada PPM )sin

    benim kodlarıma gelince iki tane yazdım, birisi ppm ile olanı ben yazdım digerini degistirdim(tmr kesmesi kullanılmı)
    benim yazdıgım calistirmiyor escyi, digeri caslitiriyor. Ancak ikiside 50Hz frekas uretiyor.
    Ve ben calisan ornege buton(pot) ekleyemiyorum( hizlandirma yada yavaslatmak icin)

     
    *********************** PPM ile calisan ************( calismayan benim yazdigim)
    #include <16F877A.h>
    #fuses HS,NOWDT,NOPROTECT,NOBROWNOUT,NOLVP,NOPUT,NOWRT,NODEBUG,NOCPD
    #use delay (clock=20000000)
    #use fast_io (b)
    #use fast_io (d)
    #define pwm pin_b7

    long s1=500;
    long bx=99;
    void main()
    {
    setup_psp(PSP_DISABLED); // PSP birimi devre dışı
    setup_timer_1(T1_DISABLED); // T1 zamanlayıcısı devre dışı
    setup_timer_2(T2_DISABLED,0,1); // T2 zamanlayıcısı devre dışı
    setup_adc_ports(NO_ANALOGS); // ANALOG giriş yok
    setup_adc(ADC_OFF); // ADC birimi devre dışı
    setup_CCP1(CCP_OFF); // CCP1 birimi devre dışı
    setup_CCP2(CCP_OFF); // CCP2 birimi devre dışı

    set_tris_b(0x00);
    set_tris_d(0x00);
    output_d(0x00);
    output_high(pin_d2);

    while(true)
    {
    bx++;
    output_high(pwm);
    delay_us(s1);
    output_low(pwm);
    delay_us(20000-s1);

    s1=10*bx+500;
    if(bx>300)
    bx=0;
    }
    }



     
    *********************** PWM ile calisan ************( degistirdigim)
    #include <16F877A.h>
    #fuses HS,NOWDT,NOPROTECT,NOBROWNOUT,NOLVP,NOPUT,NOWRT,NODEBUG,NOCPD
    #use delay (clock=20000000)
    #define ileri pin_d0
    #define geri pin_d1
    #define servo pin_b0

    // R/C Servo motor dönme açı değerleri
    const int8 servo_ileri[]={8,9,10,11,12,13,14,15,16,17,18};
    int i=0,pwm=0,duty_ileri=0;
    int16 zaman=0; // 16 bitlik değişken tanımlanıyor

    #int_timer0 // Timer0 taşma kesmesi
    void kesme ()
    {
    set_timer0(113); // TMR0 kaydedicisine 113 değeri yükleniyor
    if (pwm==0) // Eğer PWM değişkeni 0 ise
    { output_high(servo); // RB0 çıkışı lojik-1 }
    if (pwm>=duty_ileri) output_low(servo);
    zaman++; // zaman değişkenini 1 arttır
    if (zaman>17350) // bekle 17350x114,4µsn=1.984.840µsn, yaklaşık 2msn
    {
    zaman=0; // zaman değişkenini sıfırla
    i++; // i değişkeni değerini 1 arttır
    if(i==11) // Eğer i değeri 11 ise-Tüm adımlar bitti ise
    i=0; // i değişkenini sıfırla
    }
    pwm++;
    if (pwm>=173)
    pwm=0;
    }

    void main ()
    {
    setup_psp(PSP_DISABLED);
    setup_timer_1(T1_DISABLED);
    setup_timer_2(T2_DISABLED,0,1);
    setup_adc_ports(NO_ANALOGS);
    setup_adc(ADC_OFF);
    setup_CCP1(CCP_OFF);
    setup_CCP2(CCP_OFF);
    set_tris_d(0xFF);
    setup_timer_0(RTCC_INTERNAL | RTCC_DIV_4); // Timer0 ayarları belirtiliyor
    set_timer0(113); // TMR0 kaydedicisine 113 değeri yükleniyor

    enable_interrupts(int_timer0);
    enable_interrupts(global);

    while(true) // Sonsuz döngü
    { duty_ileri=servo_ileri[i]; }
    }




    Sizlerden istedigim, ilk kod neden çalışmıyor, çalışabilir formata nasil dönüştürebilirizi ( ona buton yada pot eklemedek daha kolay bence )

    yada diger ornege nasil ekleye bilirim pot, zaten kod calisinca ben calistirmiyro escyi 1 yada 2 sn sonra basliyor. pot ile nasil yapabilirim bu isi
    acikcasi kodu tam analmadim, acilari filan nasil belirmis adam :(, kesme kontorlumde olmadigi icin buton eklesem bile butona bastigimda timer hala saıyorsa bir ise yaramiyır benim buton :(







  • ilgilenecek arkadaş yok mu ?
  • Ilk kodunun calismama nedeni zamanlama olabilir. Ayrica direk olarak duty cycle'i artirmissin. Bunu yaparsan esc koruma moduna gececektir.
    Escnin calismasi icin ilk basta bir sure 0.8ms lik sinyal gonderilmesi gerekiyor. Ayrica yaptigin oldukca tehlikeli. Esc olduda calisti diyelim birden max gaza cikacak!

    Ikinci kod daha iyi aslinda onu kullanmalisin. Timerlari kullanmak her zaman daha iyidir. Ancak ben ikinci kodu da onermem sana. Cunku belli acilar icin yapilmis sadece. Araba yapacagim diyorsan cozunurlugun daha yuksek olmali. Asagida yazdigim kod en mantiklisi. Compilerim olmadigi icin deneyemedim ama muhtemelen calisacaktir.

    Gazi butonla artirmak icin bir kod yerlestirdim main'e. Istersen kendin de degerler verebilirsin. minimum gaz icin 'gaz' degiskenine 0, max icin ise 750 gondermelisin.

    Ekleme:
    Kodu oncelikle proteus ya da benzeri simulasyon programlarinda denersen olusabilecek kazalari engellemis olursun.

    Kolay gelsin.

    //////////// 
    //en az 0.0008s=0.8ms=800us'de en fazla 2000us'de,
    //ayrica 20ms de bekleme suresi icin,
    //timer kesmesi olusmasini istiyoruz.
    ////////////
    //Timer1'in tetikleme suresi=1/(frekans/4) * Oran * (65536-T1)
    //0.0008=1/(20000000/4) * 8 *(65536-T1)= 0,0000016
    //0.8ms icin T1=65036
    //2ms icin T1=64286
    //20ms icin T1=12500
    //Oyleyse T1 yerine, 65036-gaz yazariz ve
    //gaza 0 verdigimizde 0.8ms, 750 yazdigimizda 2mslik,
    //kesme olusturmus oluruz.
    //20 mslik kismi yapabilmek icin
    //65036-(52536+500+gaz) yazariz ve
    //1 olan ve 0 olan periyuodumuz toplamda 20ms olur.
    //52536 degeri 20mslik kesmeye esit olan deger,
    //500 degeri 0.8 ms olan her zaman varolmak zorunda olan deger
    //gaz ise bizim belirledigimiz degisken.
    ////////////
    //Gaz degiskeni 16 bit oldugu icin degisken unsigned long secilmeli
    ////////////

    #include <16F877A.h>
    #fuses HS,NOWDT,NOPROTECT,NOBROWNOUT,NOLVP,NOPUT,NOWRT,NODEBUG,NOCPD
    #use delay (clock=20000000)
    #define servo pin_b0
    #define BUTON_GAZ pin_a0

    unsigned long gaz=0;
    int evre=0; //Evre 0 iken 1 verecegimiz kisim,
    //1 iken 0 verecegimiz kisim

    #int_timer1
    void timer1kesme ()
    {
    if (evre==0){ //Evre-0 tamamlandi cikisi 0 yap
    //20ms-(1 verdigimiz periyot kadar) 0 veriyoruz
    //boylece sinyalimiz 50hz olmus oluyor.
    set_timer1(65036-(52536+500+gaz));
    output_low(servo);
    evre=1;
    }
    else{ //Evre-1 tamamlandi cikisi 1 yap
    set_timer1(65036-gaz);
    output_high(servo);
    evre=0;
    }
    }

    void main ()
    {
    set_tris_a(0xFF);
    set_tris_b(0x00);
    setup_timer_1(T1_INTERNAL | T1_DIV_BY_8); //20mslik bekleme uzun oldugu icin,
    //en buyuk bolme olan 8'i uyguluyoruz
    output_high(servo);
    set_timer1(65036-gaz); //gaz=0 oldugundan, 0.8ms verdik
    enable_interrupts(int_timer1);
    enable_interrupts(global); //timer'i baslattik

    while(1)
    while(input(BUTON_GAZ)) //A0'a baglayacagin buton icin
    { //butonu pulldown direnci ile baglamalisin
    delay_ms(10);
    if(!input(BUTON_GAZ))
    {
    gaz+=10;
    if (gaz>750)
    gaz=750;
    }
    }
    }



    < Bu mesaj bu kişi tarafından değiştirildi sfaunl -- 23 Aralık 2011; 7:29:53 >




  • çok teşşeür ederim,

    benim verdigim 2. kod dediginiz gibi belirli acilarda calisiyor ve guc kesildiginde anlik oalrak sinyal kaybediyordu.
    ama sizin verdiginiz kodda dediginiz gibi sinyal kaybı ortadan kalkti
    ayrica buton yerine pot taktim, butona ile cebellesmekten kurtuldum

    ancak anlamadigimi bir kac nokta var,

    0.8ms lik pwm ile 2ms pwm yapalamak icin verdigimiz T(0.8ms)=65036 ve T(2ms)=64286 >>> yani timer kesmemiz bu iki deger arasinda baslamliki motor donsun

    ama 20ms lik peryot yakalamak icin timer'i T1=12500 baslatmak gerek, ama burda >>> 65036-(52536+500+gaz) <<< yaptigimiz tam olarak nedir. neden bu degerden baslattik. gaz malum max 750 olur o zaman T min 65036-(52536+500+750)=11250 ediyor ???




  • Eheh... Sayılar birbirine karışmış galiba
    set_timer1(54286-gaz); olmalı o kısım.

    Tam kodu bir daha ekleyeyim:
    //////////// 
    //en az 0.0008s=0.8ms=800us'de en fazla 2000us'de,
    //ayrica 20ms de bekleme suresi icin,
    //timer kesmesi olusmasini istiyoruz.
    ////////////
    //Timer1'in tetikleme suresi=1/(frekans/4) * Oran * (65536-T1)
    //0.0008=1/(20000000/4) * 8 *(65536-T1)
    //0.8ms icin T1=65036
    //2ms icin T1=64286
    //20ms icin T1=53036
    //Oyleyse T1 yerine, 65036-gaz yazariz ve
    //gaza 0 verdigimizde 0.8ms, 750 yazdigimizda 2mslik,
    //kesme olusturmus oluruz.
    //20 mslik kismi yapabilmek icin
    //54286-gaz yazariz ve
    //1 olan ve 0 olan periyuodumuz toplamda 20ms olur.

    //54536 degeri 18mslik kesmeye esit olan deger,
    //gaz ise bizim belirledigimiz degisken.
    // _________ ___
    //__| |_______________________________| .....
    //
    // |<-0.8ms->| | | //65036
    // |<-------2ms------->| | //64286
    // |<--------18ms------->| //54286
    // |<------------------20ms----------------->| //53036
    ////////////
    //Gaz degiskeni 16 bit oldugu icin degisken unsigned long secilmeli
    ////////////

    #include <16F877A.h>
    #fuses HS,NOWDT,NOPROTECT,NOBROWNOUT,NOLVP,NOPUT,NOWRT,NODEBUG,NOCPD
    #use delay (clock=20000000)
    #define servo pin_b0
    #define BUTON_GAZ pin_a0

    unsigned long gaz=0;
    int evre=0; //Evre 0 iken 1 verecegimiz kisim,
    //1 iken 0 verecegimiz kisim

    #int_timer1
    void timer1kesme ()
    {
    if (evre==0){ //Evre-0 tamamlandi cikisi 0 yap
    //20ms-(1 verdigimiz periyot kadar) 0 veriyoruz
    //boylece sinyalimiz 50hz olmus oluyor.
    set_timer1(54286-gaz);
    output_low(servo);
    evre=1;
    }
    else{ //Evre-1 tamamlandi cikisi 1 yap
    set_timer1(65536-(gaz+500));
    output_high(servo);
    evre=0;
    }
    }

    void main ()
    {
    set_tris_a(0xFF);
    set_tris_b(0x00);
    setup_timer_1(T1_INTERNAL | T1_DIV_BY_8); //20mslik bekleme uzun oldugu icin,
    //en buyuk bolme olan 8'i uyguluyoruz
    output_high(servo);
    set_timer1(65036-gaz); //gaz=0 oldugundan, 0.8ms verdik
    enable_interrupts(int_timer1);
    enable_interrupts(global); //timer'i baslattik

    while(1)
    while(input(BUTON_GAZ)) //A0'a baglayacagin buton icin
    { //butonu pulldown direnci ile baglamalisin
    delay_ms(10);
    if(!input(BUTON_GAZ))
    {
    gaz+=10;
    if (gaz>750)
    gaz=750;
    }
    }
    }


    İnşallah bu sefer doğrudur.
    Neyse zaten hesaplamayı kodun içerisinde verdim. İstediğiniz değere ayarlayabilirsiniz.



    < Bu mesaj bu kişi tarafından değiştirildi sfaunl -- 24 Aralık 2011; 6:52:53 >




  • Hocam tekradan merhaba,

    dediginiz kod ile sorunsuz rf iletişim üzerinden escyi ve motoru kontrol ediyor, bu konuda sagolun.

    bir konuda daha yardımınıza ihtiyacım var, bizim suan uyguladigimiz method ile esc tek yonlu calisiyor ve gucu kesinde fren uyguluyor. hadi freni gectim ben nasil bir yontem ile esc yi geri dondurebilrim.

    sinyal peryodum filanmi degiscek ki
  • ESC terse dondurmeyi desteklemiyorsa tek yapabilecegin motora giden 2 kablonun yerlerini degistirmen. (Hangisini degistirecegin farketmiyor. Istedigin ikisini yer degistir.)
    Destekliyorsa nasil yapacagina dair bir fikrim yok ama.

    Ekleme:Bir baktim, reverse olanlarda 1.5ms tam gaz ileri, 1 ms tam gaz geri. 1.25 ise normal.



    < Bu mesaj bu kişi tarafından değiştirildi sfaunl -- 31 Aralık 2011; 1:35:55 >
  • Yapay Zeka’dan İlgili Konular
    Daha Fazla Göster
  • isin ilginc yani elimde iki tane esc var birisi Turmigy 20A Brused ( sadece ileri) digeri ise Hard Dual Mode Esc ( hem ileri hem geri hemde fren )

    en son yazdıgımız kod ile sadece turnigy calisiyor hemde super verimlilikte ck rahat kotrol ediyorum. ama diger esc calismiyor. diger esc ise en basta sayfada verdigim iki kod varya onlarda belirli acilarda donen ile calisiyor ama herhangibir noktada geri donme yok sadece fren yapıyor ve giderek hizlaniyor.

    ortalik karsiti bu escler beni bitirdi




  • reverse özelliği olan esc var elimde. Ama nasıl motoru ters yönde döndürebileceğimi hala bilmiyorum. Farklı değerlerde pwm sinyali verdim fakat pwm sinyali ile sadece hızı ayarlanıyor.
  • 
Sayfa: 1
- x
Bildirim
mesajınız kopyalandı (ctrl+v) yapıştırmak istediğiniz yere yapıştırabilirsiniz.