在氣體分析儀使用過程中,為了力求分析結果的准確性,一般要求通過的氣體流量盡可能的穩定。為了保證流量控制的穩定,我們采用PID調節來控制氣路閥門的開度。
1、硬件設計
我們采用的流量計為氣體質量流量計,采用熱式原理,輸出0-5VDC的信號。該流量計如下:
鑒於該流量計的特性,我們設計如下的采集電路來完成流量數據的采集,具體原理圖如下:
對於流量控制閥我們選擇了電動比例調節閥,該閥給的電壓不一樣時,其開度是不一樣的,所以可以通過PWM來控制其在0-100%的范圍內開關,從而獲得我們需要的流量。
關於PWM部分的電路我們采用TIM定時器產生,通過響應的隔離電路產生幅值為24VDC的PWM波。具體的原理圖如下:
2、軟件設計
關於流量的采集與前述的模擬量的采集一致,不再多說。我們主要實驗PID控制以及PWM輸出等部分。
(1)PID控制
PID是控制中最為常見的控制器,其由比例、積分、微分等部分組成,器常見的結構框圖如下所示:
這次我們要實現PID控制器,采用增量型算法,具有變積分,梯形積分和抗積分飽和功能,具體的軟件流程圖如下:
根據上述流程圖,我們很容易實現PID控制器:
1 /* PID初始化操作,需在對vPID對象的值進行修改前完成 */ 2 /* CLASSICPID vPID,通用PID對象變量,實現數據交換與保存 */ 3 /* float vMax,float vMin,過程變量的最大最小值(量程范圍) */ 4 void PIDParaInitialization(CLASSICPID vPID,float vMax,float vMin) 5 { 6 vPID->maximum=vMax; /*輸出值上限*/ 7 vPID->minimum=vMin; /*輸出值下限*/ 8 9 vPID->setpoint=vMin; /*設定值*/ 10 vPID->kp=0.6; /*比例系數*/ 11 vPID->ki=0.03; /*積分系數*/ 12 vPID->kd=0.01; /*微分系數*/ 13 14 vPID->lasterror=0.0; /*前一拍偏差*/ 15 vPID->preerror=0.0; /*前兩拍偏差*/ 16 vPID->result=vMin; /*PID控制器結果*/ 17 vPID->output=0.0; /*輸出值*/ 18 19 vPID->errorabsmax=(vMax-vMin)*0.8; 20 vPID->errorabsmin=(vMax-vMin)*0.2; 21 22 vPID->deadband=(vMax-vMin)*0.005; /*死區*/ 23 vPID->alpha=0.2; /*不完全微分系數*/ 24 vPID->deltadiff=0.0; 25 26 vPID->integralValue=0.0; 27 } 28 29 /* 通用PID控制器,采用增量型算法,具有變積分,梯形積分和抗積分飽和功能 */ 30 /* 微分項采用不完全微分,一階濾波,alpha值越大濾波作用越強 */ 31 /* CLASSICPID vPID,PID對象變量,實現數據交換與保存 */ 32 /* float pv,過程測量值,對象響應的測量數據,用於控制反饋 */ 33 void PIDRegulator(CLASSICPID vPID,float pv) 34 { 35 float thisError; 36 float result; 37 float factor; 38 float increment; 39 float pError,dError,iError; 40 41 thisError=vPID->setpoint-processValue; //得到偏差值 42 result=vPID->result; 43 if (ABS(thisError)>vPID->deadband) 44 { 45 pError=thisError-vPID->lasterror; 46 iError=(thisError+vPID->lasterror)/2.0; 47 dError=thisError-2*(vPID->lasterror)+vPID->preerror; 48 49 //變積分系數獲取 50 factor=VariableIntegralCoefficient(thisError,vPID->errorabsmax,vPID->errorabsmin); 51 52 //計算微分項增量帶不完全微分 53 vPID->deltadiff=kd*(1-vPID->alpha)*dError+vPID->alpha*vPID->deltadiff; 54 55 increment=vPID->kp*pError+vPID->ki*factor*iError+vPID->deltadiff; //增量計算 56 } 57 else 58 { 59 if((abs(vPID->setpoint-vPID->minimum)<vPID->deadband)&&(abs(pv-vPID->minimum)<vPID->deadband)) 60 { 61 result=vPID->minimum; 62 } 63 increment=0.0; 64 } 65 66 result=result+increment; 67 68 /*對輸出限值,避免超調和積分飽和問題*/ 69 if(result>=vPID->maximum) 70 { 71 result=vPID->maximum; 72 } 73 if(result<=vPID->minimum) 74 { 75 result=vPID->minimum; 76 } 77 78 vPID->preerror=vPID->lasterror; //存放偏差用於下次運算 79 vPID->lasterror=thisError; 80 vPID->result=result; 81 vPID->output=((result-vPID->minimum)/(vPID->maximum-vPID->minimum))*100.0; 82 } 83 84 /*變積分系數處理函數,實現一個輸出0和1之間的分段線性函數 */ 85 /* 當偏差的絕對值小於最小值時,輸出為1;當偏差的絕對值大於最大值時,輸出為0 */ 86 /* 當偏差的絕對值介於最大值和最小值之間時,輸出在0和1之間現行變化 */ 87 /* float error,當前輸入的偏差值 */ 88 /* float absmax,偏差絕對值的最大值 */ 89 /* float absmin,偏差絕對值的最小值 */ 90 static float VariableIntegralCoefficient(float error,float absmax,float absmin) 91 { 92 float factor=0.0; 93 94 if(abs(error)<=absmin) 95 { 96 factor=1.0; 97 } 98 else if(abs(error)>absmax) 99 { 100 factor=0.0; 101 } 102 else 103 { 104 factor=(absmax-abs(error))/(absmax-absmin); 105 } 106 107 return factor; 108 }
(2)PWM輸出
PWM輸出較為簡單,關於TIM配置等網上有很多,在此不再多說。根據PID控制器的輸出,我們計算PWM的占空比,通過占空比來調節閥門的開度,從而控制流量大小。
1 *閥門控制調節*/ 2 void ControlProcess(void) 3 { 4 uint16_t TimerPeriod = 0; 5 uint16_t PWMPulse = 0; 6 float dutyfactor=0.0;//定義占空比 7 8 vPID.setpoint=aPara.phyPara.flowSetPoint; 9 PIDRegulation(&vPID, aPara.phyPara.flowMeasuredValue); 10 dutyfactor=vPID.result/ADC1HighRange; 11 12 /*計算頻率和占空比*/ 13 TimerPeriod = PWMTimePeriod;//計算用於設置ARR寄存器的值使產生信號的頻率為17.57 Khz 14 PWMPulse = (uint16_t) ((TimerPeriod - 1)*dutyfactor);//計算CCR1寄存器的值在通道1和1N產生50%占空比,用於TIM1 15 16 HAL_TIM_PWM_Stop(&htim3, TIM_CHANNEL_1);//停止PWM 17 PWM_TIM_Configuration(TimerPeriod,PWMPulse); 18 HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_1);//啟動PWM 19 }
3、測試結果
軟件編寫完成,硬件連接好后,運行並在線監控。PID控制器的調節速度還是比較快的,流量也比較穩定。如果進行細致的參數整定應該可以進一步提高控制效果。