0509592
19-02-2009, 03:04 PM
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!
//#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
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!
//#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