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

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

kanuncan

//---------------------------------------- 666666666 Encoder A Interrupt Rutine 77777777777------------------------------------------//
void Int1_isr(void)
{            
if(PI_BASLADI==1)PI_Degiskeni++; //pi hiz hesabi icin saydiriliyor bu deger pi fonksiyonu icinde her 10 ms de bir sifirlaniyor


   if(EncoderSecimi==__ENC_A | EncoderSecimi==__ENC_AB){
       EncA_CNT +=1;//hareket konumu belirlemek için saydiriliyor
       }//

} //burada encoder dan gelen palsleri saydırıyorum.


//----------------------------------------- Timer B interrupt Loop Periode Rutine ---------------------------------------//
void tmrRB_isr(void)
{//timer b
   
if(PI_BASLADI==1)PI_Zamani++;
    if(PI_Zamani==3)// timer b interrupt ı her 10/3 ms de gerceklesiyor 10 ms icin 3 kez timer b interrupt ı gerceklesmesi gerekiyor
    {//if pi
   
      
   __e=V_Ref-V_Out;//hatayi hesapliyorum
   if(__e>5) __e=5;// ani tasmalara karsi hatayi sinirliyorum
   if(__e<-5)__e=-5;
   __Integral=__Integral+ Ki*__e*0,01;//integral aliyorum,  0,01 sn ornekleme zamani 10 ms 
   __Oransal= Kp*__e; //oransal kazanci hesapliyorum
   
   if(Aktivasyon_Durumu==ACMA)//hareket yonu acma ise pi uygulanacak pwm kanali belirleniyor
   
   {
      V_Cikis=__A_YonPWM+__Integral+__Oransal;
      if(V_Cikis>__A_YonPWM+150)V_Cikis=__A_YonPWM+150;//burada integral ve oransal ani kazanc sinirlaniyor toplam pwm oraninin % 7,5 unu gecemez
      __A_YonPWM=V_Cikis;if(__A_YonPWM>__MaxPWM)__A_YonPWM=__MaxPWM;//Cikisin sonsuza gitmesi onleniyor
      
      }
   
   if(Aktivasyon_Durumu==KAPAMA)//hareket yonu kapama ise pi uygulanacak kanal belirleniyor
   
   {
         V_Cikis=__B_YonPWM+__Integral+__Oransal;
      if(V_Cikis>__B_YonPWM+150)V_Cikis=__B_YonPWM+150;//burada integral ve oransal ani kazanc sinirlaniyor % toplam pwm oraninin %7,5 nu gecemez
      __B_YonPWM=V_Cikis;__B_YonPWM=V_Cikis;if(__B_YonPWM>__MaxPWM)__B_YonPWM=__MaxPWM;//Cikisin sonsuza gitmesi onleniyor
      
      }
   
    PI_Zamani=0;PI_Degiskeni=0;//yeni ornekleme icin hem encoder saydigi deger hem de ornekleme zamani sifirlaniyor
    }//end pi


}//end timer b

//burada da pi uyguluyorum, mantikta hata var mi? tesekkür ederim
"Denemedikçe ne yapacağını hiç kimse bilemez"

kanuncan

#31
//---------------------------------------- 666666666 Encoder A Interrupt Rutine 77777777777------------------------------------------//
void Int1_isr(void)
{            
if(PI_BASLADI==1)PI_Degiskeni++;//pi hiz hesabi icin saydiriliyor bu deger pi fonksiyonu icinde her 10 ms de bir sifirlaniyor


   if(EncoderSecimi==__ENC_A | EncoderSecimi==__ENC_AB){
       EncA_CNT +=1;//hareket konumu belirlemek için saydiriliyor
       }//

}//burada encoder pals sayisini okuyorum yani hiz bilgisini aliyorum
"Denemedikçe ne yapacağını hiç kimse bilemez"

kanuncan

//----------------------------------------- Timer B interrupt Loop Periode Rutine ---------------------------------------//
void tmrRB_isr(void)
{//timer b
   
if(PI_BASLADI==1)PI_Zamani++;
    if(PI_Zamani==3)// timer b interrupt ı her 10/3 ms de gerceklesiyor 10 ms icin 3 kez timer b interrupt ı gerceklesmesi gerekiyor
    {//if pi
   
      
   __e=V_Ref-V_Out;//hatayi hesapliyorum
   if(__e>5) __e=5;// ani tasmalara karsi hatayi sinirliyorum
   if(__e<-5)__e=-5;
   __Integral=__Integral+ Ki*__e*0,01;//integral aliyorum,  0,01 sn ornekleme zamani 10 ms 
   __Oransal= Kp*__e; //oransal kazanci hesapliyorum
   
   if(Aktivasyon_Durumu==ACMA)//hareket yonu acma ise pi uygulanacak pwm kanali belirleniyor
   
   {
      V_Cikis=__A_YonPWM+__Integral+__Oransal;
      if(V_Cikis>__A_YonPWM+150)V_Cikis=__A_YonPWM+150;//burada integral ve oransal ani kazanc sinirlaniyor toplam pwm oraninin % 7,5 unu gecemez
      __A_YonPWM=V_Cikis;if(__A_YonPWM>__MaxPWM)__A_YonPWM=__MaxPWM;//Cikisin sonsuza gitmesi onleniyor
      
      }
   
   if(Aktivasyon_Durumu==KAPAMA)//hareket yonu kapama ise pi uygulanacak kanal belirleniyor
   
   {
         V_Cikis=__B_YonPWM+__Integral+__Oransal;
      if(V_Cikis>__B_YonPWM+150)V_Cikis=__B_YonPWM+150;//burada integral ve oransal ani kazanc sinirlaniyor % toplam pwm oraninin %7,5 nu gecemez
      __B_YonPWM=V_Cikis;__B_YonPWM=V_Cikis;if(__B_YonPWM>__MaxPWM)__B_YonPWM=__MaxPWM;//Cikisin sonsuza gitmesi onleniyor
      
      }
   
    PI_Zamani=0;PI_Degiskeni=0;//yeni ornekleme icin hem encoder saydigi deger hem de ornekleme zamani sifirlaniyor
    }//end pi


}//end timer b
//burada da pi hareket yonüne gore uyguluyorum

mantikta bir hata var mı? saygılar...
"Denemedikçe ne yapacağını hiç kimse bilemez"

zamzam23

#33
  __Integral=__Integral+ Ki*__e*0,01;//integral aliyorum,  0,01 sn ornekleme zamani 10 ms

satırı

__Integral=(__Integral+ __e)*0.01*Ki; olmalı
veya

iki parca halınde yaparsanız daha iyi olur

integral=integral+hata;
integral2=(integral*0.01)*ki;


zamanlamalara dikkat edin. örnekleme aralıgı 0.01 dedik. eğer her 0.01 sn de işlem tekrarlamazsa gzl calısmaz.

justice_for_all

arkadasim counter kullansan daha iyi olabilirdi ayrica timer0 kesmesine girince kesme suresi kisaysa kesmeyi pasif yapip kesme sonunda aktif yapman gerekir .. Bide arkadasin biri timer0 i 16 bit kullanmis sanirim ama ben ccs c de timer 0 8 bit kullaniliyo die biliyorum..C18 de kullanabiliyosun 16 bit ama ccs izin vermiyo die biliyorum..Kanuncan ayrica degisken isimlerin cok karmasik zar zor seciliyo helede onunde alt cizgiler varken..Kolay gelsin...tabiki iki encoderli daha guvenilir ama normal piclerle zor olur o zaman QEI gerekli buda dspiclerde var fircali bir dc motor icinde o kadar ayrintiya gerek yok yani onlar fircasizlar icin kullaniliyo genellikle...
Deneyip de başaramayanları değil, yalnızca denemeye bile kalkışmayanları yargıla.   Gökhan Arslanbay

kanuncan

Konuya ilişkin uygulama başarı ile gerçekleştirilmiştir,bu ve benzeri sorun yaşayan arkadaşlar isterlerse kendilerine buradan yardımcı olurum.
"Denemedikçe ne yapacağını hiç kimse bilemez"

zamzam23


kanuncan

pi yeterli oldu ama istenirse d de eklenebilir.sistem çok kararlı çalıştığı için ekleme yapmadım.
"Denemedikçe ne yapacağını hiç kimse bilemez"

pisayisi

hedef pozisyon kontrolu gerektiren bir uygulama ise pd kontrol en verimli olanıdır. hız kontrol uygulamalarında ise pid tercih edin derim...
Murat

Huzame

Alıntı yapılan: kanuncan - 25 Kasım 2011, 11:48:54
pi yeterli oldu ama istenirse d de eklenebilir.sistem çok kararlı çalıştığı için ekleme yapmadım.


Mümkünse video ekleyebilir misiniz?

Okan AKÇA

pid oransal kontrol end. sanayide en cok kullanılan yontem.

kanuncan

tabiki,en kısa sürede eklemeye çalışacağım,ayrıca pid 220 VAC triac tetikleme ile sıcaklığı nasıl kontrol ettiğimin videosunu da ekleyeyim.Videoları hazırladığımda ekleyeceğim.
"Denemedikçe ne yapacağını hiç kimse bilemez"

zamzam23

motor için pi katsayılarını nasıl buldun?

kanuncan

Kullanmış olduğum motor redüktörlü olduğu için şöyle bir işlem yaptım.Öncelikle,redüktör oranı=MotorDevri(Yüksek hız)/RedüktörÇevrimliHız(Düşük) buldum,yani 3000 dv/dk devir ve 200 dv/dk redüktör aktarımlı hıza sahip bir motor için 3000/200=15 olarak bulunur.Sonra encoder pals sayısını ve motor miline redüktörden sonra bağlı ve ası hareketi sağlayan disk çevresini hesaba katarak açısal hızı encoder pals sayısı olarak tespit ettim,bu durumda 1 cm/sn hız için 75 pals kapalı kontrol değeri almam gerekti.Bu 100 pals encoder için geçerli,,siz formulü kurup değişkenleri dışarıdan değiştirebilirsiniz böyle değişen değişken değerlerine bağlı olarak yeni kapalı döngü değeri otomatik olarak hesaplanacak.Ki ve Kp değerlerini bulmaya gelince öncelikle Ki değerini sıfır olarak aldım ve istediğim gerçek hızı en kısa sürede en yakın değerce veren Kp değerini bulana kadar Kp değerini artırdım ve kesinlikle float değer kullanmadım,bunu güç elektroniği konusunda iyi birkaç akademisyenden tavsiye olarak aldım.Kp değerini ayarlarken sistemin tepkisi,titremeli,ani iniş çıkışlı hareketler şeklinde olacak.Siz istediğiniz hız çevresinde titremeli olarak gerçekleşen harekette Kp değerini bırakın.Sonra aynı şekilde Ki değerini hesaplayın.Bunun için her defasında programda ki ve kp değerlerini değiştirip durmayın. dışarıdan 2 buton aracılığı ile bu değerleri tam sayı olarak artırıp azaltın.Sonrasında titremesiz bir şekilde istediğiniz hıza eriştiğinizde Ki değerini  sabit bırakın.Kp değeri Ki değerinin yaklaşık olarak 7 -10 katı civarında çıkacaktır.Bu noktada dikkat etmeniz gereken hususlar pi sınırlarınızı çok iyi yapmanızdır,aksi halde hareketi sınırlayan sağlam bir blokta sonsuza tırmanan bir hız artışı motor sürücü buloğunuzun yanmasına neden olacaktır.Şimdilik bu kadar.
"Denemedikçe ne yapacağını hiç kimse bilemez"

zamzam23

motor için soruyorum

pi döngüsünü timer içerisinde mi kullandınız. sadece pi döngüsü için yazdıgın kodu paylasırmısın.süre hesaplamaları ve katsayılarla birlikte.

benım pi döngüm de katsayılar seninkiler gibi cıkmadı bi yerde hatammı var onu belirlemeye calısıyorum. sistem düzgün calısıyor bende ama.