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