PID kontrol sorunu

Başlatan berkay_91, 09 Ekim 2014, 00:37:39

berkay_91

mrb, alttaki kodları PID ile dc motorda devir sayısını ayarlamak için düzenledim ancak LCD de gördüğüm değer sadece 62-63 arasında değişiyor, set_rpm değerine ne yazdıysam lcddeki rakam hep aynı bir yerde hata var ama çözemedim yardımcı olurmusunuz?(Atmega32 kullandım)

#define F_CPU 1000000
#include <avr/io.h>
#include <avr/pgmspace.h>
#include <stdio.h>
#include <util/delay.h>
#include <avr/interrupt.h>
#include "lcd.h"
#define P_GAIN 0.8
#define I_GAIN 0.005
#define D_GAIN 0.01
volatile int set_rpm = 0,previous_error = 0;
volatile int error, feedback_rpm, output=0;
volatile int D_error = 0, I_error = 0;
volatile int  c = 0;
volatile int pulses;
FILE lcd_str = FDEV_SETUP_STREAM(lcd_putc, NULL, _FDEV_SETUP_WRITE);
void init_interrupts(){
MCUCR|=(1<<ISC00)|(1<<ISC01);
GICR |=(1<<INT0);
sei();
}
//PWM Frequency: (10^6)/255=3.9 kHz
// (1024/10^6)*255*4=1;
init_timer0_and_pwm(){
TCCR0=(1<<WGM00)|(1<<WGM01)|(1<<CS00)|(1<<COM01); // pwm init
TCCR0|=(1<<CS00)|(1<<CS02); // prescalar is 1024
TCNT0=0;
TIMSK=(1<<TOIE0);
}
ISR(TIMER0_OVF_vect){
TCNT0=0;
c++;
if(c==2){
    PORTD^=(1<<7);
feedback_rpm = pulses*5;
lcd_gotoxy(0,1);
printf("%d ",pulses);
c=0;
    pulses = 0;
}
}
ISR (INT0_vect){
pulses++;
}
int main(){
DDRC=0XFF; // lcd için
DDRB|=(1<<3); // pwm OC0 bacağı
DDRD|=(1<<7); // LED İÇİN
MCUCSR|=(1<<JTD); // JTAG PİNLLERİNİ KAPATMA
MCUCSR|=(1<<JTD); // JTAG PİNLLERİNİ KAPATMA
init_timer0_and_pwm();
init_interrupts();
lcd_init(LCD_DISP_ON);
stdout = stdin = &lcd_str;
lcd_clrscr();
lcd_gotoxy(4,0);
lcd_puts("PID TEST");
    set_rpm = 50;
previous_error = set_rpm - feedback_rpm;
while(1){
error = set_rpm - feedback_rpm;
I_error += (error);
D_error = (error - previous_error);
output = (P_GAIN * error) + (I_GAIN * I_error) + (D_GAIN * D_error);
previous_error = error;
if((OCR0 + output)>=255){
OCR0= 255;
    }
    else if((OCR0 + output)<=0){
OCR0= 0;
    }
    else{
OCR0+= output;
}
}
return 0;
}

Saruman

Kimse de dememiş ki aga bu nedir..

X-Fi

PID de hazır kod üzerinden yorum yapmak zor zamanlamaları da bilmek lazım.

output = (P_GAIN * error) + (I_GAIN * I_error) + (D_GAIN * D_error);


öncelikle yukarıdaki satırdan integral ve türevi çıkart. sadece P ile dene sonra integrali ekle çalışıyorsa türevide ekler arızayı bulursun.
http://www.coskunergan.dev/    (Yürümekle varılmaz, lakin varanlar yürüyenlerdir.)

trinity

bu formül wikipedia'da bile var, PID demek bu formül demek değildir, PID demek katsayıları sisteme göre ayarlamak demektir.

ylmz

Regülatör Dns Trafo | Regülatör | Redresör | Ups

ceyhanan

#define P_GAIN 0.8f
#define I_GAIN 0.005f
#define D_GAIN 0.01f


bu şekilde değiştirerek dene bir de

berkay_91

#6
bu sorunu hallettim sorun katsayılardan değilmiş timer ı kurma biçimimden kaynaklanıyormuş, hem timer kesmesi hemde PWM için ayrı bir timer aktif olunca haliyle işlemci sapıtıyodu timer için delay_ms() frekans okuma içinde external clock source pinini kullandım ve gayet iyi çalıştı