mrbean8910 |
03-01-2015 03:49 PM |
[Help] PID và PWM
Các anh trong diễn đàn chỉ giúp e bài này cái.
E nhờ thằng bạn viết dùm nhưng khi nap thực tế vào mạch thì ngõ ra PWM không có tín hiệu gì (dùng VOM đo PWM thì chẳng có điện áp), hiện tại không liên lạc đc với nó nên đành post lên đây mong mọi người chỉ giúp dùm e cai. Em không hiểu sao để xuất được PWM ra để điều khiển nhiệt độ (dùng đèn 12V qua FET để kich dẫn), hay trong bài code của e có gì sai.
Code:
#include "30F2010.h"
#device adc=10
#FUSES NOWDT //No Watch Dog Timer
#FUSES CKSFSM //Clock Switching is enabled, fail Safe clock monitor is enabled
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOMCLR //Master Clear pin used for I/O
#device ICSP=1
#use delay(crystal=16000000)
#use rs232(xmit=PIN_F3, rcv=PIN_F2, baud=9600, stream=RS232_PORT1) // duong RS232 RX:F2, TX:F3
void tinhtoan_FUZZY(float nhietdo); // tinh toan mo
float tinhtoan_PID(float nhietdo, float KP,float KI,float KD); // tinh toan PID
float PID_pwm_tinhtoan=0;
float e1,e2,e_sum,e_del;
float KP_out=0,KI_out=0,KD_out=0;
/////////////// cac gia tri sau deu tu thuc nghiem //////////////////////////////////////////////////
float KP_in[3]={12.5,14.5,17.6};// min max kp
float KI_in[3]={1.07,2.46,4.23};// min max ki
float KD_in[3]={0.2,1,2.31};// min max kd
////////////////////////////////////////////////////////////////////////////////////////////////////////////
void main()
{
char i=0;
float temp=0;
float nhietdothuc=0;
float dt_nhietdo=0;
char nhietdo=0;
unsigned int16 PID_pwm=0;
set_tris_b(0b10000001);
set_tris_d(0b10000000);
setup_adc_ports(sAN0, VSS_VDD); /// chan B0 doc gia tri dien ap tu LM35 vao
setup_adc(ADC_CLOCK_DIV_4 | ADC_TAD_MUL_0);
setup_timer2(TMR_INTERNAL | TMR_DIV_BY_1, 3999);
setup_compare(1, COMPARE_PWM | COMPARE_TIMER2); // su dung kenh pwm1 dieu khen IRF cong xuat ( bong den)
set_pwm_duty(1, 0); // xuat xung pwm ra kenh pwm1
set_ADC_channel(0);
delay_ms(1);
while(true)
{
for(i=0;i<200;i++)
{
temp +=read_adc();
delay_us(500);
}
dt_nhietdo=read_adc(); // vi phan nhiet do
dt_nhietdo=dt_nhietdo*0.4883;
temp=temp/200; // nhiet do trung binh cua 200 lan lay mau
nhietdothuc = temp*0.4883; // doi sang do C
nhietdo=(char)nhietdothuc;
putc(nhietdo); // goi gia tri nhiet do len pc qua RS232
tinhtoan_FUZZY(dt_nhietdo); // mo de lay ra gia tri kpout,kiout,kdout cho ham tinh toan pid
PID_pwm_tinhtoan=tinhtoan_PID(nhietdothuc, KP_out,KI_out,KD_out); /// nhap gia tri Kp Ki ,Kd tu ham tinh FUZZY
PID_pwm=(unsigned int16)PID_pwm_tinhtoan;
set_pwm_duty(1,PID_pwm);;
}
}
//////////////////////////////////////////////////////////////////////////////////
void tinhtoan_FUZZY(float nhietdo)
{
if(nhietdo<30){KP_out=KP_in[0];KI_out=KI_in[0];;KD_out=KD_in[0];}
else if(nhietdo<35){KP_out=KP_in[1];KI_out=KI_in[0];;KD_out=KD_in[0];}
else if(nhietdo<40){KP_out=KP_in[2];KI_out=KI_in[0];;KD_out=KD_in[0];}
else if(nhietdo<45){KP_out=KP_in[2];KI_out=KI_in[1];;KD_out=KD_in[1];}
else if(nhietdo<50){KP_out=KP_in[2];KI_out=KI_in[2];;KD_out=KD_in[2];}
else {KP_out=0,KI_out=0,KD_out=0;}
}
/////////////////////////////////////////////////////////////////////////////////
float tinhtoan_PID(float nhietdo, float KP,float KI,float KD)
{
float pwm;
e2 = 50 - nhietdo;
e_sum = e1+ e2;
e_del = e2 - e1;
e1 = e2;
pwm += KP*e2 + KI*e_sum + KD*e_del; // phep cong don
if (pwm < 799) pwm = 799;
if (pwm> 3999) pwm = 3999;
return pwm;
}
/////////////////////////////////////////////////////////////////////////////////
Có gì sai, không đúng mong anh em chỉ dùm e
Thanks
|