dc motor PI kontrol. sorunumu bi türlü çözemedim

Başlatan zamzam23, 13 Eylül 2010, 11:36:29

teknikelektronikci

Orda donanimsal register ile cozuyorsunuz normal pic dede soft ile ayrica bu pic ler ozel ollarak motor surmek icin belkide pid ozelligide vardir bskmak gerek
Ey Türk istikbalinin evlâdı! İşte, bu ahval ve şerâit içinde dahi, vazifen; Türk İstiklâl ve Cumhuriyetini kurtarmaktır! Muhtaç olduğun kudret, damarlarındaki asil kanda mevcuttur!

zamzam23

#16
pid varsa hemen alırım. durun bakıcam sımdı

baktım pid yok.

Quadrature Encoder Interface Module
Features:
• Phase A, Phase B and Index Pulse input
• 16-bit up/down position counter
• Count direction status
• Position Measurement (x2 and x4) mode
• Programmable digital noise filters on inputs
• Alternate 16-bit Timer/Counter mode
• Interrupt on position counter rollover/underflow

teknikelektronikci

Bu ozelliklerbile guzel pid parametrelerinde onemli etkendenbiride encoderden gelen bilgi degilmi birde ds serisine baktinizmi
Ey Türk istikbalinin evlâdı! İşte, bu ahval ve şerâit içinde dahi, vazifen; Türk İstiklâl ve Cumhuriyetini kurtarmaktır! Muhtaç olduğun kudret, damarlarındaki asil kanda mevcuttur!

teknikelektronikci

Ey Türk istikbalinin evlâdı! İşte, bu ahval ve şerâit içinde dahi, vazifen; Türk İstiklâl ve Cumhuriyetini kurtarmaktır! Muhtaç olduğun kudret, damarlarındaki asil kanda mevcuttur!

zamzam23

onlara baktım zaten.30f serisine.ama pid özelliği yok. neyse artık AN dekilerde işime yarayabilir saolun.

picusta

Alıntı yapılan: zamzam23 - 18 Eylül 2010, 22:38:51
Alıntı yapılan: picusta - 18 Eylül 2010, 09:54:50
Yanliz unutmaman gereken sey pals degiskeni her iki kesmede kullaniliyor. Eger birisi ona erisirken digeri degerini degistirirse sorun olabilir. (2 byte'lik deger oldugundan 1. bayt, 2. bayt)
birisi ona erişirken diğeri değerini değiştiremez cunku bır ınterrupt bitmeden diğerine gecemez.
Bu PIC'te oldugu gibi 2 kesme önceligi olursa olur (kesme önceligi bu ise yarar).
Hazir PID ancak PLC'lerde blok halinde olur, mikroislemcilerde olsa olsa MAC (multiply accumulate olur), DSP'lerde FFT hardware acceleration.
Yapilan hesaplama belli : çarpma toplama.

zamzam23

picusta dediklerinizi yapıcam ama suan pic motor kalkıs anında resetleniyor onu çözmeye calısıyorum.

zamzam23

Alıntı yapılan: picusta - 20 Eylül 2010, 11:17:30
Alıntı yapılan: zamzam23 - 18 Eylül 2010, 22:38:51
Alıntı yapılan: picusta - 18 Eylül 2010, 09:54:50
Yanliz unutmaman gereken sey pals degiskeni her iki kesmede kullaniliyor. Eger birisi ona erisirken digeri degerini degistirirse sorun olabilir. (2 byte'lik deger oldugundan 1. bayt, 2. bayt)
birisi ona erişirken diğeri değerini değiştiremez cunku bır ınterrupt bitmeden diğerine gecemez.
Bu PIC'te oldugu gibi 2 kesme önceligi olursa olur (kesme önceligi bu ise yarar).
Hazir PID ancak PLC'lerde blok halinde olur, mikroislemcilerde olsa olsa MAC (multiply accumulate olur), DSP'lerde FFT hardware acceleration.
Yapilan hesaplama belli : çarpma toplama.

kesme önceliği su işe yarar. eğer iki kesme tamamen aynı anda gerceklesırse birindn birine oncelık verır. szin dediğiniz biri işlerken öbürüne atlama olayı kı bu pic tarihinde gerceklersmemıs bır olaydır.

picusta

Alıntı yapılan: zamzam23 - 22 Eylül 2010, 17:24:27
Alıntı yapılan: picusta - 20 Eylül 2010, 11:17:30
Alıntı yapılan: zamzam23 - 18 Eylül 2010, 22:38:51
Alıntı yapılan: picusta - 18 Eylül 2010, 09:54:50
Yanliz unutmaman gereken sey pals degiskeni her iki kesmede kullaniliyor. Eger birisi ona erisirken digeri degerini degistirirse sorun olabilir. (2 byte'lik deger oldugundan 1. bayt, 2. bayt)
birisi ona erişirken diğeri değerini değiştiremez cunku bır ınterrupt bitmeden diğerine gecemez.
Bu PIC'te oldugu gibi 2 kesme önceligi olursa olur (kesme önceligi bu ise yarar).
Hazir PID ancak PLC'lerde blok halinde olur, mikroislemcilerde olsa olsa MAC (multiply accumulate olur), DSP'lerde FFT hardware acceleration.
Yapilan hesaplama belli : çarpma toplama.

kesme önceliği su işe yarar. eğer iki kesme tamamen aynı anda gerceklesırse birindn birine oncelık verır. szin dediğiniz biri işlerken öbürüne atlama olayı kı bu pic tarihinde gerceklersmemıs bır olaydır.
Ben PIC18Fxx2 datasheetinin yalancisiyim.
Alıntı YapHigh priority interrupt sources can interrupt a low priority interrupt.
http://ww1.microchip.com/downloads/en/devicedoc/39564c.pdf
Sayfa 73 (pdf 75).
Proteusta simulasyonunu yap veya test programi yazip devrede çalistir (iki ledli bir devre yapabilirsin mesela).


kanuncan

Merhaba,yazınızı baştan sona okudum ve fikir almaya çalıştım ama sizinki ile benzer olan sorunumu bir türlü çözemedim,yardımcı olur ya da hatam varsa gösterirseniz çok sevinirim,
elimde çift kanal 100 pals encoderu olan bir adet 24 volt dc motor var,bu motor ile bir mesafenin encoderdan aldığım bilgi ile boyunu ölçüyorum.Elde ettiğim toplam boyun bir bölümünde motoru belirli bir ivme ile belirlediğim bir hıza kadar hızlandırıyorum,sonra devam eden bir bölümde bu hız ile sabit olarak devam ettiriyorum ve devam eden bir başka bölümde de motoru yine önceden belirlediğim bir hıza belirli bir ivme ile düşürüyorum ve kalan son bir bölümde de en son düşürdüğüm hız ile motoru sürüyorum.Yani ölçülen toplam mesafede önce hızlan sonra sabit hızla git sonra yavaşla ve yavaşladığın hız ile meafeyi tamamla diyorum,buraya kadar her şey güzel.Ancak motoru sürdüğüm iki sabit hız mesafesinde hızın dış kuvvetlerden arınmasını istiyorum,yani bu iki sabit hız mesafesinde motora durdurucu ya da hızlandırıcı bir kuvvet etkirse motor buna karşı sabit hızını korusun istiyorum ve bunun için PI controlden faydalanmak istedim ama bir türlü başaramadım,yardımcı olursanız çok sevinirim.

1-mikrodenetleyicide dahili bir interrupt kurdum,bu interrupt önceliği encoder harici interrupt dan sonra yani 2. öncelikli ayarladım.timer interrupt ını motor tam sabit hız noktalarına girdiğinde başlatıp Encoder ın o anki değerini bir değişkene attım,    ilk_Deger=EncA_CNT; sonra belirli bir süre bitiminde Encoder degerini ikinci bir degişkene atadım ve bu süre icinde encoder ın saydığı değeri hesapladım,bu degeri refarans değer olarak aldım,yani sabit hız mesafesi boyunca aynı süre icinde aynı degerde adım sayısı alacağım. ikinci_Deger=EncA_CNT; Ref_Deger=ikinci_Deger-ilk_Deger; sonrasında  ayni süre içerisinde sürekli olarak fark değeri hesaplayıp referans değer ile karşılaştırarak
Hata hesabı yaptım,    Fark_Deger=EncA_CNT-ikinci_Deger;   ikinci_Deger=EncA_CNT;
Hata=Ref_Deger-Fark_Deger; sonra bu değeri  PI formulünde kullandım ama sonuç alamadım, kod tam olarak aşagıdaki gibi,nerede hata yaptığımı söyleyebilir misiniz..! teşekkür ediyorum.

//------------------------------------------- hata hesabı----------------------------------------------------------
void tmrRB_isr(void)
{//Calisma_Ekrani();
PulseWidthCounter ++;
if (PulseWidthCounter==10&&__Sonuc_Al!=1)
{ ilk_Deger=EncA_CNT;
      }//if end                           
      else if(PulseWidthCounter==20&&__Sonuc_Al!=1)         //2,4 us sonra ikinci ornek aliniyor      
      { ikinci_Deger=EncA_CNT;   Ref_Deger=ikinci_Deger-ilk_Deger;   
                                 
   __Sonuc_Al=1;PulseWidthCounter=10;// hatanin hemen hesaplanmasi icin esitleniyor   
      }//else if end   
    if(__Sonuc_Al==1&&PulseWidthCounter==10)                      {                           
      Fark_Deger=EncA_CNT-ikinci_Deger;
      ikinci_Deger=EncA_CNT;                  
      Hata=Ref_Deger-Fark_Deger;
      PulseWidthCounter=0;                     
   }//else if end      
}
//------------------------------------------PI Hesabi---------------------------------------------------------
unsigned long KapaliDonguKontrol(unsigned long GelenOran)
{      unsigned long GidenOran=0,HesabaGirenOran=0;
   //__disable_interrupt();
   HesabaGirenOran=GelenOran;
         __Integral=__Integral+Hata*Ki*0,012;//örnekleme suresi ile carpiyoruz
      __Oransal=Kp*Hata;
      if(__Integral>100)__Integral=100;
      if(__Integral< -100)__Integral= -100;
      GidenOran=HesabaGirenOran+__Oransal+__Integral;
      Hata=0;
return GidenOran;
}
"Denemedikçe ne yapacağını hiç kimse bilemez"

zamzam23

#25
#int_timer0  //25 msn
void  timer0_kesme ()   
    {
    if (yon==0) pals1=65536-pals1;
     hiz=(pals1*40)/xx;
     hata=reff-hiz; 
  
       integral=integral+hata;
     P=Kp*hata; 
     I=Ki*(integral*dt); 
     yeni=(int8)(P+I); 
           
           if(yeni >120)  yeni = 120;   
           if(yeni <1)  yeni = 0; 
          
         set_pwm1_duty(yeni); 
         pals1=0; set_timer0(3036); 

    }


ben PI ve PID srununu hallettim gibi. kullandığım formulü verdim. koda bakınca anlayacagını zannediyorum. kodu aynen kullanamazsın tabıkı. sana yol göstermesi için yazdım. kodu kendine göre düzenlemelisin. Parametreleri de soyle ayaladım:
1tane lcd ekran ve 5 tane buton
kp,ki,kd basta hepsi sıfır. ekrana yazdırdım. sonra butonların herbirini bir parametre için ayarladım.(örneğin 1. butona basınca kp=kp+0.1 komutu işliyor) 4. butonu da parametreleri asagı cekmek ıcın kullandım. (örneğin 1. ve 4. butona basarsak kp=kp-0.1 komutu ıslıyor) 5. buton da reff_hiz değeini artırıyor. (reff_hiz++). yıne 4. ve 5. butona basınca reff_hiz-- oluyor. buna uygun deneme fonksıyonunu hazırlıyoruz.fonksıyonn sonunda motora enerjiyi verip sonsuz döngüye sokuyoruz.ardından  butonlarla motor döner vaziyette ıken artır azalt yaparak istediğimiz reff_hiz değerindeki davranısına bakıyoruz.en uygununu ayarlıyoruz.arada bir de tabi reff_hiz i artırıyoruz azaltıyoruz. farklı hızlardakı davranısı da önemlı. bitti bu kadar.

dt değeri örnekleme zamanı. yani bu koda göre dt=0.025;değişkenleri uygun tipte tanımlarsınız zaten. kolay gelsın.

kanuncan

yanıtınız ve açıklamalarınız için teşekkür ediyorum, bu pi kontrolü ilk defa kullaniyorum ve bir hayli sikintisini yaşadim ama şuan belli bir noktaya geldim,tekrar anlatayim hatam varsa düzeltirseniz sevinirim,benim için oldukça önemli bir projede kullaniyorum,açıklamam başkalarına da fikir verebilir hem,

100 pals çözünürlükte bir encoder dan geri besleme alıyorum, dc motoru sürmek için PWM i   2000 oraninda artırıp azaltarak değişik hizlar elde ediyorum, ayarlanmis sabit hizlarda birtane timer ı baslatip her 10 ms de bir encoder dan gelen pals sayisindaki değisime bakiyorum,encoderdan gelen palsi harici interrupt ile sayıyorum, referans hızı ise her pwm oranı icin her 10 ms deki encoder pals sayisindaki değişimden hesapladım,örneğin 1000 pwm oranında motor hareket ederken timer her 10 ms de 20 pals saydı.referans hız olarak V_Ref=20 pals/10ms. bu şekilde tüm pwm oaranları için referans hızları belirledim.dışarıdan ayarlanan pwm oranına karşılık V_Ref  değeri 10ms için hesaplanıyor ve o oranda  o referans değeri kullanılıyor.
hata=V_Ref-V_Bulunan, V_Bulunan hareket sırasında her 10 ms de elde edilen pals sayısı. ıntegral=ıntegral+Ki*Hata; burada dt ornekleme zamanını 10ms icin 0,001 olarak kullanmalı mıyım? yani Integral=Integral+Ki*Hata.0,001; şeklinde ? BİR DE EN ONEMLİ SORUM,PI KONTROLDE ÇİFT KANAL ENCODER KULLANMANIN BİR ARTISI VAR MIDIR? şimdiden teşekkür ediyorum.   
"Denemedikçe ne yapacağını hiç kimse bilemez"

zamzam23

değişik PI hesağlama yöntemleri var ve az da olsa formulleri de farklı. benm verdiğim koddaki I değişkeni integral değişkeni oluyor. kodu inceleyin e kodunuzu da ona göre uyarlamaya calısın.
encoder, PI kontrolün sadece hız verısını elde etmede işe yarıyor. siz hızı ister tek kanal ister çift kanal encoderle elde edin farketmez. 2 kanal olunca program ıcınden motorun dönüş yönünü de bilebiliyorsunuz. hepsi bu.

kanuncan

Önemli bilgileriniz için teşekkür ediyorum,hepsi çok aydınlatıcı oluyor,bir sorum daha olacak,hareketin sabit ivmeli yani hızlanan veya yavaşlayan durumlarında da pi kontrol uygulanabilir mi? Uygulanırsa nasıl?
saygılarımla...
"Denemedikçe ne yapacağını hiç kimse bilemez"

zamzam23

gecikmeyle bunu sağlayabilirsiniz.örneğin
for(a=0;0<=10;a++)
{
reff_hiz=a;
delay_ms(25);
}

benım PI fonksiyonum interuptın içindeydi ona sıra geldikce de hızı reffhiza göre ayarlıyordu.ama isizn PI fonk interuptın dısında foksıyon seklınde olabılır o zmnda reff_hiz=PI(a); seklınde reff hızını PI fonksiyonuna gönderirsiniz.hatta gecikmeyi foksiyonun ıcınde verecekseniz PI(a,time) seklınde bir fonksıyonda yazabılrısın.

veya da bana da önerilen rampa[] dizisine yazarsın reff değerlerini oradan cekersin.sana kalmıs hangisini uygularsan. kolay gelsın.