Pid motor kontrolünde FeedBack Periyodu

Başlatan Mucit23, 05 Mayıs 2014, 12:55:44

mozkan87

Alıntı yapılan: Mucit23 - 14 Mayıs 2014, 16:00:28

Set Değeri 100 RPM değeri 101 veya daha fazla oluca çok büyük değerler alıyorum. 54000+ küsür. Aradaki farka göre git gide artıyor.

error değişkenini ne olarak tanımladınız, unsigned tanımlamadınız değil mi?
Birde ilk denemelerde katsayıları küçük tanımlayın, daha sonra sistemin tepkisini arttırmak istediğinizde katsayı değerleriyle oynayın.
http://en.wikipedia.org/wiki/PID_controller
Linkteki grafikleri incelerseniz katsayılarla oynadığınızda ne tür değişiklikler olacağını kestirebilirsiniz.

Mucit23

#16
Hocam int16 türünde tanımlamıştım. Ben negatif değer alacağını düşünüyordum ama almıyormuş meğer. Signed int16 türünde tanımladım.

Şimdiki durum ise şöyle.
Yine pid fonksiyonuna sabit değerler veriyorum.
Referans değeri Motor RPM değerinden büyükse PI sonucunda elde edilen değer hatanın boyutune göre hızlı veya yavaş pozitif yönde sürekli artıyor.
Referans değeri Motor RPM değerinden küçükse bu dediğim işlemin tam tersi oluyor. Yani PI sonucu negatif yönde sürekli artıyor.

Sanırım problem yok. PID parametreleri ise default olarak hepsi 1 olarak belirledim. Ama ayarlamak için bir menü yaptım. Menüden değiştirebiliyorum.

Hocam şimdi Bu işlemin sonucunda elde ettiğim değeri PWM registerine yazmam lazım.

Benim PWM duty registerim 0-1000 arası değer alıyor.

PI işlemi sonucundada Negatif veya pozitif değer alabiliyor.  PID sonucunda elde ettiğim değeri Duty registerine nasıl aktaracağım? Mantığı nedir?

mozkan87

Katsayılar tam olarak ayarlandığında ve feedback mekanizmasında bir sorun olmadığında pid değeri negatif veya çok yüksek değer almayacaktır ama işi garantiye almak için pwm register'a değeri atamadan önce değerler aralıkta mı diye bir kontrol işe yarar(özellikle sisteme zarar verilebilecek durumlarda bu sınırlar güvenli bölgede tutulursa iyi olur). İlk olarak katsayılarınız kontrol periyodunuza göre çok büyük geliyor gibi duruyor bu nedenle sisteminiz sürekli salınımda kalıyor, katsayıları 0.1 gibi değerler ayarlayın bu tepki sürenizi uzatacaktır ama salınımın önüne geçer. Siz denemeleri manuel olarak yaptığınız ve kontrol periyodundan çok yavaş tepki verdiğiniz için sistem değeri arttırıyor veya azaltıyor ama feedback te değişiklik göremediği için bu işlemi sürekli yapmaya devam ediyor.

Eğer ilk etapta bu şekilde öğrenmek için deneme yapacaksanız(motor bağlamadan) kontrol periyodunu(dt)'yi 5 saniye gibi bir değere ayarlayın ve feedbacki elle değiştirip sonucu karşılaştırın.

Mucit23

Hocam şu negatif pozitif olayını ben isiste denedim. Ama gerçektede oluyor fakat çok daha hızlı. Şuan elimde kurulu donanım var. Gerçekte test yapabiliyorum.

Şöyle sistem ilk çalışmaya başladığında referans değerini 500rpm yapıyorum. Pid Referans değerinin 500 motor devrinin 0 olduğunu görünce motor hemen enerjileniyor ve referans değerini çok kısa bir sürede geçiyor.

Bu durumda referans değeri motor devrinden küçük olacağı için error ve pid işlemi sonucundaki output değeri negatife iniyor. Yani bi anlamda salınım oluyor. Çıkış değerinin negatif olması demek benim PWM duty değerinin azaltmam gerektiği anlamına geliyor. İşte bunu nasıl yapacağımı bilmiyorum.  Bu konuda öneriye ihtiyacım var.

Aslında benim aklıma şöyle bir yöntem geldi.

PID fonksiyonun güncel değerini ve bir önceki değerini sürekli takip edeceğim. Şayet yeni gelen değer eski gelen değerden büyük ise demekki pozitif yönde bir artış vardır. O halde nekadarlık bir artış olduğunu bulup bunu PWM duty registerine ekleyeceğim.

Şayet yeni gelen değer eski değerden küçük ise o halde negatif yönde bir artış vardır. O halde yine yeni değerle eski değer arasındaki farkı bulup duty registerinden çıkartacağım.

Bu durumda iken zaten güvenlik için PWM duty registerinin alt ve üst limitleri kontrol altında olur. Bu düşündüğüm sistem sağlıklı çalışırmı?

DT değeri ise şuanda benim için soru işareti. Ben 100ms aralıklarla ölçüm yapıyorum. her 100ms sonun pid işlemi uyguluyorum. Bu durumda DT ne olması gerekir. Ben 0.1 verdim. 5 versem sonuç nasıl değişir?

z

#19
Motor referans degeri gectimi  Hata=Ref-Cikis negatif deger alir.

Pozitif degerler +v anlamina gelirken negatif degerler -V anlamina gelir.

Yapacagin sey motora ters voltaj vermekten ibaret. 

Hata pozitif iken PWM +V genligini belirlerken negatif hatada PWM -V genligini belirleyecek.

Eger H kopru benzeri yapin yoksa ve hata negatif olduysa ters voltaj uygulamak yerine frenleme yapabilirsin. Motor voltajini kesip voltaj uygulamazsan motorun yavaslamasi uzar. Cunku mekanik yuk motoru surukler.
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

Mucit23

Hocam yaptığım PCB kart veya donanım Motora ters voltaj vermeye müsade etmiyor.

Motoru tek mosfet ile flyback olarak sürüyorum.


Huzame

Hocam  ben de tam olarak tamamlanmayan bir çalışmam oldu ben şöyle bir şey denedim isis'te çalışıyordu bir dene istersen
              if(giris > cikis){
                  fark = giris - cikis;
              }
              if(giris < cikis){
                  fark = cikis - giris;
             }

z

Alıntı yapılan: Mucit23 - 14 Mayıs 2014, 21:33:12
Hocam yaptığım PCB kart veya donanım Motora ters voltaj vermeye müsade etmiyor.

Motoru tek mosfet ile flyback olarak sürüyorum.

Olmaz boyle.

Motorda volan gibi bir yuk varsa motoru yavaslatamazsin. Bahsettigin sistemi ancak surtunmeli yuklerde kullanabilirsin.
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

Mucit23

Hocam sistemin PID mantığını kavramaktan başka bir amaçla yapmadım. İleride bir iki proje yapacağım. Daha önce PID'e hiç elimi bulaştırmadım. Tecrübe kazanmaya çalışıyorum.

Motor milinde enkoder diskinden başka motorun momentumunu arttıracak birşey yok. Bu yüzden enerjisi kesildiğinde kısa bir süre içerisinde motor duruyor. Yani frenlemeye ihtiyaç olacağını zannetmem. İlk hedef verdiğim devirde motoru sabitlemesi.


Mucit23

Şu negatif sayı işini çözemedim. Bunu çözersem işin çoğunu halletmiş olacağım. Programsal olarak öneriye ihtiyacım var.

Sorunu Tekrarlayayım.

PWM Duty registerim 0-1000 arası bir değer alabiliyor.

Benim PID fonksiyonuma gönderdiğim SET değeri Motorun RPM değerinden büyük ise PID işlemi sonucunda pozitif yönde sürekli artan bir değer alıyorum. Bu aldığım değeri DUTY registerine yazarsam hiç sıkıntı olmuyor. Motor zorlanmalara karşı tepki veriyor.

Fakat Motorun RPM değeri SET değerinden büyük olunca Bu sefer PID fonksiyonu bana negatif  yönde artan değerler vermeye başlıyor. İşte bu aşamadan sonra benim duty registerini PID fonksiyonundan gelen değere göre azaltmam gerekiyor. Burada tıkandım kaldım.

Bunu nasıl yaparım?

mistek

#25
Değişkenlerde taşma olabilir mi?

uint16 tanımlamış olabilirsin belki negatifte sorun oluyordur.

PWM registerına nasıl yazıyorsunuz? calc_pid çıktısını olduğu gibi orayamı geçiyorsunuz.

Eğer öyleyse

Birde şunu denermisiniz.

Sizin kodunuzun anlaşılır bir bölümünüde buraya koyarsanız iyi olur.

int16 calc_pid(unsigned int16 set_value, unsigned int16 rpm_value){
static int16 output=0;
  
  error= set_value-rpm_value;
  err_dif=error-old_error;
  
  P = Kp * error;
  I = I + (Ki * error * DT);
  D =(Kd * err_dif) / DT;
  
  output += (int16)( P + I + D);
  old_error = error;
return output;
}



boş işlerin adamı ---- OHM Kanunu: I = V/R ---- Güç Formülü: P = V*I = I^2*R = V^2/R

Mucit23

#26
Hocam kusura bakmayın, işlerden dolayı fazla ilgilenemiyorum. Bu yüzden geç yazıyorum.

Aslında problemi kendi yöntemlerimle çözdüm.

şu şekilde bir algoritma kurdum.
     if(pid_ready_flag)
     {
        if(ref_value>0) 
        {
            output=(signed int16) calc_pid(ref_value, mot_rpm);
            output_dif=abs(output-old_output);
            if(output>=old_output)
            {
              duty_val+=output_dif;
              if(duty_val>1000) duty_val=1000;
            }
            else
            {
               duty_val-=output_dif;
               if(duty_val<0)duty_val=0;
            }
            old_output=output;
            set_pwm1_duty((unsigned int16)duty_val);
        }
        else
        {
          set_pwm1_duty((unsigned int16)0);
        }
        pid_ready_flag=0;
     }


PID fonksiyonundan gelen değerlere baktım. Bir önceki ile bir sonraki arasındaki farkı bulup gelen sayının pozitif veya negatif olma durumuna göre duty registerine ekledim veya çıkardım.

Çalışıyor.

Ama PID fonksiyonu yine negatif değerler gönderiyor. Anlamadığım nokta, diyelim motor devri set değerini aştı ve pid fonksiyonu negatif değerler göndermeye başladı. Motor devri ile set değeri eşitlense bile artık negatif değer göndermeye devam ediyor. Sanki bir önceki değerler hafızada tutuluyorda PID fonksiyonu eski değerin üzerine ekleme yapıyor.

Artık Biraz kodları irdelemem lazım.

@Mistek
Hocam siz fonksiyon sonunda elde ettiğiniz değeri output değerine eklemişsiniz. Bence  bu tümüyle yanlış. Böyle yaparsam saniyeler içerisinde göre dönen değer binlere çıkar ve sürekli artar

Edit;
Bir diğer sorum şu olacak.

Ben PID katsayılarını min 0.1 olacak şekilde ayarlamıştım. P ve PI kontrolde yeterli oluyordu. Ama D kontrolü yani türevide ekleyince motor Pd katsayısı 0.1 olmasına rağmen motor osilasyona giriyor.

Acaba D kontrol için 0.1 çokmu fazla bir değer? Step aralığını 0.01'mi yapayım?

mistek

#27
Haklısınız output min ve max değerler için limit fonksiyonunu yazmayı unutmuşum.

P + I + D çıkışa eklenecek. Bu toplam pozitif olduğunda duty artar toplam negatif olduğunda önceki değerden çıkarılarak duty azaltılacak.

Motor kontrolde çoğu zaman PI yeterli gelir. İhtiyaç yoksa D hiç eklemeyin. Veya küçük katsayılar kullanın.
boş işlerin adamı ---- OHM Kanunu: I = V/R ---- Güç Formülü: P = V*I = I^2*R = V^2/R

Mucit23

Hocam Sıkıntım kalmadı.

Kullandığım motor 12V da 2500RPM dönüyordu. PI ile çok güzel sonuçlar aldım. PID ilede denemeler yaptım.

PID parametrelerini uygun değerler yaptıktan sonra motoru bir elimle tutup diğer elimlede motor mili sıkıştırıp serbest bıraktığımda motorda aşağıdaki grafik teki gibi bir salınım oluyordu

Bu salınımı elimle hissedebiliyordum.