PIC Vietnam

PIC Vietnam (http://www.picvietnam.com/forum/index.php)
-   Cơ bản về vi điều khiển và PIC (http://www.picvietnam.com/forum/forumdisplay.php?f=8)
-   -   ổn định tốc độ động cơ (http://www.picvietnam.com/forum/showthread.php?t=3559)

0509592 19-02-2009 03:04 PM

ổn định tốc độ động cơ
 
HI!
chào các bác!
em muốn ổn định tốc độ động cơ dùng bộ PID!
và đồng tốc 2 động cơ!
nhưng không hiểu sao em lam hoài mà không được!
lúc đầu thì động cơ có đáp ứng!
nhưng sau khi hiệu chỉnh thông số PID nhiều lần thì không chạy nữa!
các bác xem giúp em với!
thanks!
Trích:

//#include "D:\hanh trinh robocon\lap trinh robot\dong_co_pic_pic\887\pic_PID.h"
#include <16f887.h>
#include <def_877a.h>
#FUSES HS, NOPUT, NOPROTECT, NODEBUG, NOBROWNOUT, NOLVP, NOCPD, NOWRT,NOWDT
#use delay (clock = 20000000)
#include <math.h>
#include <lcd_lib_4bit.c>

#byte PR2 = 0x92

//////////////////////////////////////////////////////
////cac ham nguyen mau
void init_timer();
void init_PWM(unsigned int16 frequency);
void hien_thi(int16 v);
void call_pid1(void);
void call_pid2(void);


int8 a,b,c,d;
unsigned char i = 1 ;

///////////////////////////////////////////////////////
//////////////gia tri dat
int16 v_set1 =3;
int16 u_set1=3;


/////////////////////////////////////////////////////////
/////////gia tri thuc phan hoi duoc
int16 v_cur,u_cur;

//////gia tri tinh toan
signed int16 e_sum,u_sum,e_del,u_del,e1,u1,e2,u2;

//////////////////// cac thong so pid
float kp =150,kp2 =170;

//float ki =0.01,ki2 =0.008;
float ki =0.002,ki2 =0.003;

float kd = 0,kd2 = 0;


////////////////////////////////////////////////////////////
float pw_duty1,pw_duty2;
int16 temp_timer1,cnt=0,pwm1=200,pwm2=200;

#define START_TIMER0 5 //tri khoi tao ban dau cua timer0 5
#define START_TIMER1 5535 //tri khoi tao ban dau cua timer1


#int_EXT
void EXT_isr(void)
{
cnt++;
}

#INT_TIMER0
void TIMER0_int()
{

i++;
tmr0if=0;
set_timer0(START_TIMER0);
if(i==3 ){
temp_timer1 = get_timer1();
set_timer1(START_TIMER1);
i=0;

v_cur = 2*(temp_timer1 - START_TIMER1);
u_cur=cnt;

cnt=0;
}


}

void init_timer()
{

setup_timer_0(RTCC_INTERNAL | RTCC_DIV_16); // moi lan tran timer0 tuong ung 250*16*1/5 us = 0.8ms,

set_timer0(START_TIMER0);

setup_timer_1(T1_EXTERNAL | T1_DIV_BY_2);

set_timer1(START_TIMER1);

ext_int_edge( H_TO_L );

enable_interrupts(GLOBAL);
enable_interrupts(INT_EXT);
enable_interrupts(INT_TIMER0);

}

void hien_thi(int16 v)
{
a=v/1000;
b=(v-1000*a)/100;
c=(int)((v-1000*a-100*b))/10;
d=v%10;
lcd_putchar(a+48);
lcd_putchar(b+48);
lcd_putchar(c+48);
lcd_putchar(d+48);
lcd_putchar(" ");

}

void init_PWM(unsigned int16 frequency)
{
setup_ccp1(CCP_PWM); // initiate PWM
setup_ccp2(CCP_PWM); // initiate PWM
PR2 = 20000000/4/frequency - 1; // set PWM period

setup_timer_2(T2_DIV_BY_4,140,1);
//(1/20000000)*4*4*(140+1)=112.8 us( will over flow every 112.8us, will intrup every 112.8us or 8.86khz;

}

float temp_kp,temp_kp2;
float temp_ki,temp_ki2;
float temp_kd,temp_kd2;

void call_pid1()
{
e2 = v_set1 - v_cur;
e_sum += e2;
e_del = e2 - e1;
e1 = e2;

temp_kp = kp*e2;
temp_ki = ki*e_sum;
temp_kd = kd*e_del;
pw_duty1 =pw_duty1+temp_kp+temp_ki+temp_kd;

/*
if (pw_duty1 <1000)pw_duty1 += temp_ki;
if (pw_duty1 <1000)pw_duty1 += temp_kd;
if (pw_duty1 <256)pw_duty1 = 256;
// vi khi pw_duty <256 thi PWM chi dieu rong xung 8 bit

*/

if (pw_duty1 >1000)pw_duty1 = 1000; // bao hoa

pwm1=(int16)(pw_duty1);
}

void call_pid2()
{
u2 = u_set1 - u_cur;
u_sum += u2;
u_del = u2 - u1;
u1 = u2;

temp_kp2 = kp2*u2;
temp_ki2 = ki2*u_sum;
temp_kd2 = kd2*u_del;
pw_duty2 =pw_duty2+temp_kp2+temp_ki2+temp_kd2;
/*
if (pw_duty2 <1000)pw_duty2 += temp_ki2;
if (pw_duty2 <1000)pw_duty2 += temp_kd2;
if (pw_duty2 <256)pw_duty2 = 256;
// vi khi pw_duty <256 thi PWM chi dieu rong xung 8 bit
*/

if (pw_duty2 >1000)pw_duty2 = 1000; // bao hoa

pwm2=(int16)(pw_duty2);
}

void main()
{

trisd=0x00;
rd0=0;
rd1=0;

// lcd_init();
init_timer();
init_PWM(35714);

while(true)
{


// lcd_putcmd(0x80);
// hien_thi(v_cur);
// lcd_putcmd(0xC0);
// hien_thi(u_cur);

call_pid1();
call_pid2();
set_pwm1_duty(pwm1);
set_pwm2_duty(pwm2);

}//while
}//main

0509592 21-02-2009 08:39 PM

way!
sao không thấy bác nào tham gia thế!
?????????????????????????????????
------------------------
"thang ngay dong duoi cuoc doi
nho nguoi co huu hen ngay tai ngo"

0509592 01-03-2009 10:19 PM

buồn wua!
sao không thấy bác nào quan tâm vậy!??????????????

sandro_bk 02-03-2009 12:19 AM

chào bạn,
Trước tiên mình nghĩ bạn nên test từng bước một,
1/điều khiển 1 động cơ thôi
2/điều khiển vòng hở xem đáp ứng của động thế nào?
3/bỏ qua mấy cái râu ria hiển thị đi,chạy được cái đã.
Theo mình thấy bạn điều khiển 2 động cơ nhưng phần hồi tiếp về dùng 2 loại khác nhau,1 cái là timer,1 cái là ngắt ngoài,thường người ta ko dùng ngắt ngoài để hồi tiếp tốc độ vì dễ nhiều và nếu ở tốc độ động cơ lớn + resolution của encoder cao thì chương trình sẽ vào ngắt liên tục,ko làm được gì nữa cả,bạn nên dùng chung 1 cái timer xuất pwm và tạo thời gian lấy mẩu encoder,còn 2 cái timer kia để hồi tiếp tốc độ.
Mình nghĩ bạn nên dùng dòng pic18fxx31,chuyên điều khiển động cơ.Khi đó hồi tiếp encoder và PWM sẽ tiện hơn.
Còn cái thời gian để lấy mẫu xung encoder tại sao bạn chọn là 3x0.8ms = 2.4ms?

mtuankct 03-03-2009 07:55 PM

mình nghĩ bạn nên giải thích để mọi người hiểu thuật toán đk trước chứ bạn viết code thế lại không đúng chuẩn khó đọc lắm (bạn nên dùng tab để trình bày lại code đọc sẽ dễ hiểu hơn) cũng nên post cả sơ đồ mạch nguyên lý lên ;)
mình cũng đã đọc qua chương trình của bạn mình thấy nhiều chỗ không ổn lắm như
1. Trong hàm main bạn liên tục gọi hàm PID và set_duty như vậy thì thời gian trích mãu Tsp của bạn bằng bao nhiêu? bạn nên đọc lại phần lý thuyết đk số của bộ đk PID
2. Trong hàm tính PID bạn chưa chống tràn cho thành phần tích phân
3. Mình cũng không hiểu phần lấy mẫu encoder của bạn lắm theo mình với PIC16 hình như không hỗ trợ QEI (nếu mình không nhầm) thì bạn nên dùng chế độ InputCapture của nó để đo độ rộng xung encoder

0509592 04-03-2009 02:06 PM

vâng!
cảm ơn các bác!
đúng là em chưa hiểi nhiều về bô PID!
hôm trươc em dùng matlap mô phỏng để tìm các thông số PID nhưng không tìm đươc!
có lẽ em phải xem lai kiến thức về bộ PID đã!
rồi lên hỏi các bác sau!
thanks!


Múi giờ GMT. Hiện tại là 07:55 PM.

Tên diễn đàn: vBulletin Version 3.8.11
Được sáng lập bởi Đoàn Hiệp.
Copyright © PIC Vietnam