恭喜,你发布的帖子
发布于 2020-12-04 10:36:44
5楼
按说,LGF的方式是标准的间隔采样积分方法。怎么是这样?
是在实际PLC上测试的么?
难道每次平均后1.0都变成了0.9999999?
我看程序里面,也没有什么特别的地方,但是确实是按0.9算的,0.9*70=63,我按1.1算经过70秒后的积分值正好是70.但这也仅仅是70秒之内的数值,如果时间增大到几分钟,甚至几小时,积分值还是不准确。反正就不是这个值是介于(1,1.1)之间的一个值。
我把源代码也贴上来。如下:
REGION Reset the function
IF #reset THEN
#statInputOldValue := #ZERO;
#statIntegral := #ZERO;
// Clear LastTime value.
// Initial condition - first Delta time will be 0.
#statLastTime := #CLEAR_TIME;
#integral := #ZERO;
#error := false;
#status := #STATUS_EXECUTION_FINISHED_NO_ERROR;
#subfunctionStatus := #SUB_STATUS_NO_ERROR;
RETURN;
END_IF;
END_REGION
REGION Enable/Disable integral calculation
IF NOT #enable THEN
#statInputOldValue := #ZERO;
// Clear LastTime value.
// If it is not cleared when the function is enabled again,
// the first value will be multiplied with the time difference of the whole disable time
// Initial condition - first Delta time will be 0.
#statLastTime := #CLEAR_TIME;
#integral := #statIntegral;
#error := false;
#status := #STATUS_EXECUTION_FINISHED_NO_ERROR;
#subfunctionStatus := #SUB_STATUS_NO_ERROR;
RETURN;
END_IF;
END_REGION
REGION Get system time
// Read system time
#tempRetval := INT_TO_WORD(RD_SYS_T(OUT => #tempSysTime));
// Error Handling read system time
IF (#tempRetval > #SUB_STATUS_NO_ERROR) THEN
#integral := #statIntegral;
#error := TRUE;
#status := #ERR_SYST_TIME;
#subfunctionStatus := #tempRetval;
RETURN;
END_IF;
END_REGION
REGION Caluclating the integral
// Calculate time difference between last and actual time
// coverting from DTL via time and DInt to Real
// scale from millisecond to second
#tempDeltaTime := DINT_TO_REAL(TIME_TO_DINT(LTIME_TO_TIME(#tempSysTime - #statLastTime))) / #SECOND_IN_MS;
// Write actual to last time
#statLastTime := #tempSysTime;
// integration by trapezoidal rule
// add LastScalIn to ScalIn
// divide by two --> avarage of both - old and actual value
// multiply with time delta --> area unterneath the both borders
#tempCalculation := (#value + #statInputOldValue) * #tempDeltaTime / #DIVIDE_BY_TWO;
// Calculate new integral
#statIntegral += #tempCalculation;
// Save last input
#statInputOldValue := #value;
END_REGION
REGION Write outputs
#integral := #statIntegral;
#error := false;
#status := #STATUS_EXECUTION_FINISHED_NO_ERROR;
#subfunctionStatus := #SUB_STATUS_NO_ERROR;
//ENO mechanism is not used
ENO := TRUE;
END_REGION
请填写推广理由:
分享
只看
楼主