Merhaba arkadaşlar,
wikipedia da pid ile ilgili standart temel kod var.
previous_error = 0
integral = 0
start:
error = setpoint - measured_value
integral = integral + error*dt
derivative = (error - previous_error)/dt
output = Kp*error + Ki*integral + Kd*derivative
previous_error = error
wait(dt)
goto start
buradaki dt örnekleme zamanı şeklinde açıklanmış..sorum şu:
dt program içerinde bir değişken olarak benim tanımlayacağım bir değer mi olacak , yoksa timer kullanarak belirleyeceğim bir süre mi ?
dt birim zaman sen ne kadar sürede bir örnek alıyorsan o kadar.Bunu ister delay verip delay süresini al program içinde olsun ister timerla belli zaman aralığında interrupt oluştur onu ala ama mantıklısı timer ile interrupt oluşturmak.
cevap için teşekkürler..
timer0 ı kullanarak kesme oluşturabilirim.
soru1 : Ancak ne kadarlık bir süre belirlemeliyim?
ve dt yerine de o süreyi mi girmeliyim?
Kp ki ve kd degerlerini nasil olsa deneme yanilma ile bulacagina gore, dt'nin pek onemi yok.
cur_pos=adc_oku(); //mevcut durumu oku
error =cur_pos-ref_pos;
derivative = (error - previous_error);
integral = integral + error;
previous_error = error;
output=error*Kp+derivative*Kd+integral*Ki;
şeklinde yazsak olur mu??? dt yi kullanmadan...
Olur. Fakat buradaki
Kd, Kd'
Ki, Ki' seklinde farkli degiskene donusmus olur.
Atiyorum eskiden Ki=100 iken artik 0.00001 gibi bir deger alacak.
o zaman bu kp,kd ya da ki float tanımlanmalı değil mi?
ama ben outputu integer olarak kullanıyorum..Acaba hesaplamayı float yaptıktan sonra output değişkeni integer tanımlandıysa derleyici sonucu otomatik çevirir mi??
void pid()
{
error =ref_pos-cur_pos;
P = error*Kp;
I = (I + error)*Ki;
D = (error - previous_error)*Kd;
output=P+I+D;
previous_error = error;
}
void hiz_ayarla()
{
if(output>motor_hiz) output=motor_hiz;
if(output<-motor_hiz) output=-motor_hiz;
set_pwm1_duty(motor_hiz+output);//sol motor
set_pwm2_duty(motor_hiz-output);// sağ motor
}
kodun doğru olduğunu düşünüyorum ama maalesef çalıştıramadım...Bir de siz inceler misiniz?
Bütün işlemleri float olarak yaptıktan sonra sonucu değerlendirirken integer olarak tip dönüşümü yapabilirsin.
output un da float olduğunu var sayarsak bunu motor_hiz değişkenine integer olarak atmak için;
motor_hiz = (uint16_t)(output);
hız alt ve üst limitlerin varsa bunu da şu şekilde denetleyebilirsin
if(motor_hiz<MIN_SPEED)
motor_hiz=MIN_SPEED
else if(motor_hiz>MAX_SPEED)
motor_hiz=MAX_SPEED
mesaj birleştirme:: 23 Mart 2014, 14:26:09
kp, ki ve kd değerlerini güzel seçebilirsen output verisini doğrudan pwm verisi olarak kullanabilirsin. Gerekirse output a bir ofset değeri ekleyerek yada bir sabit katsayı ile çarparak ta kullanman mümkün.
benimde bir sorum olacak konu açmaya gerek yok , çizgi izleyen de engel için dış kesme yaptğımızda sadece b0 pinindemi bu işi gerçekleştirebiliriz?yoksa picin herhangi bir portunda herhangi pininde bu işlemi gerçekleştirebilirmiyiz?
PIC16 serisi için konuşuyorsanız harici kesme pinleri B0 ve B4~B7 pinleridir.
Benim merak ettiğim konu pid uygulamalarında kp, ki ve kd değerlerini nasıl pratik ve kesin bir şekilde tespit edebiliriz?
Değer vererek deneme-yanılma sürecini kolaylaştırabileceğimiz bir yol var mı?
Matlab dan bu konuda nasıl faydalanabiliriz?
PID katsayılarının bulunma yöntemleri vardır.İnternet de PID taratması yaptığında birçok kaynak bulunmaktadır.Aşağıdaki linkde yükseklisans tezinde kontrolör arayüz tasarımı altında matlab guide de bir arayüz tasarlanıp PID katsayıları bulunmuşve daha evelsinde nedir nasıl die açıklamalarda bulunulmuş.Küçük bir araştırmayla konuyu daha iyi anlayabilirsin. İyi çalışmalar..
http://personel.trakya.edu.tr/aydingullu/#.VMznQdKsUfY (http://personel.trakya.edu.tr/aydingullu/#.VMznQdKsUfY)