Ynt: pid kontrol (fan(dc motor) ile levha açısının kontrolü)

Başlatan quadcopter_61, 11 Mart 2013, 12:05:14

quadcopter_61

Herkese Merhaba,

Öncelikle yapmış olduğunuz tüm paylaşımlar için hepinize teşekkür ederim.  Herkes gibi benimde bir konu hakkında yardıma ihtiyacım  var.
Linkte vermiş olduğum sistemi kurmak istiyorum. (http://www.kri.com.sg/fan.html#Software)   Bunu CCS C de  pic16f877a ile yapmaya çalışıyorum, öneriniz ile farklı şekillerlede yapabilirim. Amacım potansiyometre ile bir açı değeri girip levhayı istenilen açı değerine taşımak.
Ayrıca işlemci levhanın açısını potansiyometre ile kontrol ederek(ikinci bir analoğ değer hesaplanacak (geri beslemeli bir sistem))  pid kontrolü(yanlızca oransal) yapmasını istiyorum. Yani sadece oransal denetleme yapacak. P katsayısınında üçüncü bir potansiyometre ile okunup 0-255 arası bir değere atanıp dışarıdan ayarlanması ile sistemin düzgün çalışması sağlanabilir diye düşünüyorum.  Motoru l298n ile sürüyorum. Pic programlama konusunda pek bi bilgim yok  ama temel şeyleri yapabiliyorum programlama mantığı yani algoritmalar hakkında biraz bilgim var(temel seviyenin altında c bilgiside var.)
Aşağıda verilen programı yazdım(kopyala yapıştır ile yaptım ama mantığını anlayabiliyorum) Pic e yüklüyorum ama pic in pwm çıkısında sadece 0,32v luk bir gerilim değeri okuyorum. Belkide programın yanlıştır(tek bir analog girişle yanı potansiyometre ile motorun hızını kontrol edebiliyorum denedim ve yaptım) Program konusunda yardımlarınızı bekliyorum. 1 analog değeri okuyup motoru sürerken sıkıntı yaşamıyorum ama 3 analog degeri okuyup bunlar arasında işlem yapınca çalıştıramıyorum. Daha ayrıntılı bilgi verebilirim elimde fotografda var(kendimce bir düzenek kurdum fena sayılmaz. devrede board üzerinde kurulu). Umarım istediğimi anlatabilmişimdir
Şimdiden teşekkür ederim..


#include <16f877a.h>
#device adc=8
#fuses xt,nowrt,nowdt,nodebug,nobrownout,nolvp,nocpd,noput,noprotect
#use delay(clock=4M)
#use fast_io(a)
#use fast_io(e)
#use fast_io(c)
#use fast_io(b)

signed int sur;
unsigned int giris; //olmasını istediğimiz açı değerini girdigimiz potansiyometre 0-5v arası deger 0-90 dereceye dönüştürülüyor
unsigned int levha;//levhadan okunan değer levhanın hangi konumda olduğu
signed int hata;
unsigned int P;



void main()
{
setup_timer_2(T2_DIV_BY_16,250,1);
setup_timer_1(T2_DISABLED);
setup_CCP1(CCP_PWM);
setup_CCP2(CCP_OFF);
setup_adc(adc_clock_internal);
setup_adc_ports(ALL_ANALOG);

set_tris_c(0x00);
set_tris_e(0xFF);
set_tris_b(0x00);
output_c(0x08);




set_pwm1_duty(0);
delay_ms(20);

while(1)
{
set_adc_channel(2);//potansiyometre ile girilen değer 5v=250
delay_us(20);

giris=read_adc();

set_adc_channel(1);//levhanın konum bilgisi
delay_us(20);

levha=read_adc();


hata=giris-levha; // hata hesaplanıyor

set_adc_channel(0);//potansiyometre ile girilen değer 5v=250integer
delay_us(20);

P=read_adc();



sur=sur+hata*P; //oransal sabit p ile hata çarpılıyor


if(sur<-49)
sur=30;
if(-50<sur<0);
sur=40;

output_high(pin_c3);
output_low(pin_c4);

if(sur>250)
sur=250;
set_pwm1_duty(sur);


}

}


mesaj birleştirme:: 11 Mart 2013, 12:14:35

Projenin görünümü: http://imageshack.us/photo/my-images/46/20130311114347.jpg/
Devre şeması:  http://imageshack.us/photo/my-images/833/isisizimi.png/

JKramer

setup_adc(adc_clock_internal);
yerine kataloğun ADC bölümündeki uygun bir değere (8 olabilir) ayarlayın.
sur=sur+hata*P; //oransal sabit p ile hata çarpılıyor
Bu tip işlemlerde tanımlanan değişkenlerin sınırlarına dikkat edin. Mesela signed int8 olarak tanımladığınız sur değişkeni, -128...+127 arası; unsigned int8 olarak tanımladığınız P değişkeni 0...255 arası değer alabilir. Kabaca gözüme çarpan bunlar.