{------------------------------------------------------------------------------} {µ¥ÔªÃû³Æ£ºtestThread.pas } {Ä£¿éÃû³Æ£º×Ô¶¯¼ì²âÏß³Ì } {Ä£¿é˵Ã÷£ºÏ̴߳´½¨ºó×Ô¶¯Æô¶¯ } { ×Ô¶¯¼ì²âÏ̸߳ù¾ÝplcÖ¸Á¿ØÖÆË®·ÖÒÇ×Ô¶¯Íê³Éº¬Ë®Âʼì²â£¬×Ô¶¯Éϱ¨½á¹û } {½¨Á¢ÈÕÆÚ£º2023-10-27 } {ÐÞ¸ÄÐ޸ģº2025-02-12 } {°æÈ¨ËùÓУºÀîÁ¼Í¥ liangtingli@outlook.com } {------------------------------------------------------------------------------} unit testThread; interface uses Windows, Classes, SysUtils, PubUtils, DateUtils, ActuatorLib; type TTestThread = class(TThread) private { Private declarations } t_ret,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; //У׼ϵÊý ff : boolean; //´óÀà±êÖ¾ procedure UpdateStartClock; procedure UpdateStopClock; procedure UpdateSendGrain; procedure UpdateSendTest; procedure UpdateReadStateError; procedure UpdateReLink; procedure UpdateModifyGrain; procedure UpdateModifyGrainError; procedure UpdateTest; procedure UpdateTestError; procedure UpdateResetError; procedure UpdateFaultCode; 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; 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 //¼ÓÔØÁ¸ÖÖУ׼ϵÊý //×¢Ò⣺´ÓCod²éѯÁ¸ÖÖÐÅÏ¢»áÖØ¸´£¬ÔÝδÐ޸쬴ý¶¨¡£¡£¡£ 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);//ÐÂÔö½Ø¾à ff := Grain.flag; //ÐÂÔö´óÀà±êÖ¾ //¸üнçÃæÐÅÏ¢ 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 := 'Á¸Ê³Æ·ÖÖÐ޸ijɹ¦£¬×¼±¸¾ÍÐ÷£¡'; frmMain.lblAutoRet.Caption := ''; frmMain.lblAutoRet_error.Caption := ''; log4info('Á¸ÖÖÐÅÏ¢£ºÁ¸Ê³Æ·ÖÖÐ޸ijɹ¦£¬×¼±¸¾ÍÐ÷£¡'); end; //³ö´íÏÔʾ--ÐÞ¸ÄÁ¸ÖÖ³ö´í procedure TTestThread.UpdateModifyGrainError; begin //¸üнçÃæÐÅÏ¢ frmMain.lblAutoRet.Caption := ''; frmMain.lblAutoRet_error.Caption := 'Á¸ÖÖÐÅÏ¢£ºÁ¸Ê³Æ·ÖÖÐÞ¸Äʧ°Ü£¬Ë®·ÖÒǹÊÕÏ£¡'; 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.UpdateFaultCode; begin RefashFaultCode(t_faultCode); end; //------- Ö´ÐÐÏß³Ì ---------------------------------------- procedure TTestThread.Start(); var nState : Word; //plc״̬×Ö¡¢Á¸ÖÖ´úÂë 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; //ÉϵçÏȼì²âË®·ÖÒǹÊÕÏÂë ReadFaultCode(hWrDev, @t_faultCode); Synchronize(UpdateFaultCode); //¶Á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 //ÏòË®·ÖÒÇÏ·¢Á¸ÖÖÐÞ¸ÄÖ¸Áî Synchronize(UpdateStartClock); Synchronize(UpdateSendGrain); //¼ÓÔØÁ¸ÖÖϵÊý ret := SendCommands(hWrDev, WR_READY, t_nGrainType, glTime1); Synchronize(UpdateStopClock); //д»Ø¼ì²â½á¹û 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]; } if ff then t_val1 := CalcValue(t_nDatas[0], x0,x1,x2,x3,x4) //´óÀ಻Ôö¼Ó½Ø¾à else 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 ret := SendCommands(hWrDev, WR_RESET, 0, glTime2); if ret<>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(); //¸üйÊÕÏÂë ReadFaultCode(hWrDev, @t_faultCode); Synchronize(UpdateFaultCode); //·ÀÖ¹Ïß³Ì×èÈûCPU Sleep(1000); end; end; end.