信捷(XINJE)是一家专注于工业自动化控制产品的公司,其PLC(可编程逻辑控制器)产品广泛应用于各种工业场合。在PLC编程中,数字滤波功能块(FB, Function Block)是用于处理输入信号的噪声或干扰,以提高信号质量的一种方法。采用C语言对这些功能块进行封装,则意味着将数字滤波算法以C语言的形式实现,并作为库函数提供给用户使用。这种做法有以下几个方面的意义和主要应用场合:
代码复用:通过封装,可以将通用的数字滤波算法抽象成一个或多个函数,便于在不同的项目中重复利用。
维护性增强:封装后的代码更易于理解和维护。当需要修改算法时,只需调整封装好的函数内部逻辑,而不需要改动整个项目的代码。
性能优化:针对特定平台或硬件进行优化的C语言代码,往往能够获得比高级语言更好的执行效率。
跨平台支持:虽然这里提到的是PLC环境下的应用,但良好的封装设计也有助于未来可能的跨平台迁移工作。
二、主要应用场合
工业现场的数据采集与处理:在工业环境中,传感器等设备采集的数据常常受到电磁干扰、机械振动等因素的影响,导致数据波动较大。这时就可以使用数字滤波来平滑数据,去除不必要的噪声。
过程控制中的参数监测:对于一些需要实时监控的过程变量,如温度、压力等,适当的数字滤波有助于得到更加稳定可靠的测量结果。
运动控制系统:在伺服驱动系统或者步进电机控制等领域,位置反馈信号的质量直接影响到系统的精度。合理运用数字滤波技术可以改善位置反馈信号,从而提高整体控制性能。
通信接口的数据处理:当通过串行或其他方式传输数据时,可能会遇到误码问题。数字滤波可以帮助识别并纠正这些错误,保证信息传递的准确性。
总之,采用C语言封装数字滤波FB块不仅提高了开发效率,还增强了程序的功能性和可靠性,在各类需要精确数据处理的工业应用场景中都发挥着重要作用。此外,这也反映了现代工业自动化领域向着更加智能化、高效化方向发展的趋势。
三、FB块封装
void Digital_Filtering_BODY(Digital_Filtering* self){#define SysRegAddr_HD_D_HM_M
REAL KM_X_1, KM_P_1, KM_A = 1.0, KM_X = 0.0, KM_B = 0.0, KM_P = 1.0, KM_C = 1.0, KM_K = 0.0;
REAL KM_Q, KM_R;
self->IN_PUT_DATA = self->IN_DATA;
int i; int data_long = self->Array_collection_length; if(self->DATA_4[1] != data_long) { self->relay_1 = 0; }
if ( self->relay_1 == 0 ) //第一次数据采集
{ self->DATA_4[1] = data_long; for ( i = 0; i < self->Array_collection_length; i++ ) { self->DATA_1 = self->IN_PUT_DATA; } self->relay_1 = 1; } if ( self->relay_1 != 0 ) //第二次数据采集 { for ( i = 0; i < self->Filter_strength; i++ ) { self->DATA_1 = self->IN_PUT_DATA; } }
REAL DATA_P;
// 找出最大值和最小值
self->data_max = 0;
for ( i = 0; i < self->Array_collection_length; i++ ) {
if ( self->DATA_1 > self->data_max ) {
self->data_max = self->DATA_1; }
}
self->data_min = self->data_max;
for ( i = 0; i < self->Array_collection_length; i++ ) {
if ( self->DATA_1 < self->data_min ) {
self->data_min = self->DATA_1; }
}
self->data_sum = 0; for ( i = 0; i < self->Array_collection_length; i++ ) { self->data_sum = self->DATA_1 + self->data_sum; }
DATA_P = self->data_aver = ( self->data_sum - self->data_min - self->data_max ) / ( self->Array_collection_length - 2 );
for ( i = 0; i < ( self->Array_collection_length - self->Filter_strength ); i++ ) { self->DATA_2 = self->DATA_1; }
for ( i = 0; i < ( self->Array_collection_length - self->Filter_strength ); i++ ) { self->DATA_1[i + self->Filter_strength] = self->DATA_2; }
if ( * ( self->str_1 ) > 3 ) {
* ( self->str_1 ) = 3; }
if ( self->Array_collection_length < 10 ) { self->Filter_strength = 4; }
if ( 10 < self->Array_collection_length ) { self->Filter_strength = data_long / 10 * 2 * ( * ( self->str_1 ) ); }
if ( * ( self->IIR_A ) != self->DATA_3[1] ) //增益系数判断 { * ( self->IIR_B ) = 1.0 - * ( self->IIR_A ); self->DATA_3[1] = * ( self->IIR_A ) ; self->DATA_3[2] = * ( self->IIR_B ); }
if ( * ( self->IIR_B ) != self->DATA_3[2] ) { * ( self->IIR_A ) = 1.0 - * ( self->IIR_B ); self->DATA_3[1] = * ( self->IIR_A ); self->DATA_3[2] = * ( self->IIR_B ); }
REAL DATA_10;
DATA_10 = * ( self->IIR_A ) * DATA_P + * ( self->IIR_B ) * self->DATA_3[3]; self->DATA_3[3] = DATA_10; //数据暂存上一个周期的数据
KM_Q = self->km_q; KM_R = self->km_r;
KM_X_1 = KM_X + 0.0; KM_P_1 = KM_P + KM_Q;
KM_K = KM_P_1 / ( KM_P_1 + KM_R ); KM_X = KM_X_1 + KM_K * ( DATA_10 - KM_X_1 ); KM_P = KM_P_1 - KM_K * KM_P_1;
self->OUT_PUT_DATA = KM_X; //最后输出值
} |