From 868daf94f29ce1ffdd799a68c07bb668cd373bcd Mon Sep 17 00:00:00 2001 From: HP\李良庭 <liliangting@lanpucloud.cn:1111> Date: 星期二, 08 七月 2025 11:49:03 +0800 Subject: [PATCH] 提交分辨率自适应版本V3.1.0.1500 --- src/thread/testThread.~pas | 332 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 332 insertions(+), 0 deletions(-) diff --git a/src/thread/testThread.~pas b/src/thread/testThread.~pas new file mode 100644 index 0000000..82df1b5 --- /dev/null +++ b/src/thread/testThread.~pas @@ -0,0 +1,332 @@ +{------------------------------------------------------------------------------} +{单元名称:testThread.pas } +{模块名称:自动检测线程 } +{模块说明:线程创建后自动启动 } +{ 自动检测线程根据plc指令,控制水分仪自动完成含水率检测,自动上报结果 } +{建立日期:2023-10-27 } +{修改修改:2023-11-11 } +{版权所有:李良庭 liangtingli@outlook.com } +{------------------------------------------------------------------------------} +unit testThread; + +interface + +uses + Windows, Classes, SysUtils, PubUtils, DateUtils, ActuatorLib; + +type + TTestThread = class(TThread) + private + { Private declarations } + t_ret : Integer; + t_faultCode : Word; //水分仪故障码 + + t_val1, t_val2 : Double; //计算出来的含水率、容重比 + t_val3, t_val4 : Double; //采集出来的 温度、湿度 + t_nGrainType : Word; //粮种代码 + t_nDatas : array[0..3] of Word; //水分仪数据 + x0,x1,x2,x3,x4,x5 : double; //校准系数 + procedure UpdateStartClock; + procedure UpdateStopClock; + procedure UpdateSendGrain; + procedure UpdateSendTest; + procedure UpdateReadStateError; + procedure UpdateReLink; + procedure UpdateModifyGrain; + procedure UpdateModifyGrainError; + procedure UpdateTest; + procedure UpdateTestError; + procedure UpdateResetError; + procedure UpdateQuit; + protected + procedure Start(); + procedure Execute; override; + public + constructor Create(param: Boolean=false); + procedure Terminate; + end; + +implementation + +uses + uMain, uDM, uInit, uSaveData, Global, log4me; + +{ TTestThread } +//--------线程初始化---------------------------------------- +//线程初始化 +constructor TTestThread.Create(param: Boolean=false); +begin + //线程停止后自动释放 + inherited Create(param); //设置线程运行, False-自动运行, True-手动启动 + FreeOnTerminate := True; //设置线程退出自动销 + t_val1 := 0; + t_val2 := 0; + t_val3 := 0; + t_val4 := 0; + t_ret := 0; +end; + +//线程销毁事件 +procedure TTestThread.Terminate; +begin + inherited; + m_TestThread := 0; //清理线程句柄 +end; + +//--------界面处理函数-------------------------------------- +//计数器开始 +procedure TTestThread.UpdateStartClock; +begin + //启动检测计时器动画 + glStartTest := GetMillisecondTimeStamp; + dm.tmAutoTest.Enabled := true; +end; + +//计数器结束 +procedure TTestThread.UpdateStopClock; +begin + dm.tmAutoTest.Enabled := false; + frmMain.mtAutoClock.Value := 0; +end; + +//状态显示--下发修改粮种指令 +procedure TTestThread.UpdateSendGrain; +begin + //加载粮种校准系数 + Grain := queryGrainSql1(t_Grain, t_nGrainType); + x0 := StrToFloat(Grain.coef[0]); + x1 := StrToFloat(Grain.coef[1]); + x2 := StrToFloat(Grain.coef[2]); + x3 := StrToFloat(Grain.coef[3]); + x4 := StrToFloat(Grain.coef[4]); + x5 := StrToFloat(Grain.Intercept);//新增截距 + + //更新界面信息 + frmMain.lblAutoInfo.Caption := '修改粮种信息,请稍候......'; + frmMain.lblAutoRet.Caption := ''; + frmMain.lblAutoRet_error.Caption := ''; +end; + +//状态显示--下发检测指令 +procedure TTestThread.UpdateSendTest; +begin + //更新界面信息 + frmMain.lblAutoInfo.Caption := '正在检测含水率,请稍候......'; + frmMain.lblAutoRet.Caption := ''; + frmMain.lblAutoRet_error.Caption := ''; +end; + +//-------- 错误信息 --------------------------------------- +//出错显示--读PLC状态字异常 +procedure TTestThread.UpdateReadStateError; +begin + //更新界面信息 + frmMain.lblAutoRet.Caption := ''; + frmMain.lblAutoRet_error.Caption := '读取 PLC状态字 异常!'; + log4error(Format('错误:读取 PLC状态字 异常,返回值=[%d].',[t_ret])); +end; + +//出错回复--一般是重连恢复 +procedure TTestThread.UpdateReLink; +begin + if frmMain.lblAutoRet_error.Caption<>'' then begin + frmMain.lblAutoRet_error.Caption := ''; + log4error('连接:通讯异常后,自动断开重连成功!'); + end; +end; + +//正常显示--修改粮种信息 +procedure TTestThread.UpdateModifyGrain; +begin + //更新界面信息 + frmMain.lblAutoInfo.Caption := '粮食品种修改成功,准备就绪!'; + frmMain.lblAutoRet.Caption := ''; + frmMain.lblAutoRet_error.Caption := ''; + log4info('粮种信息:粮食品种修改成功,准备就绪!'); +end; + +//出错显示--修改粮种出错 +procedure TTestThread.UpdateModifyGrainError; +begin + //更新界面信息 + frmMain.lblAutoRet.Caption := ''; + frmMain.lblAutoRet_error.Caption := Format('粮食品种修改失败,水分仪故障码 [%d]!',[t_faultCode]); + log4error('粮种信息:粮食品种修改失败,水分仪故障!'); +end; + +//正常显示--执行检测 +procedure TTestThread.UpdateTest; +var ss : string; +begin + if glIsDebug then + frmMain.lblAutoInfo1.Caption := Format('粮种[%s], 系数[%s,%s,%s,%s,%s]', + [Grain.Name, + Grain.Coef[0], + Grain.Coef[1], + Grain.Coef[2], + Grain.Coef[3], + Grain.Coef[4]]); + //更新界面信息 + frmMain.lblAutoInfo.Caption := '含水率检测成功!'; + ss := '含水率: '+Format('%.2f',[Trunc(t_val1*100)/100])+'%, 温度: '+Format('%.2f',[t_val3])+'℃, 湿度: '+Format('%.2f',[t_val4])+'%.'; + frmMain.lblAutoRet.Caption := ss; + frmMain.lblAutoRet_error.Caption := ''; + log4info('自动检测:含水率检测成功,'+ss); + + //更新数据库和保存csv + insertTestSql(t_Data,Ord(rmAuto),1,DateTimeToUnix(Now), + Grain.Code,Grain.Name,'', + Trunc(t_val1*100)/100, t_val3, t_val4); + //保存csv文件 + WriteCsvFile(Grain.Name, t_val1, t_val3, t_val4); +end; + +//出错显示--执行检测出错 +procedure TTestThread.UpdateTestError; +begin + //更新界面信息 + frmMain.lblAutoInfo.Caption := '执行检测失败!'; + frmMain.lblAutoRet.Caption := ''; + frmMain.lblAutoRet_error.Caption := '执行检测失败,水分仪故障!'; +end; + +//出错显示--复位失败 +procedure TTestThread.UpdateResetError; +begin + //更新界面信息 + frmMain.lblAutoInfo.Caption := '执行复位失败!'; + frmMain.lblAutoRet.Caption := ''; + frmMain.lblAutoRet_error.Caption := '执行复位操作失败,水分仪故障!'; +end; + +//退出线程--打印日志 +procedure TTestThread.UpdateQuit; +begin + log4info('退出:线程 TestThread()退出.'); +end; + +//------- 执行线程 ---------------------------------------- +procedure TTestThread.Start(); +var + nState : Word; //plc状态字、粮种代码 + ret : Integer; + y : double; //公式y=kx+b +begin + //初始化线程变量 + nState := 0; + t_nGrainType := 0; + t_nDatas[0] := 0; + t_nDatas[1] := 0; + t_nDatas[2] := 0; + t_nDatas[3] := 0; + + //读PLC状态字,获取nState、nGrainType + t_ret := ReadState(hPlcDev,@nState,@t_nGrainType); + if t_ret<=0 then + Synchronize(UpdateReadStateError) + else if ((nState>0) and (t_nGrainType>0)) then begin + //========================================== + //从PLC读取命令并执行 + //注意,这里仅处理PLC下发给水分仪的命令 + //========================================== + case nState of + //0x01-粮食品种改了 + PLC_READY_GRAIN: begin + //检查水分仪故障码 + ret := ReadFaultCode(hWrDev, @t_faultCode); + //向水分仪下发粮种修改指令 + if ret >=0 then begin + Synchronize(UpdateStartClock); + Synchronize(UpdateSendGrain); //加载粮种系数 + ret := SendCommands(hWrDev, WR_READY, t_nGrainType, glTime1); + Synchronize(UpdateStopClock); + end; + if ret<0 then begin + Synchronize(UpdateModifyGrainError); + ResponseState(hPlcDev, PLC_DEVICE_WR_FAULT); + end + else begin + Synchronize(UpdateModifyGrain); + ResponseState(hPlcDev, PLC_READY_FINISH); + end; + end; + //0x03-开始测试 + PLC_DETECT_START: begin + //向水分仪下发检测指令 + Synchronize(UpdateStartClock); + Synchronize(UpdateSendTest); + ret := SendCommands(hWrDev, WR_DETECT, 0, glTime2); + Synchronize(UpdateStopClock); + if ret<0 then begin + Synchronize(UpdateTestError); + ResponseState(hPlcDev, PLC_DEVICE_WR_FAULT); + end + else begin + //从水分仪读取检测结果: + //0-电压、1-重量、2-温度、3-湿度 + ReadDatas(hWrDev, @t_nDatas); + //返回PLC检测成功 + ResponseState(hPlcDev, PLC_DETECT_FINISH); + //计算含水率 + {t_val1 := x0 + + x1 * t_nDatas[0] + + x2 * t_nDatas[0] * t_nDatas[0] + + x3 * t_nDatas[0] * t_nDatas[0] * t_nDatas[0] + + x4 * t_nDatas[0] * t_nDatas[0] * t_nDatas[0] * t_nDatas[0]; } + t_val1 := CalcValue(t_nDatas[0], x0,x1,x2,x3,x4) + x5; //将截距加进去 + //-------------------------------------------- + //用公式 y=kx+b 计算重量,重量-去皮 + y := Wg.k * (t_nDatas[1]-SysConfig.Tare) + Wg.b; + //-------------------------------------------- + //计算容重比 + if SysConfig.Volume=0 then SysConfig.Volume:=1; + t_val2 := y / SysConfig.Volume; //注意这里使用新公式计算容重比 + + //调整温湿度高低位,liliangting 2024-10-15 + t_val3 := t_nDatas[2]/10; + t_val4 := t_nDatas[3]/10; + //t_val3 := SwapHighLowWord(t_nDatas[2])/10; //对温度高低位交换 + //t_val4 := SwapHighLowWord(t_nDatas[3])/10; //对湿度高低位交换 + + //结果输出到界面 + Synchronize(UpdateTest); + + //拼成三个数据的数组,传给PLC + t_nDatas[0] := t_nGrainType; //粮食品种 + t_nDatas[1] := Trunc(t_val1*100); //含水率-->PLC要求乘以100取整,以便寄存器存入整数,并非真实结果 + t_nDatas[2] := Trunc(t_val2*10); //容重比-->PLC要求乘以10 取整,以便寄存器存入整数,并非真实结果 + UploadData(hPlcDev, @t_nDatas); + end; + end; + //0xFE-复位命令 + PLC_DEVICE_WR_RESET: begin + if SendCommands(hWrDev, WR_RESET, 0, glTime2)<0 then begin + Synchronize(UpdateResetError); + ResponseState(hPlcDev, PLC_DEVICE_WR_FAULT); + end; + end; + //其他命令字时,仅清除异常标签,liliangting 2023-12-7 + else + Synchronize(UpdateReLink); + end; + //=====PLC指令解析结束====================== + end + //当不满足指令时,也更新重连标签信息!liliangting 2023.12.8 + else + Synchronize(UpdateReLink); +end; + +//------- 线程入口 ---------------------------------------- +procedure TTestThread.Execute; +begin + { Place thread code here } + while not terminated do begin + //执行检测代码 + Start(); + //防止线程阻塞CPU + Sleep(1000); + end; + Synchronize(UpdateQuit); +end; + +end. -- Gitblit v1.9.3