Tạo thêm 1 nút nhấn REVERSE để đảo chiều quay của động cơ nhưng chỉ nhấn REVERSE được 1 lần.
II)Các đoạn chương trình mẫu của giải thuật PID thích nghi:
//Đoạn đọc tín hiệu xung:
double CBAI4Dlg::DataPulse() { PT_DioReadPortByte ptDioReadPortByte0,ptDioReadPortByte1; USHORT DataLo,DataHi; doublePulse; doubleDelta_Pulse; //static double PrevPulse;
// read low byte
ptDioReadPortByte0.port = 0;
ptDioReadPortByte0.value = (USHORT far *)&DataLo; // read high byte
ptDioReadPortByte1.port = 1;
ptDioReadPortByte1.value = (USHORT far *)&DataHi;
DRV_DioReadPortByte(DriverHandle,(LPT_DioReadPortByte)&ptDioReadPort Byte0);
DRV_DioReadPortByte(DriverHandle,(LPT_DioReadPortByte)&ptDioReadPort Byte1);
Pulse = DataHi*256 + DataLo; Delta_Pulse = Pulse - PrevPulse; PrevPulse = Pulse;
// processing counter overflow
if(Delta_Pulse>+32768) Delta_Pulse = Delta_Pulse - 65536; if(Delta_Pulse<-32768) Delta_Pulse = Delta_Pulse + 65536; return (Delta_Pulse); } //Đoạn xử lý tín hiệu: m_nTimer = SetTimer(1,T0,0); if(!flag) gdwStartTime = GetTickCount(); flag =1;
if(SetSpeed > 0)
USetSpeed = (2952.0 - SetSpeed)/1135.4; //QUY DOI TOC DO RA DIEN AP else
USetSpeed = (2720.0 - SetSpeed)/1133.8; a[0][0] = a0;
a[1][0] = a1; a[2][0] = a2;
//Đoạn tính tín hiệu điều khiển:
double CBAI4Dlg::PID(double currentspeed) {
static double u[2]; //u[0]: u(k-1); u[1]: u(k)
static double e[3]; //e[0] la` e1(k), e[1]: e1(k-1), e[2]: e1(k-2) double etemp;
double e2; //e2 trong cong thuc cap nhat thong so int i1;
//dua toc do do duoc thanh ap /* if(Output>2.6)
etemp = (2952 - currentspeed)/1135.4; else if( Output >= 2.4)
etemp = 0; else etemp =(2720 - currentspeed)/1133.8; */ /* Tinh' e2 //*/ if(Output<=2.4) e2 = 2.5-(2695.0-SetSpeed-25)/1133.8+Output; // 50ms (0V->2.5V) //if(u<2.4) e = 2.4-(2696.5-dat)/1135.9-u; // 50ms (0V->2.5V) (them 2.3V) if(Output>2.4 & Output<2.6) e2 = 2.5;
if(Output>=2.6) e2 = 2.6-(2897.7- SetSpeed)/1135.4+Output; // 50ms (2.5V->5V) //sai lech dau vao tinh theo ap
// e[2] = USetSpeed - etemp; /* Tinh e1(k) tuc la e[2]*/
if(Output<=2.4) e[2] = 2.4-(2695.0-(SetSpeed - currentspeed- 25))/1133.8; // 50ms (0V->2.5V)
// if(u<2.4) e_omega0 = 2.4-(2696.5-(dat - s/T1))/1135.9; // 50ms (0V->2.5V) if(Output>2.4 & Output<2.6) e[2] = 2.5;
currentspeed))/1135.4; // 50ms (2.5V->5V)
//sai lech tinh theo ap giua toc do dat va tin hieu dieu khien // Output = 2.5 - Output;
// e2 = -USetSpeed + Output; for(i1 =0;i1<3; i1++)
//Cong thuc cap nhat thong so: an[k+1] = an[k] +beta*e2[k]*e1[k-n] a[i1][1] = a[i1][0] + beta*e[2-i1]*e2;
u[1] = u[0] + a[0][1]*e[2] + a[1][1]*e[1] + a[2][1]*e[0]; u[0] = u[1];
e[0] = e[1]; e[1] = e[2];
for (i1 = 0; i1<3; i1++) a[i1][0] = a[i1][1]; return u[1];
}
//Đoạn xuất tín hiệu điều khiển:
void CBAI4Dlg::OnTimer(UINT nIDEvent) {
// TODO: Add your message handler code here and/or call default CString s;
double m_speed;
// static double updatespeed[MAXUPDATE]; double avrspeed =0;
if(m_nTimer) {
m_speed = DataPulse()*speedratio/T0; updatespeed[MAXUPDATE-1] = m_speed; for(i=0; i<MAXUPDATE; i++){
avrspeed+= updatespeed[i];}
avrspeed = avrspeed/MAXUPDATE; //TINH TRUNG BINH DE TRANH' NHIEU for (i=0; i<MAXUPDATE-1; i++)
updatespeed[i] = updatespeed[i+1];
Output = 2.5 - Output; if(Output> MaxValueOut) Output = MaxValueOut; if(Output < MinValueOut) Output = MinValueOut; ptAOVoltageOut.OutputValue = (Output); DRV_AOVoltageOut(DriverHandle, (LPT_AOVoltageOut)&ptAOVoltage Out); if(i<1000) { CurrentSpeed[i] = avrspeed; i++; // }
//plot the measure speed, set speed, control voltage Scope1.Channels[0].Data.AddYPoint(SetSpeed);
Scope1.Channels[1].Data.AddYPoint(avrspeed); Scope2.Channels[0].Data.AddYPoint(Output); }
dwCurrentTime = GetTickCount()- gdwStartTime; s.Format("%0d", dwCurrentTime/1000); this->SetDlgItemText(IDC_STATIC_RUN, s); s.Format("%2.2f",Output); this->SetDlgItemText(IDC_STATIC_VOLTAGE, s); s.Format("%2.2f",SetSpeed - m_speed); this->SetDlgItemText(IDC_STATIC_ERROR, s); s.Format("%4d",m_speed); this->SetDlgItemText(IDC_STATIC_MEASPEED, s); s.Format("%4d",SetSpeed); this->SetDlgItemText(IDC_STATIC_SETSPEED, s); CDialog::OnTimer(nIDEvent); }