Picproje Elektronik Sitesi

ENDÜSTRiYEL OTOMASYON => Kontrol Teorisi - Matematiği => Konuyu başlatan: zamzam23 - 24 Haziran 2011, 11:59:45

Başlık: PID döngü yaptım calısıyor anck sıkıntı var
Gönderen: zamzam23 - 24 Haziran 2011, 11:59:45
arkadaşlar PID hız kontrollü motor var. normal çalısıyor motor yüksüzken hızı değiştirdiğimde kısa sürede reff hıza ulaşıor. ancak motora yük bindiğinde o kdr da başarılı calısmıyor. titreme yapıyor sonucta bazen istenen reff hızına oturuyor bazen oturmuyor sapıtıyor. sorun benım PID kodlarımda mı yoksa katsayılarında mı yardımcı olursanız sevınırım.ya da bu konuda ücretli profosyonel yardım da alabılırım.
ccs de yazılmıs PID kodu: kesme 15ms de bir işliyor.P,II ve DD float tipi, hata ve hata3 ise int tipi değişken.

#int_timer0  //15 msn
void  timer0_kesme ()   
    {
     hiz=(pals1<<6)/xx;
     hata=reff-hiz;
     if(hata>5) hata=5;  if(hata<-5) hata=-5;
     integral=integral+hata;
     if(integral > 150) integral = 150;
     else if(integral < -150) integral = -150;
     P=3.3*hata;
     II=58.7*((float)integral*0.015628);
     DD=(float)(gd)*((float)(hata-hata3)/0.015628);
      if(DD > 150) DD = 150;
     else if(DD < -150) DD = -150;
     yeni=(int8)(P+II+DD);
   
        if(yeni>200) yeni=0;
        else if(yeni >150)  yeni = 150;   
       hata3=hata;
         set_pwm1_duty(yeni);
         pals1=0;set_timer0(63093);

    }
Başlık: Ynt: PID döngü yaptım calısıyor anck sıkıntı var
Gönderen: z - 24 Haziran 2011, 12:53:39
Timer rutini içindeki kodların işlenmesi ne kadar zaman alıyor?
Başlık: Ynt: PID döngü yaptım calısıyor anck sıkıntı var
Gönderen: zamzam23 - 24 Haziran 2011, 14:13:35
bunu hiç hesaplamadım ama encoderden gelen palsleri duzgun sayıyor.onları sayarkende RB0 kesmesı kullandım
Başlık: Ynt: PID döngü yaptım calısıyor anck sıkıntı var
Gönderen: iyildirim - 24 Haziran 2011, 15:22:03
Hesaplanan duty 200 den büyük olduğunda neden bir üst limit tanımlanmıyorda sıfırlanıyor.
Başlık: Ynt: PID döngü yaptım calısıyor anck sıkıntı var
Gönderen: PROTECH_ - 24 Haziran 2011, 15:43:41
   bide şu şekilde dene

         if(yeni<0)        yeni=0;
       else if(yeni >255) yeni = 255;

out=(uint8)yeni;   
       
hata3=hata;         
set_pwm1_duty(out);         
pals1=0;set_timer0(63093); 
                       
Başlık: Ynt: PID döngü yaptım calısıyor anck sıkıntı var
Gönderen: zamzam23 - 24 Haziran 2011, 17:07:34
Alıntı yapılan: PROTECH_ - 24 Haziran 2011, 15:43:41
   bide şu şekilde dene

         if(yeni<0)        yeni=0;
       else if(yeni >255) yeni = 255;

out=(uint8)yeni;   
       
hata3=hata;         
set_pwm1_duty(out);         
pals1=0;set_timer0(63093); 
                       

uint8 nedir ccs de derlenmiyor
Alıntı yapılan: iyildirim - 24 Haziran 2011, 15:22:03
Hesaplanan duty 200 den büyük olduğunda neden bir üst limit tanımlanmıyorda sıfırlanıyor.

üst limit 150. "yeni" değişkeni int bir değişken. dolayısıyla - değer almıyor 0 dan asagı dusunce 255 oluyor. ben de onu sınırlamak ıcın 200den buyukse 0 a esıtle dedım.
Başlık: Ynt: PID döngü yaptım calısıyor anck sıkıntı var
Gönderen: JKramer - 24 Haziran 2011, 18:32:57
unsigned int8
Başlık: Ynt: PID döngü yaptım calısıyor anck sıkıntı var
Gönderen: optimum - 24 Haziran 2011, 19:36:37
sakıncası yoksa bunun devresinide ekliyebilir misiniz?
Başlık: Ynt: PID döngü yaptım calısıyor anck sıkıntı var
Gönderen: PROTECH_ - 25 Haziran 2011, 16:13:32
Alıntı yapılan: zamzam23 - 24 Haziran 2011, 17:07:34
Alıntı yapılan: PROTECH_ - 24 Haziran 2011, 15:43:41
   bide şu şekilde dene

         if(yeni<0)        yeni=0;
       else if(yeni >255) yeni = 255;

out=(uint8)yeni;   
       
hata3=hata;         
set_pwm1_duty(out);         
pals1=0;set_timer0(63093); 
                       

uint8 nedir ccs de derlenmiyor
Alıntı yapılan: iyildirim - 24 Haziran 2011, 15:22:03
Hesaplanan duty 200 den büyük olduğunda neden bir üst limit tanımlanmıyorda sıfırlanıyor.

üst limit 150. "yeni" değişkeni int bir değişken. dolayısıyla - değer almıyor 0 dan asagı dusunce 255 oluyor. ben de onu sınırlamak ıcın 200den buyukse 0 a esıtle dedım.

"uint8"  i "unsigned char"  olarakda alabilirsin
Başlık: Ynt: PID döngü yaptım calısıyor anck sıkıntı var
Gönderen: zamzam23 - 27 Haziran 2011, 19:26:26
unsigned char mı int mi
Başlık: Ynt: PID döngü yaptım calısıyor anck sıkıntı var
Gönderen: fatihinanc - 27 Haziran 2011, 20:48:17
Zaten uint8 8bitlik unsigned integer dır.
Yani bir nevi unsigned char olabilir.
Başlık: Ynt: PID döngü yaptım calısıyor anck sıkıntı var
Gönderen: zamzam23 - 28 Haziran 2011, 09:09:20
bir nevisi mi var. değişkene sayı atıyoruz char nasıl oluyor. char da 8 bitlik diye oyle diyorsun belli ki.neyse
Başlık: Ynt: PID döngü yaptım calısıyor anck sıkıntı var
Gönderen: fatihinanc - 28 Haziran 2011, 12:52:16
Alıntı yapılan: zamzam23 - 28 Haziran 2011, 09:09:20
bir nevisi mi var. değişkene sayı atıyoruz char nasıl oluyor. char da 8 bitlik diye oyle diyorsun belli ki.neyse
Farketmez ki.
İster char ister uint8 olarak tanımla, bellekte yine 1 byte yer kaplar. Yani char tanımlayınca uint8 e göre farklı biryerde farklı bir adres gösterilmez.
Okuma amacına göre okuduğun değeri karakter veya sayı olarak kullanabilirsin.
Başlık: Ynt: PID döngü yaptım calısıyor anck sıkıntı var
Gönderen: zamzam23 - 28 Haziran 2011, 12:54:47
evet öyle. peki saol ama sorun hallolmadı eksik birseyler var yine.
Başlık: Ynt: PID döngü yaptım calısıyor anck sıkıntı var
Gönderen: fatihinanc - 28 Haziran 2011, 12:56:00
Alıntı yapılan: zamzam23 - 28 Haziran 2011, 12:54:47
evet öyle. peki sağol ama sorun hallolmadı eksik birseyler var yine.
;)
PID Konusunda çok fazla yorum yapamayacağım, o konuda üstadlar daha iyi yardımcı olacaktır.
Başlık: Ynt: PID döngü yaptım calısıyor ancak sıkıntı var
Gönderen: zamzam23 - 28 Haziran 2011, 16:20:28
şöyle bir sıkıntı var: 50m/sn ye ye kdr motor hızlanıyor sonra sapıtıyor PID yanlıs ve dogrusunu nasıl yapıcam bılmıyorum katsayıları bulmak cok sıkıntılı. deneme yanılmayla yaptım sanıyordum ama yapamamısım yük binince titreme yapıyor tam oturmuyor ref hız degerıne
Başlık: Ynt: PID döngü yaptım calısıyor anck sıkıntı var
Gönderen: zamzam23 - 29 Haziran 2011, 10:38:14
arkadaslar baska konu acıp da kalabalıklık olusturmak ıstemıyorum forumda. PID dongusu yazdım ama sıra katsayıları bulmaya geldi. motorun PID katsayılarını nasıl bulabılırım?kp>ki mi olmalı yoksa tersi mi? kd=0.001 gibi birsey mi olmalı yoksa kd>1 mi olmalı nerden baslamalıyım? deneme yanılmayla bulucam artık baska yol yok sanırım
Başlık: Ynt: PID döngü yaptım calısıyor anck sıkıntı var
Gönderen: zamzam23 - 11 Temmuz 2011, 15:42:43
bana bu pid konusunda hakkıyla yardım edecek bi allahın kulu yok mu ya
Başlık: Ynt: PID döngü yaptım calısıyor anck sıkıntı var
Gönderen: Tagli - 11 Temmuz 2011, 17:09:52
Ziegler–Nichols yöntemi olarak bilinen bir yöntem başlangıç değerleri hakkında fikir verir, ama bu yöntemi uygulamak her zaman mümkün olmayabilir.

Genelde deneme yanılma ile yapılıyor ayar. Microchip'in ters sarkaç konusundaki bir uygulama notunda (http://ww1.microchip.com/downloads/en/AppNotes/00964A.pdf) bir dizi adım önerilmiş, ama tabi bunlar senin sistemin için geçerli olmayabilir.

Başlık: Ynt: PID döngü yaptım calısıyor anck sıkıntı var
Gönderen: Klein - 11 Temmuz 2011, 18:18:18
PID'yi zaten yapmışsın. Parametre ayarları tamamen senin sisteminin dinaiği ile ilgili oduğu için , birşey söylemek gerçekten zor.  Bu yüzden yardımcı olmak da oldukça zor. 
Genel olarak hangi parametrenin etkisi nasıl olacaktır bundan bahsedeyim. Belki oturmayan taşlar biraz olsun yerine yerleşir.

Kp parametresi:Bu parametre set değerimiz ile çıkışımız arasındaki farka yani hataya göre çıkışa hangi büyüklükte bir sinyal uygulayacağımızı belirler. 
Örneğin:
Bir motor kontrolümüz var. Kontrolü PWM ile ayarlıyoruz.
PWM %0 olduğunda motor 0 devir %100 olduğunda ise  motorumuz 1000 devir oluyor.  Eğer PID kullanmasaydık  500 devir istediğimizde  motora %50 PWM uygulayacaktık.  İşte Kp katsayısı da bunu belirler.  Yani bizim Kp katayımız burda 0.1 dir. her bir RPM değişim için çıkışa uygulamamız gereken değer.
Eğer KP yüksek olursa ne olur:Çıkışa her zaman olması gerekenden daha fazla veya daha az güç uygulanacağı için sistem osilasyona girer.
Şöyle örnekleyebiliriz. Bir otomobiliniz var , güzel de bir gaz pedalı var ama sizin ayağınızın ayarı yok.  istediğiniz hıza ulaşmak için gaza yüklendiniz araba hızlandı ,baktınız ki fazla hızlandı ayağı gazdan çektiniz. bu sefer de fazla yavaşladı. Gaza ne kadar basacağınızı ayarlayamazsanız bir hızlanır bir yavaşlarsınız.
Düşük olursa ne olur:Sisteme olması gerekenden daha az güç uygulayacağımız için, ya istediğimiz değere ulaşamaz , ya da en ufak yüklenmede kendini bırakır.
Yine otomobilden örnekleyecek olursak:
Gaza az bastığınızda arabanın ivmelenmesi düşük olacaktır. 10 saniyede 100Km hıza çıkmak isteyeceğiz ama gaza yumurtaya basar gibi bastığımız için  daha biz 50 km hıza çıkmadan bir kırmızı ışık göreceğiz ve durmak zorunda kalacağız. Tabiki istediğimiz yere olmamız gereken zamandan çok daha uzun zamanda varacağız.
Ya da kırmızı ışık görmedik yolumuz uzun. Gaza hafif hafif bastık , ama istediğimiz hıza bir türlü çıkamadık.
Diyelim ki yeterince gaza basmışız, istediğimiz hıza geldik. 
Ama o da ne bir rampa! Eğer biz gaza aynı şekilde basmaya devam edersek  yokuşta araba bayılacak ve hızımız yine düşecek.
Bunu  motorun yüke binmesine benzetebiliriz.

Ki Parametresi:Ki parametresi  bizim ivmelenmemizi artıran parametre. Arabamızdaki vites değiştiren adam.
Herseferinde bir önceki sefer ile şimdiki arasındaki hataya bakarak, sistemin daha hızlı tepki vermesini sağlar.
Örneğin Kp düşük. veya tam değerde. 500 devir dönmesi gereken motora %50 PWM verdik. Bu değer bize sonuçta seti yakalattıracak. Ama ne kadar zaman sonra?
Sisteme yarım güç uyguladığımız için ivmelenmemiz de daha az olacak. Yükselttiğimiz zama da osilasyona girecek.
Peki ne yapacağız?
Buarada yardımımıza Ki yetişir. Bir önceki periyottaki hataya bakar , şimdiki periyottaki hataya bakar ,
Der ki biz çok yavaş hızlanıyoruz. Ya da bir yokuşa geldik araba hız kaybetmeye başladı,  hemen duruma el koyar. Hemen arabanın vitesini küçültür. Biz gaza aynı da bassak,
Vitesimiz küçüldüğü için daha hızlı ivmeleniriz. Ama sonra bir bakar ki araba almış başını gitmiş. Demek ki bu vites düşük geldi der ve
vitesi yarım vites büyütür. Ve böylece ivmelenme azalır. Daha sonra yine bakar bu sefer de vites fazla büyük , bu sefer vitesi
çeyrek viter küçültür. Tabi ivmelenmemiz yine artar, ama daha öncekinden daha az artar. Bu şekilde
vitesi biraz büyütüp biraz küçülterek doğru vitesi bulur. Biraz deneme yanılmacı bir kişiliği vardır.
Eğer yüksek olursa:Vitesi her zaman daha yüksek oranlarda artırıp azaltacağı için doğru vitesi bulana kadar bir hızlanır bir yavaşlarız.
Düşük olursa: İvmelenmemiz de yavaş olacaktır.

Kd Parametresi:Güvensiz bir kişiliktir. Arabadaki vites değiştiren adama güvenmediği için ayağı her zaman frenin üzerindedir.
Gözü de her zaman hız göstergesinde olur.
Ki adamımız vitesi küçülttüğünde ivmelenme artınca tırsar. Gözü hemen göstergeye kayar. Bakar ki çok hızlı ivmeleniyoruz.
Hemen ufak ufak frene basmaya başlar. Hızımız istenilen hıza yaklaştıkça frene daha fazla asılmaya başlar. Kontrollü kişiliğinden dolayı
nerede ne kadar frene basacağını bildiği için , hız limiti aşılmadan önce hızlanmayı düşürür.

Yüksek olursa: Frene biraz fazla asılacağı için ivmelenmeyi fazla düşüteceği için , Ki adamı sürekli vitesle oynar
ve sistem osilasyona girer.
Düşük olursa : Yeterince etkili olamadığı için kaderimiz Ki adamına bağlı kalır.


Ekleme:
Kendmi elindeki dandik malı kakalamaya çalışan pazarlamacı gibi hissetmeye başladım ama,
PID parametrelerinin çıkışa etkisini grafik üzerinde görmek sistemi anlamayı kolaylaştırıyor.
Bu yüzden yine başka bir proje için yazdığım basit simülatörün linkini veriyorum.
Simülasyonda volan etkisi vs.. olmadığı için ihtiyacı tam karşılamayabilir. Ama yine de fikir veriyor.
Program basit bir .exe programcık. makinenizi kasmaz.
http://hotfile.com/dl/123755653/6020228/PID_TEST_PRJ.rar.html (http://hotfile.com/dl/123755653/6020228/PID_TEST_PRJ.rar.html)

Diğer konuyu takip etmediyseniz ,  kullanımını tekrar açıklarım.
Başlık: Ynt: PID döngü yaptım calısıyor anck sıkıntı var
Gönderen: NaMcHo - 11 Temmuz 2011, 19:17:54
Alıntı yapılan: bunalmis - 24 Haziran 2011, 12:53:39
Timer rutini içindeki kodların işlenmesi ne kadar zaman alıyor?

Merhabalar konu dışında bir sorum olucak ama, bir if bloğu içindeki kodların ne kadar sürede işletildiğini nasıl hesaplarızı?

while(1)
{
    if(kontrol1)
    {
        TRISB=0x00;
        PORTB=5;
    }
    if(kontrol2)
    {
        for(x=1;x<=8;x++)
            PORTB>>1;
    }
}


Bu kod için Fosc=4MHz olsun herhangi bir PIC entegre kullanıyo olalım,kontrol1 içine girildiğinde  1/( (Fosc/4)*2 )  kadarlık bir sürede,
kontrol2 kısmında ise 1/( (Fosc/4)*8 ) kadarlık bir sürede mi tam olarak işletişmiş olucak kodlarımız?
Birde yine benzer olarak bu hesaplamaları ARM veya MSP serisi entegrelerle yaparken Fosc'yi 4'e bölmeden mi yapıcaz( Mimarisine bakarak mı kara vericez bu dörde bölme olayında )?
Başlık: Ynt: PID döngü yaptım calısıyor anck sıkıntı var
Gönderen: Klein - 11 Temmuz 2011, 19:25:36
İf bloğu için oluşturulan ASM kodu bilmeden , hesaplamak zor.  İf bloğu işletilmeden önce timer'i sıfırlayıp , blok bitiminde de timer'i okursanız olabilir.
Başlık: Ynt: PID döngü yaptım calısıyor anck sıkıntı var
Gönderen: zamzam23 - 12 Temmuz 2011, 00:48:41
Klein arkadaş. programın kullanılısını hangi linkte bulabılırım ya da bıraz anlatır mısın?
birde sundan bahsedeyım PID dongusunde D parametresını iptal ettim. kullandıgım parametrelere gore sıstemın davranısı şöyle:
set değerine oturuyor ancak bu baya zaman alıyor 10 sn gibi. bu süreyi kısmak için parametrelrle asagı yukarı oynuyorum ama sistem osilasyona giriyor ne yapmam lazım?yazdıgın uzun paragrafa göre ki yi artırmalıyım artırıyorum ancak osilasyona giriyor. D parametreli döngüyü de henüz calısıtırabılmek nasip olmadı.PID timer içinde oldugu için süremi uzun geliyor anlamadım D parametresin devreye alınca sistem  iyice sapıtıyor
Başlık: Ynt: PID döngü yaptım calısıyor anck sıkıntı var
Gönderen: Klein - 12 Temmuz 2011, 01:10:34
Programın kullanımı basit.
Sol üstte Set , Pset , Iset, Dset var. Bunların ne olduğu zaten belli.  Bulardan herhengi birini değiştirmek için , değeri girdikten sonra enter tuşuna basmak yeterli.  Noktalı sayı  kullanırken nokta yerine  virgül kullanmak gerekiyor.

Bir de en sağda üstte varsayılan değeri 20 olan kutucuk var.  O değer , set değerinin sürekli olarak değiştiği bir durumu simüle etmek için kullanıldı.  Set değerine oradaki kadar sayıyı , belirli bir zaman aralığında ekler ve çıkarır.  Sabit bir set değeri istiyorsan onu 0 yapmalısın.
Bunun dışında diğer parametrelerle girmene gerek yok. Onlar başka bir konu için vardı. Bu başlık için gereksiz.
Mavi çizgi set değerimizi , kırmızı çizgi ise çıkış değerimizi gösteriyor.

İlk mesajında da yanılmıyorsam yüke binince motorun titrediğinden bahsetmiştin.  Bu titremenin PID ile ilgili olduğu kesin mi? PID olmadan çıkış değerini el ile ayarladığında motor dönüyor mu? Eğer  yüke binince tork düşüyorsa Ki değerini artırmalısın.
Başlık: Ynt: PID döngü yaptım calısıyor anck sıkıntı var
Gönderen: zamzam23 - 12 Temmuz 2011, 07:50:35
yüke binince titreme yapıyordu o şimdi bitti kaysayıları biraz oturtunca. ancak şimdi de oturma süresi baya bi uzun onu kısaltmak için sanırım ya kesmenin süresini kısaltıcam ya da ki kp değerleriyle oynayacam. birde türev parametresi için şu formul dogru mu:

derivative=kd*( (hata-hata2)/dt )
döngü sonunda da
hata2=hata;
Başlık: Ynt: PID döngü yaptım calısıyor anck sıkıntı var
Gönderen: Tagli - 12 Temmuz 2011, 08:48:34
İfade doğru. Yavaş oturuyorsa Kp'yi arttırman gerekiyor. Bence önde Ki'yi kapatıp Kd'yi kurcala osilasyonu engellemek için. Bir diğer mesele de kullandığın sensörde parazit varsa özellikle D bundan çok etkilenir. Sistem Kd'yi arttırırken saçmalamaya başlıyorsa sorun bundan olabilir.
Başlık: Ynt: PID döngü yaptım calısıyor anck sıkıntı var
Gönderen: zamzam23 - 12 Temmuz 2011, 13:43:10
D yi iptal ettim K ve I gzl çalısın bana yeter. söylediklerinizin ışıgında calısmalarım sonunda şu noktaya vardım:
başlangıcta set değeri=20cm/sn
motor ilk harekette 12m/sn
sonra yavas yavas artıyor 20 ye oturuyor fark sıfır olunca da öyle devam ediyor.yük bindirsem d 1-2 cm/sn hız azalıyor sonra kendını toparlıyor set değerine gelip oturuyor. sonra
set değerini 50 ye kadar belırlı aralıklarla cıkarıyorum. yine benim peşim sıra yavas yavas hız artarak gelıyor 5-10sn ıcerısınde set değerine oturuyor.
sonra set değerini azaltmaya baslıyorum 50 den yavas yavas belırlı aralıklarla iniyorum yine benim peşim sıra beni takip ediyor ve set değerine gelip oturuyor ta ki set değeri=2 ye kadar.
diyelim ki hız=3 set değer 3. bu durumda stabıl calısırken
set değerini 1 yapıyorum. hız gelıyor 2 oluyor sonra tam 1 olup değer oturacakken birden 50 ye cıkıyor hız sonra yine kendını azaltmaya baslıyor 1 e gelıyor sonra yıne 50 ye fırlıyor.halbukı bu durumlarda set değerim hep 1

sıkıntı nedir sizce? programı tekrar veriyorum acaba sağa sola shift işlemleri var onları yaparken mi bit kayboluyor ne yapıyor anlamadım


#int_timer0  //15 msn.
void  timer0_kesme ()   
    {
    hiz=(pals1<<6)/xx;
    //if(hiz>50) hiz=50;
    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>>6);//0.0594
        yeni=(unsigned int8)(P+II);
        if(yeni >150)  yeni = 150;
                set_pwm1_duty(yeni);
         pals1=0;set_timer0(63093);

    }
Başlık: Ynt: PID döngü yaptım calısıyor anck sıkıntı var
Gönderen: Tagli - 12 Temmuz 2011, 14:19:11
Kafamı karıştıran noktalar var, bilmiyorum belki de ben kodu anlamadım.

Öncelikle, sorun sanki yeni değişkeninin bir şekilde fazla yükselmesinden kaynaklanıyor gibi. Bence sorun "yeni=(unsigned int8)(P+II);" kod parçasıyla ilgili. P+II değeri yavaşlama sırasında negatif olacak. Ama sen bunu işaretsiz bir hale getirmeye çalışıyorsun. Dönen değer işaretsiz olarak ifade edildiğinde doğal olarak 150'den büyük oluyor. Ayrıca yine "II=gi*(integral>>6)" satırı da bana tehlikeli gözüktü. Sanırım burada bölme işlemi yapmak istiyorsun ama negatif bir sayıyı bu şekilde bölmeye çalışırken işaretine de dikkat etmelisin. Muhtemelen soldan sıfır giriyor ve eksi olan işaret artıya dönüşüyor. Önce bir bu dediklerimi kontrol et, mümkünse debug yaparak.

Tabi tamamen yanılıyor da olabilirim, ilk şüphelendiğim şeyleri yazdım.
Başlık: Ynt: PID döngü yaptım calısıyor anck sıkıntı var
Gönderen: Klein - 12 Temmuz 2011, 14:35:14
Aşağıdaki kodu bir dener misin?


float ref,hiz;
float output=0;
float error=0;
float olderror=0;
float oldolderror=0;
float Kp = 1;
float Ki=0;
float Kd=0;


void pid(void){
            error = (ref-hiz)/10;
            output = output + Kp * (error - olderror + (Ki * error) + (Kd * (error - olderror * 2 + oldolderror)));
             oldolderror=olderror;
             olderror = error;
             if(output>150)  output =150;
             if(output<0) output = 0;
}
Başlık: Ynt: PID döngü yaptım calısıyor anck sıkıntı var
Gönderen: zamzam23 - 12 Temmuz 2011, 14:58:18
Alıntı yapılan: Tagli - 12 Temmuz 2011, 14:19:11
Kafamı karıştıran noktalar var, bilmiyorum belki de ben kodu anlamadım.

Öncelikle, sorun sanki yeni değişkeninin bir şekilde fazla yükselmesinden kaynaklanıyor gibi. Bence sorun "yeni=(unsigned int8)(P+II);" kod parçasıyla ilgili. P+II değeri yavaşlama sırasında negatif olacak. Ama sen bunu işaretsiz bir hale getirmeye çalışıyorsun. Dönen değer işaretsiz olarak ifade edildiğinde doğal olarak 150'den büyük oluyor. Ayrıca yine "II=gi*(integral>>6)" satırı da bana tehlikeli gözüktü. Sanırım burada bölme işlemi yapmak istiyorsun ama negatif bir sayıyı bu şekilde bölmeye çalışırken işaretine de dikkat etmelisin. Muhtemelen soldan sıfır giriyor ve eksi olan işaret artıya dönüşüyor. Önce bir bu dediklerimi kontrol et, mümkünse debug yaparak.

Tabi tamamen yanılıyor da olabilirim, ilk şüphelendiğim şeyleri yazdım.
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.
II=gi*(integral>>6) satırında dediğin gibi negatif bölmede işaret kayboluyor olabılır debug yok yapamıyorum ama negatif bolmede işaretin kybolmaması ıcın ne yapmam lazım onu da bılmıyorum sonucta ccs nin kendı fonksıyonu işareti kaybetmemesı lazım.
Alıntı yapılan: Klein - 12 Temmuz 2011, 14:35:14
Aşağıdaki kodu bir dener misin?


float ref,hiz;
float output=0;
float error=0;
float olderror=0;
float oldolderror=0;
float Kp = 1;
float Ki=0;
float Kd=0;


void pid(void){
            error = (ref-hiz)/10;
            output = output + Kp * (error - olderror + (Ki * error) + (Kd * (error - olderror * 2 + oldolderror)));
             oldolderror=olderror;
             olderror = error;
             if(output>150)  output =150;
             if(output<0) output = 0;
}

bu fonksiyonu ne kdr sıklıkla cagırıcam? türevde ve integralde kullanılan dt değeri ne olmalı?
Başlık: Ynt: PID döngü yaptım calısıyor anck sıkıntı var
Gönderen: Tagli - 12 Temmuz 2011, 15:17:25
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.
Başlık: Ynt: PID döngü yaptım calısıyor anck sıkıntı var
Gönderen: iyildirim - 12 Temmuz 2011, 15:33:23
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..

Başlık: Ynt: PID döngü yaptım calısıyor anck sıkıntı var
Gönderen: zamzam23 - 12 Temmuz 2011, 16:27:09
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"

Başlık: Ynt: PID döngü yaptım calısıyor anck sıkıntı var
Gönderen: Tagli - 12 Temmuz 2011, 16:38:56
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.
Başlık: Ynt: PID döngü yaptım calısıyor anck sıkıntı var
Gönderen: zamzam23 - 12 Temmuz 2011, 16:48:47
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?
Başlık: Ynt: PID döngü yaptım calısıyor anck sıkıntı var
Gönderen: iyildirim - 12 Temmuz 2011, 17:11:41
Zamzam23 kodun son halini değişkenlerin tipleri de belli olacak şekilde verebilirmisin..
Başlık: Ynt: PID döngü yaptım calısıyor anck sıkıntı var
Gönderen: zamzam23 - 12 Temmuz 2011, 17:48:46
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);

    }
Başlık: Ynt: PID döngü yaptım calısıyor anck sıkıntı var
Gönderen: Klein - 12 Temmuz 2011, 18:02:34
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.
Başlık: Ynt: PID döngü yaptım calısıyor anck sıkıntı var
Gönderen: zamzam23 - 12 Temmuz 2011, 19:17:18
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?
Başlık: Ynt: PID döngü yaptım calısıyor anck sıkıntı var
Gönderen: Klein - 12 Temmuz 2011, 19:57:46
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.
Başlık: Ynt: PID döngü yaptım calısıyor anck sıkıntı var
Gönderen: moksan - 08 Haziran 2015, 17:13:29
@zamzam23 merhaba.. CCS wiev topicteki bir yorumunu gördüm.
http://www.ccsinfo.com/forum/viewtopic.php?t=40259&highlight=nguyen+thanh+tuan+entete (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.?