Picproje Elektronik Sitesi

ENDÜSTRiYEL OTOMASYON => Proses Kontrol Sistemleri => Konuyu başlatan: berkay_91 - 09 Ekim 2014, 00:37:39

Başlık: PID kontrol sorunu
Gönderen: berkay_91 - 09 Ekim 2014, 00:37:39
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;
}



Başlık: Ynt: PID kontrol sorunu
Gönderen: Saruman - 10 Ekim 2014, 03:17:39
Kimse de dememiş ki aga bu nedir..
Başlık: Ynt: PID kontrol sorunu
Gönderen: X-Fi - 10 Ekim 2014, 07:52:33
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.
Başlık: Ynt: PID kontrol sorunu
Gönderen: trinity - 10 Ekim 2014, 08:44:43
bu formül wikipedia'da bile var, PID demek bu formül demek değildir, PID demek katsayıları sisteme göre ayarlamak demektir.
Başlık: Ynt: PID kontrol sorunu
Gönderen: ylmz - 14 Haziran 2015, 21:16:01
Alıntı yapılan: Saruman - 10 Ekim 2014, 03:17:39
Kimse de dememiş ki aga bu nedir..
hahah koptum gulmekten :D
Başlık: Ynt: PID kontrol sorunu
Gönderen: ceyhanan - 14 Haziran 2015, 23:20:13
#define P_GAIN 0.8f
#define I_GAIN 0.005f
#define D_GAIN 0.01f


bu şekilde değiştirerek dene bir de
Başlık: Ynt: PID kontrol sorunu
Gönderen: berkay_91 - 15 Haziran 2015, 00:53:35
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ı