From 1c9d8f3b6b0097a77f59d88b8b89ea609670bee3 Mon Sep 17 00:00:00 2001 From: Paul Barron Date: Tue, 17 Dec 2019 14:46:55 +0100 Subject: [PATCH] Remove mode 2 from position restore It was decided in a code review that mode 2 wasn't doing exactly as we wanted and that it probably wasn't required, at least for now. Changes to logic so that the position restore is only done after a power cycle and not a download, reset cold or reset origin. --- solution/tc_project_app/POUs/MAIN.TcPOU | 93 ++++++++++++++++--------- 1 file changed, 59 insertions(+), 34 deletions(-) diff --git a/solution/tc_project_app/POUs/MAIN.TcPOU b/solution/tc_project_app/POUs/MAIN.TcPOU index add0d67..de4615c 100644 --- a/solution/tc_project_app/POUs/MAIN.TcPOU +++ b/solution/tc_project_app/POUs/MAIN.TcPOU @@ -39,15 +39,20 @@ VAR //fbEK1110 : EK1110; (******Startup, Shutdown and UPS********) - eStartUp: (ColdStart, ReadAxisFeedbackType, CheckReadDone, ExecuteRestore, CheckRestore, FinishRestore); - bPositionRestoreDone : BOOL := FALSE; - bExecuteReadEncRefSys : BOOL := TRUE; - iRetry : INT; - fbReadEncRefSys : ARRAY [1..gvl_app.axisNum] OF MC_ReadParameter; fbUPS : FB_S_UPS_CX51x0; eUpsMode : E_S_UPS_Mode := eSUPS_WrPersistData_Shutdown; + eStartUp: (ColdStart, ReadAxisFeedbackType, CheckReadDone, ExecuteRestore, CheckRestore, FinishRestore); + bPositionRestoreDone : BOOL := FALSE; + bRestoreExecute : BOOL := FALSE; + bExecuteReadEncRefSys : BOOL := FALSE; + iRetry : INT; + fbReadEncRefSys : ARRAY [1..gvl_app.axisNum] OF MC_ReadParameter; fbRestorePosition : ARRAY [1..GVL_app.axisNum] OF MC_SetPosition; +END_VAR + +VAR PERSISTENT + bRestoreOnStartup : BOOL; END_VAR]]> IF eGlobalSUpsState = eSUPS_PowerFailure THEN (* first cycle of powerfailure *) (* execute code that should only be done once with each powerfailure, i.e. increase powerfailure counter *) + bRestoreOnStartup:=TRUE; STORE_PERSISTENT(); + RETURN; ELSIF eGlobalSUpsState > eSUPS_PowerFailure THEN (* next cycles of powerfailure *) (* skip regular code execution for the remaining cycles of the powerfailure/writing of persistent data/quick shutdown ... *) @@ -65,12 +72,12 @@ END_IF RESTORE_POSITIONS(); PROG(); AXES(); -ERROR(); -STORE_PERSISTENT();]]> +ERROR();]]> - @@ -130,15 +137,22 @@ fbEL1808( // It checks the type of axis, 0=incremental, and that the axis was stationary at shut down. // Because 0 equates to incremental we also need to check that the data is valid, otherwise by default it would restore all axes. // By default an axis will not restore the position unless it is set to opt-in, i.e. gvl.axes[i].config.eRestorePosition is non-zero. +// This needs to be initialised somewhere in TwinCAT code otherwise it will not be available at start up. +// A restore will only be performed on a loss of power, this code shouldn't make any changes on a reset cold, a rest origin or a download. // There is a enum to allow for different types of restore modes, currently only one is implemented. // 0 'DontRestore' // 1 'RestoreWithoutHome' -restores the position using a set position fb and does not set the home bit in the axis struct. // Note from Beckhoff: "A maximum of 1 MB persistent data can be reliably saved over the entire service life." ///######################################################### +IF bRestoreOnStartup THEN + bRestoreOnStartup:=FALSE; + bRestoreExecute:=TRUE; +END_IF + // Upon startup bPositionRestoreDone will be set to FALSE, after successfully completing the following code it will be set TRUE // and should stay TRUE for the rest of the time the PLC is operational, thus this routine should only be completed once. -IF bPositionRestoreDone = FALSE THEN +IF bRestoreExecute AND NOT bPositionRestoreDone THEN // Cycle through function blocks that read the encoder reference system i.e. whether axis is incremental or absolute // Result stored in Value, 0=Inc 1=Abs, execute set during the case statement @@ -152,7 +166,6 @@ IF bPositionRestoreDone = FALSE THEN END_FOR // Cycle through set position function blocks for each axis - // Only axes with RestorePosition=RestoreWithoutHome (mode 1) will be utilised FOR i:=1 TO gvl_app.axisNum DO fbRestorePosition[i]( Axis:= gvl.axes[i].Axis, @@ -200,7 +213,9 @@ IF bPositionRestoreDone = FALSE THEN // Execute position restore by setting fbRestorePosition.execute = TRUE FOR i:=1 TO gvl_app.axisNum DO IF fbReadEncRefSys[i].Valid = TRUE AND fbReadEncRefSys[i].Value = 0 AND NOT(axesPersistent[i].bMovingAtShutdown) THEN - fbRestorePosition[i].Execute:=TRUE; + IF GVL.axes[i].config.eRestorePosition = RestorePosition.RestoreWithoutHome THEN + fbRestorePosition[i].Execute:=TRUE; + END_IF END_IF END_FOR eStartUp:=eStartUp+1; @@ -211,47 +226,49 @@ IF bPositionRestoreDone = FALSE THEN // bPositionRestoreDone will never get set to TRUE and will take up cycle time FOR i:=1 TO gvl_app.axisNum DO IF fbReadEncRefSys[i].Valid = TRUE AND fbReadEncRefSys[i].Value = 0 AND NOT(axesPersistent[i].bMovingAtShutdown) THEN - IF NOT fbRestorePosition[i].Done THEN + IF GVL.axes[i].config.eRestorePosition = RestorePosition.RestoreWithoutHome THEN + IF NOT fbRestorePosition[i].Done THEN RETURN; + END_IF END_IF END_IF END_FOR eStartUp:=eStartUp+1; - FinishRestore: // Remove execute = TRUE for fbRestorePosition + FinishRestore: + // Remove execute = TRUE for fbRestorePosition FOR i:=1 TO gvl_app.axisNum DO fbRestorePosition[i].Execute:=FALSE; END_FOR bPositionRestoreDone:=TRUE; + bRestoreExecute:=FALSE; END_CASE END_IF]]> - 0 THEN - axesPersistent[i].bMovingAtShutdown:=TRUE; - ELSE - axesPersistent[i].bMovingAtShutdown:=FALSE; - END_IF - axesPersistent[i].bMovingAtShutdown:=axesPersistent[i].bMovingAtShutdown OR gvl.axes[i].Axis.Status.Moving; - END_FOR -END_IF]]> + 0 THEN + axesPersistent[i].bMovingAtShutdown:=TRUE; + ELSE + axesPersistent[i].bMovingAtShutdown:=FALSE; + END_IF + axesPersistent[i].bMovingAtShutdown:=axesPersistent[i].bMovingAtShutdown OR gvl.axes[i].Axis.Status.Moving; +END_FOR]]> - + - + @@ -283,11 +300,16 @@ END_IF]]> - + + + + + + @@ -295,9 +317,7 @@ END_IF]]> - - - + @@ -330,21 +350,27 @@ END_IF]]> - + + + + - + + + + + - @@ -352,7 +378,6 @@ END_IF]]> - \ No newline at end of file