Jump to content
şenol eker

Nedir bu PID? Neden gerekli?

Önerilen İletiler

şenol eker    0

Örnekler bir ısıtıcı sistem üzerinden verileceğinden, ISI ve SICAKLIK nedir, arasında ne fark vardır bilmiyorsanız ya da kafanızda tam net değilse, şimdi bu sayfayı kapatıp ISI VE SICAKLIK makalesine gidin, onu okuyup anladıktan sonra buraya gelin. Aksi halde bu makaleyi anlamanız gerçekten sıkıntıya düşecektir.

PID birçok yerde kullanılsa da en iyi "bir odayı ısıtma" problemi ile tarif edilebilir. Bir odanın sıcaklığını sabit tutmak istiyorsak, bir ısıtıcı elemana, bir de sıcaklığı ölçen elemana ihtiyacımız var. Sıcaklığı ölçen elemana "termometre", ısıtıcı elemana da "ısıtıcı" diyelim.

İlk akla gelen şey, eğer termometre istediğimiz sıcaklıktan az bir değer gösteriyorsa ısıtmaya başlar, istediğimiz sıcaklığa ulaşınca da ısıtmayı keseriz. Bunu hepimiz biliriz,  "termostat" bunun adı.

Ama şöyle bir sıkıntı var: Eğer termometreyi hemen ısıtıcının yanına koyarsak, ısıtıcı çalışır çalışmaz termometre yüksek bir sıcaklık değeri gösterir. Çünkü ısıtıcı gerçekten sıcaktır. Ama ısıtmamız gereken ortam henüz ısınmamıştır. O halde termometreyi ısıtıcıdan uzağa koymamız gerekir.

Termometreyi uzağa koyduğumuzda ortam ısınır, ama tam da istediğimiz sıcaklıkta tutamayız ortamı. Isıtıcıyı çalıştırdığımızda ısıtıcı ortamı ısıtmaya başlar, termometremiz sıcaklığı görür, istenen sıcaklığa geldiğinde ısıtıcıyı kapatırız ama ısıtıcının yüksek sıcaklığı ile ortam bir süre daha  ısınmaya devam eder, sıcaklık bizim istediğimizden daha yüksek değere çıkar. Neyse, düşene kadar bekleriz, sıcaklık sınıra geldiğinde ısıtıcıyı açarız ama bu sefer de ısıtıcı kendini ısıtana kadar ortam soğumaya devam edeceğinden bizim istediğimiz sıcaklığın altına düşer. Mesela biz 30 dereceye ayarladıysak bir 25'e düşer, bir 35'e çıkar. Eh, bu da bir şey tabii ki. Ama neden daha iyisi olmasın? Nasıl bir şey yapmalıyız ki sıcaklık tam da o derecede dursun?

Aslında şöyle yapabiliriz:

Isıtıcımız aç - kapa şeklinde değil de ayarlı olsa, ilk başta sonuna kadar açıp ortamı istenen sıcaklığa getirsem, sonra öyle bir şekilde kıssam ki, istediğim sıcaklıktan ne aşağı ne yukarı gitmese. Ne güzel olur değil mi?

Bu mümkün aslında. Yapmamız gereken oda ne kadar ısı kaybediyorsa, ısıtıcıdan aynı miktar ısıyı ortama verirsek odanın sıcaklığı sabit kalır. Peki odanın ne kadar ısı kaybettiğini nereden bileceğiz? Bunu ölçmek zor değil mi? Bunun bir kolayı yok mu?

Bunu yapmak aslında çok kolay. Isıtıcıyı öyle sonuna kadar açmayacağız. Oda sıcaklığı ile bizim istediğimiz sıcaklık arasındaki fark ne kadar büyükse o kadar çok açacağız. Tabii tam tersine istenenden daha sıcak ise, ısıtıcıyı daha çok kısacağız. Böylece tam noktasını bulabileceğiz.

Termometreden gelen sıcaklık "t" olsun.

İstediğimiz sıcaklık "g" olsun.

Bu "g-t" değeri, bizim hatamızdır.

Yani bizim sistemimiz istenen şeyi yapamamış demektir. Yani bir hatamız var demektir. Bu hata da, istenen ve ölçülen sıcaklık değerleri arasındaki farktır. Biz, bu farkın yani hatanın sıfır olmasını isteriz. Bakın bu "hata" çok mühim. PID'in kalbi bu "hata"

(Devam Edecek)

İletiyi paylaş


İletiye bağlantı
Sitelerde Paylaş
şenol eker    0

PID'deki bu üç harf, üç hesaplamaya karşılık gelir.

Birincisi: P. Proportional'in kısaltması. Proportional kelimesi, "oransal" demek sözlüklere göre. Zaten birçok durumda PID'nin sadece P'sini kullandığımızda işimiz görülür. Odanın "sıcaklığını" sabit tutabiliriz. I ve D ise, kapı açılıp kapandığında içerisi soğuyacak ya, istenen sıcaklığa daha "düzgün" gelmesi içindir.

Önceki gönderide "hata"yı hesaplamıştık. Hesap denirse tabii :) Yani istenen sıcaklıktan ölçtüğümüz sıcaklığı çıkartmıştık.

Bu hata ne kadar büyükse, ısıtıcımızı o kadar "güçlü" çalıştıracağız.

Mesela ısıtıcıyı PWM ile ya da analog olarak çalıştırıyor olabiliriz. (PWM ve Analog nedir biliyorsunuz umarım. Bilmiyorsanız önce bunları iyice anlayın, aksi halde devamı havada kalacaktır, kafanız karışacaktır, dolayısı ile devam etmeyin, PWM'i öğrenin, Analog kontrolu öğrenin sonra buraya tekrar gelin)

Isıtıcımızı her ne şekilde kontrol ediyorsak edelim, bunu bir "sayı" ile yapacağız. Bu sayının bir alt bir üst sınırı vardır. Mesela PWM ile kontrol ediyorsak bir "duty cycle", analog olarak kontrol ediyorsak bir "analog deger" vardır. Örneğin ısıtıcımıza "0" gönderirsek hiç çalışmıyor, "100" gönderirsek son gücüyle çalışıyor olsun. Kimi zaman bu değerler örneğin "0" ile "1" arasında ya da "0" ile "1023" arasında olabilir.

Eğer PID'ye bir göz attıysanız, P,I ve D için "katsayılar" verilmesi gerektiğini ve bu katsayıları belirlemenin çok zor olduğunu öğrenmişsinizdir. Şimdi "hata" yı bulduğumuza göre, P değerini de vererek PID'mizin ilk kısmını yapalım.

Evet, şimdi iki değer çıktı karşımıza: alt ve üst sınır. Bir de ne vardır? istenen sıcaklıkla ölçülen sıcaklık arasındaki fark, yani "hata". Üç tane değerimiz oldu. Alt ve üst sınırı neden kullanacağız? Eğer hesap sonucu alt sınırdan az ya da üst sınırdan çok çıkarsa sonucu bunlara uyduracağız:

Basic kullanıyorsak:
 

hata=istenen_sicaklık-olculen_sıcaklik
deger=hata*P_katsayisi
IF deger>UstSinir THEN deger= UstSinir END IF
IF deger<AltSinir THEN deger= AltSinir END IF

Ya da C kullanıyorsak:
 

hata=istenen_sicaklık-olculen_sıcaklik;
deger=hata*P_katsayisi;
IF (deger>UstSinir) deger= UstSinir;
IF (deger<AltSinir) deger=AltSinir;

Sonra bu değeri ısıtıcımıza gönderiyoruz. Hepsi bu.

Şimdi bu anlattıklarımızı program haline getirelim. Ama hem BASIC hem C yazmak istemiyorum, ben buraya C olarak yazacağım.


 

istenen_sicaklik=25; //Odamızı 25 derece sıcaklıkta sabit tutmak istiyoruz.
UstSinir=100; //Isıtıcımızı tam güç çalıştırmak için vermemiz gereken değer
AltSinir=0; //Isıtıcımıza verebileceğimiz en düşük değer
P_katsayisi=1;
while (1) //PID döngüsü, Bu kısımları programınızda başka kodlar da varsa, ana döngüye yerleştireceksiniz.
{
  olculen_sicaklik=TermometreOku(); //Termometre okumak konumuz dışında, onu açıklamayacağız
  hata=istenen_sicaklık-olculen_sıcaklik;
  deger=hata*P_katsayisi;
  IF (deger>UstSinir) deger= UstSinir;
  IF (deger<AltSinir) deger=AltSinir;
  IsiticiCalistir(deger); //Isıtıcıyı PWM ya da analog ile çalıştırmak da konumuz dışında
}

Böylece bir P kontrolü yapmış olduk. Bu kadar basit :)
 

(Devam Edecek)

İletiyi paylaş


İletiye bağlantı
Sitelerde Paylaş
şenol eker    0

P kontrolü yaptığımızda, sorun çözülmüş gibi görünüyor ama ilk çalışma anında ya da sistemde "olağandışı" bir şey olduğunda bir "eksiklik" olduığıunu fark ederiz.

Örneğin 40 derecede sabit sıcaklıkta tuttuğumuz bir ortama hatırı sayılı miktarda buz koyarsak,

hata=istenen_sicaklık-olculen_sıcaklik

değeri çok büyük olacak, bu yüzden ısıtıcımız muhtemelen var gücüyle, %100 kapasiteyle çalışmaya başlayacaktır. Bu belki ortam sıcaklığını hızlıca 40 dereceye çıkartmak için iyi gibi görünebilir. Ancak 40 dereceye yaklaştığında 40 dereceyi çok fazla aşabilecektir.

Bu, aslında Kp katsayısının ne kadar büyük olduğuna bağlıdır. Örneğin Kp katsayısı çok küçük ise, ortam 40 dereceyi çok aşmayacak, Kp daha küçükse hiç aşmayacak, ama sistemin 40 dereceye gelmesi çok uzun sürecektir.

Kp katsayısı büyük olursa, bu sefer ortam sıcaklığı hızla yükselecek, ama 40 dereceyi ısklayacak, bu değeri aşacaktır.

Yani Kp katsayısını büyüttükçe hedefe daha çabuk yaklaşırken küçülttükçe daha hassas yaklaşıyor. Yani iki ucu pis değnek...

Peki, hem hızlı hem de hassas olarak yaklaşmasının bir yolu yok mu?
Var tabii. Bunun için, PID'in diğer bileşenlerini devreye almamız gerek.

Peki, sadece P denetleyici yaparsak, hedefe yavaş ulaşmak / hedefe ulaşırken sapmalar göstermek dışında başka olumsuzluklarla karşılaşır mıyız?
Şimdi gerçek verilerle bir "fırın", P denetleyici ile nasıl çalışıyor bakalım.
Hedef sıcaklık olarak 70 derece verdik. Başlangıçta fırının içi ve dışı 30 derece idi. Sistemi başlattığımızda önce sıcaklık hızla 95 dereyece kadar çıktı, sonra 50 dereceye düştü, derken 68 derece civarında karar kıldı:
PID1.thumb.png.bcda111ea00f8c976857909888a13381.png

Ama biz, 70 dereceye ayarlamıştık. Neden 68'de kaldı?
İşte, buna "offset" veya "drift" deniyor. Eğer 68 dereceye ulaşma hızı sizin için yeterli ise ve P denetleyici kullanmak isterseniz, hedefi 70 yerine 72 yaptığınızda sorun çözülecektir.

 

İletiyi paylaş


İletiye bağlantı
Sitelerde Paylaş
şenol eker    0

Biz, 70 dereceye ayarlamıştık. Neden 68'de kaldı?

Çünkü "hata" diye bir şey hesapladık ve ısıtıcıyı, bu "hata"ya göre çalıştırdık. Eğer ortamımız tam 70 derece olsaydı, hata sıfır olacak ve ısıtıcı hiç çalışmayacaktı. Halbuki ortamın bir "ısı kaybı" var. Isıtıcı, "ısı kaybı kadar" çalışmak zorunda ki sıcaklık sabit kalsın. Bu yüzden P kontolöründe arada bir fark = drift = offset olması kaçınılmaz. Bunu set değerimizi biraz yüksek vererek dengeleyebiliriz ama eğer PID'in I bileşenini de kullanırsak, zaten hem baştaki titreşim daha azalacak, hem de bu offset sorunu gidecek.

I bileşeni için INTEGRAL yani toplama işlemi yapacağımızdan, bir "toplam" değerine ihtiyacımız var. Her PID döngüsünde buna hatayı ekleyeceğiz. Buna "Toplam" diyelim. Her döngüde hata miktarını bu "toplam" değerine ekleyeceğiz. Ayrıca PID sonucuna da bu toplamın Ki katsayısı ile çarpımını ekleyeceğiz. Ki nedir biliyoruz değil mi? Hani Kp,Ki,Kd katsayılarındaki integral bileşeninin katsayısı.
O halde programımızı I (integral) bileşenini de içerecek şekile güncelleyelim:
 

istenen_sicaklik=25; //Odamızı 25 derece sıcaklıkta sabit tutmak istiyoruz.
UstSinir=100; //Isıtıcımızı tam güç çalıştırmak için vermemiz gereken değer
AltSinir=0; //Isıtıcımıza verebileceğimiz en düşük değer
Toplam=0;
P_katsayisi=1;
I_katsayisi=1;
while (1) //PID döngüsü, Bu kısımları programınızda başka kodlar da varsa, ana döngüye yerleştireceksiniz.
{
  olculen_sicaklik=TermometreOku(); //Termometre okumak konumuz dışında, onu açıklamayacağız
  hata=istenen_sicaklık-olculen_sıcaklik;
  Integral=Toplam*I_katsayisi;

  IF (Integral>UstSinir) Integral= UstSinir;
  IF (Integral<AltSinir) Integral=AltSinir;

  deger=hata*P_katsayisi+Integral;
  IF (deger>UstSinir) deger= UstSinir;
  IF (deger<AltSinir) deger=AltSinir;
  Toplam+=hata;
  IsiticiCalistir(deger); //Isıtıcıyı PWM ya da analog ile çalıştırmak da konumuz dışında
}

Burada Integral değeri hesaplandıktan sonra, integral değeri için özel olarak üst ve alt sınır kontrolü yapıldığına dikkatinizi çekerim. Bunun sebebi, aşırı yüksek (veya aşırı düşük) çıkacak bir Integral değerinin, diğer bileşenleri işlevsizleştirmesini engellemektir. Örneğin P bileşeni -20, Integral bileşeni 30000 çıktı ise, bu sınır kontolü olmasa sonuç 100 çıkacakken, integral sınır kontrolü yapıldığında sonuç 80 olarak çıkacaktır.
 

Yukarıdaki örneğimize sıcaklık/zaman grafiğimiz nasıl oluyor ona bir bakalım:
PI.thumb.png.98194cbc84ebcd2872ae690fa5d08814.png

İletiyi paylaş


İletiye bağlantı
Sitelerde Paylaş
şenol eker    0

Sırası gelmişken, buradaki eğriler, gerçek bir sistemden alınan veriler değildir. Bir fikir vermesi için excel'de çizilip konmuştur. Daha güzel grafikler (tabşii ki kendi hazırladığınız) gönderirseniz değiştiririz.
Şimdi sıra, PID'in son bileşeni olan D (Derivative) bileşenine geldi. Türev de bildiğiniz gibi "fark" demektir ve hesaplanan sonuca öneki hata ile şimdiki hata arasındaki farkı ekleyeceğiz. Tabii ki Kd katsayısı ile çarparak.

Bu durumda bize bir de "önceki hata" değişkeni lazım. Her seferinde derivative=(hata-oncekihata)*Kd hesaplayıp ardından oncekihata=hata diyerek bir sonraki döngü için "önceki hata" değerini saklayacağız.

Ancak burada dikkat etmemiz gereken bir olay var. Program ilk olarak çalıştığında, oncekihata değeri olmayacağından aşırı yüksek bir derrivative değeri çıkacaktır. Bundan kaçınmak için ilk döngüde derrivative değerini hesaplamayacağız. Bu yüzden "ilkSefer" diye de bir değişkene ihtiyacımız olacak.

ilkSefer=1

while (1)
{
......
    derivative=(hata-oncekihata)*kd;
    if (ilkSefer)
    {
      derivative=0;
      ilkSefer=0;
     }
    oncekihata=hata;
......
}

Şimdi bu kısmı programımızın içine ilave edelim:
 

istenen_sicaklik=25; //Odamızı 25 derece sıcaklıkta sabit tutmak istiyoruz.
UstSinir=100; //Isıtıcımızı tam güç çalıştırmak için vermemiz gereken değer
AltSinir=0; //Isıtıcımıza verebileceğimiz en düşük değer
Toplam=0;
ilkSefer=1;
P_katsayisi=1;
I_katsayisi=1;
D_katsayisi=1;
while (1) //PID döngüsü, Bu kısımları programınızda başka kodlar da varsa, ana döngüye yerleştireceksiniz.
{
  olculen_sicaklik=TermometreOku(); //Termometre okumak konumuz dışında, onu açıklamayacağız
  hata=istenen_sicaklık-olculen_sıcaklik;
  Integral=Toplam*I_katsayisi;
  Turev=(hata-OncekiHata)*D_Katsayisi;
  if (ilkSefer)
  {
    ilksefer=0;
    Turev=0;
  }
  OncekiHata=hata;
  IF (Integral>UstSinir) Integral= UstSinir;
  IF (Integral<AltSinir) Integral=AltSinir;

  deger=hata*P_katsayisi+Integral+Turev;
  IF (deger>UstSinir) deger= UstSinir;
  IF (deger<AltSinir) deger=AltSinir;
  Toplam+=hata;
  IsiticiCalistir(deger); //Isıtıcıyı PWM ya da analog ile çalıştırmak da konumuz dışında
}

Bunu da eklediğimizde sistem çok kısa bir sürede denge durumuna girecektir:
PID.thumb.png.9e6e4bc5c7c53793f6ce3dab54e14b3e.png


Yukarıdaki örnek, test edilmiş C programları değildir. Büyük küçük harf hataları / değişken tanımlama eksiklikleri olabilir. Siz kendi kodunuzu yazarken bunlara dikkat edin.
Ayrıca örnekte Kp,Ki ve Kd katsayıları olarak hep 1 verdik. Gerçekte bu böyle gerçekleşmez. Bir PID sistemin nasıl ayarlanacağı konusu, PID'in kendisi gibi basit bir konu değildir. Hatta "şöyle ayarlanır" diye bir yöntem bile yoktur. Çeşitli yaklaşımlar vardır; Ziegler–Nichols metodu ya da Cohen-Coon metodu gibi.

İletiyi paylaş


İletiye bağlantı
Sitelerde Paylaş
Misafir
Bu konu kapalıdır ama konuya cevap yazmaya yetkiniz var görünüyor.

×
×
  • Yeni Oluştur...

Önemli Bilgilendirme

Facebook / Twitter / Google hesabınızla kolayca kaydolup cevap verebilir, soru sorabilir, istekte bulunabilirsiniz.
Devam etmeniz, forum kurallarını kabul ettiğiniz anlamına gelir.            Forum Kuralları