PID döngü yaptım calısıyor anck sıkıntı var

Başlatan zamzam23, 24 Haziran 2011, 11:59:45

Tagli

Alıntı yapılan: zamzam23 - 12 Temmuz 2011, 14:58:18
P+II negatif nasıl olur set_pwm_1 degerine negatif değer yüklenmezki benım bıldıgım. 0 sa %0, 150 ise %100 pwm.
Örnek: Referans = 1, Hız = 3 -> Hata = (1 - 3) = -2
Bu durumda hataya bağlı olan P ve II ifadeleri ve bunların toplamı olan P+II ifadesinin negatif olması kaçınılmaz. Tabi II daha önceden yüksek bir pozitif değer almış ve bundan kurtulamamışsa pozitif çıkabilir ama durumun böyle olduğunu sanmıyorum.
Gökçe Tağlıoğlu

iyildirim

Anladığım kadarıyla PWM değeri 8bitlik.

Ancak Tagli'nin de dediği gibi hesaplanan değerin negatif olma ihtimali var. Eğer işaretli -1'i işaretsiz olarak değerlendirirsek sonuç 255 çıkar. Bu da hız düşürülmeye çalışıldığında neden arttığını açıklayabilir.

Yeni değişkenini signed int olarak tanımlayıp, sonuc sıfırdan küçükse sıfıra eşitleyip, sanırım max limit olan  150 den büyükse de 150 ye eşitleyip, Sonra PWM duty sine aktarın..


zamzam23

iyildirim, dediğinizi yaptım ama olmadı.
ccs serdar çiçeğin kitabında bu var bununla alakalı olabilir mi:

"set_pwm1_duty(deger)

deger kısmına yazılan sayı 8 bitlik ise derleyici bu değeri 2 kere sola kaydırır ve 10 bitlik yapar. 2 kez sola kaydırma işleminde değer 4 ile çarpılmıs olur. 8 bitlik deger ve 10 bitlik değer yazıldıgında görev çevrim süresi değişir.
10 bitlik ise:
t=deger*Tosc*TMR2 oranı
8 bitlik ise:
t=deger*Tosc*TMR2 oranı*4"


Tagli

Bu 8 biti 10 bit yapma işi sakat olabilir. İşaretten dolayı değil. PWM frekansına göre çözünürlük daha düşük olabiliyor, datasheet'lerde genelde bir tablo olarak örnekleri verilir. Frekans artarken çözünürlük azalıyor. Ama asıl mesele şurada: Çözünürlük 8 bit olduğunda büyük 8 biti değil küçük 8 biti yazmak gerekiyor. Yoksa duty süresi PWM periyodundan fazla olabiliyor ve çıkış 1 olarak kalıyor.

set_pwm1_duty(deger) fonksiyonunu Serdar Çiçek mi yazmış yoksa CCS C'nin dahili fonksiyonu mu? Ama dediğin gibi 8 bitlik değeri 4 ile çarpıp yerleştiriyorsa muhtemelen yanlış çalışıyor. Veya senin çözünürlük yüksek frekans sebebiyle 10 bit olamadığı için sorun çıkıyor.
Gökçe Tağlıoğlu

zamzam23

ccs nin dahili fonksiyonu. serdar yazmamıs.
Alıntı yapılan: Tagli - 12 Temmuz 2011, 16:38:56
Ama asıl mesele şurada: Çözünürlük 8 bit olduğunda büyük 8 biti değil küçük 8 biti yazmak gerekiyor. Yoksa duty süresi PWM periyodundan fazla olabiliyor ve çıkış 1 olarak kalıyor.
asıl mesele bu ise asıl çözüm nedir?

iyildirim

Zamzam23 kodun son halini değişkenlerin tipleri de belli olacak şekilde verebilirmisin..

zamzam23

float P=0.0,II=0.0,gi=4.4,gp=3.3;
unsigned int8 yeni=0,hiz=1;
signed int16 integral=0;
signed int8 reff=0,hata=0;
#int_timer0  //15 msn.
void  timer0_kesme ()   
    {
       if ((yon==0)||(iki_sn==1)) pals1=65536-pals1;
    hiz=(pals1<<6)/xx;
    hata=reff-hiz;
     if(hata>5) hata=5;  if(hata<-5) hata=-5;
     integral=integral+hata;
     if(integral > 10000) integral = 10000; 
     else if(integral < -10000) integral = -10000;
     P=gp*hata; //9.99
     II=gi*(integral/64);//0.0594
        yeni=(unsigned int8)(P+II);
      if(yeni >150)  yeni = 150;
                if(reff==0)
        {yeni=0;integral=0;hata=0;}
         set_pwm1_duty(yeni);
         pals1=0;set_timer0(63093);

    }

Klein

bu fonksiyonu ne kdr sıklıkla cagırıcam? türevde ve integralde kullanılan dt değeri ne olmalı?


Hızı nasıl okuyorsun? sabit aralıklarla gelen darbe sayısını mı?   tur süresini mi?

Yukarıda varmış şimdi gördüm.  10mS ile bir başla. Gerekirse biraz hızlandırırız.

zamzam23

klein
şuan evdeyim düzenek iş yerinde. ama kod hakkında birkaç birşey sorabilirim yarın denerim konustuklarımızı.

1-kodun işlenme periyodu önemli ve kesin değil midir? sonucta türev de integral de dt süresin göre alınmıyor mu?
2-error = (ref-hiz)/10; hatayı neden 10a böldük
3-birde vermiş oldugun değişkenlerde kd=0 ki=0
bunları ben ayarlamalıyım galıba ama kp=1 vermişsin bu 1 mi kalacak?

Klein

Kodun işleme periyodu önemli tabiki.
Örneğin sisteminiz çok yavaş tepkilere sahip. Sizin pid  zamanınız çok küçük yani çok hızlı. Bu durumda daha sisteminiz PID çıkışına tepki veremeden , PID çıkışınız hızla artacak veya azalacak kontrolünüz zorlaşacak.
Tam tersi durumda ise  PID, sistemin hızına yetişemeyeceği için , sistem alıp başını gidecek.
Bu yüzden PID hızına da biraz sistem ve ne kadar sürede ölçüm alabildiğiniz karar verecek.

Bu kodda zaman, 1 öçüm periyodu. Bundan daha hızlı yapmamız da olanaksız. sonuçta çıkışa bir sinyal uygulayacağız ve tepkiyi görmek için ölçüm peritodu kadar bekleyeceğiz. Bu yüzden PID kodunu her ölçümden sonra çağıracağız. Bu da kodunuzdan anladığım kadarıyla 15mS civarı. Zaman biraz göreceli bir kavram. Biz burada dt yi 1 periyot olarak alıyoruz. Buradaki PID artımlı bir PID. PID değeri hesaplanıp çıkışa  bu değeri vermek yerine , her periyotta çıkışı hesaplanan değer kadar artırıp azaltmaya dayalı.

Error'u neden 10'a böldüm. Simülasyonla ilgili bir durumdu.biraz yavaşlatmam gerekiyordu. Siz kullanmayabilirsiniz. 
Kd ve Ki   başlangıç değeri olarak 0 verdim siz bir değere ayarlarsınız.  Kp 1 verdim ama sadece 0 olmasın diye verilmiş bir değer.

moksan

@zamzam23 merhaba.. CCS wiev topicteki bir yorumunu gördüm.
http://www.ccsinfo.com/forum/viewtopic.php?t=40259&highlight=nguyen+thanh+tuan+entete
Bu kişinin yazdığı kodu denedin mi?PID algoritması ile sıcaklık kontrolü yapmak istiyorum.ssr röleyi sürücem pwm çıkışında.önerilerin nelerdir.?