Sequences
Each state of a unit's statemachine - a predefined state, a userdefined state or an action - is associated with a Sequence. Sequences are implemented within the context of an application. While there are sequences that are usually implemented for any application, there also exist sequences that are application specific. Such sequences are associated with user-defined states.
Usually at least the following sequences should be implemented for every Unit
- Automatic implements the main task of the Unit (i.e. for a handling unit, move part from A to B)
- GoHome
- Stop
- FaultReaction (FaultReaction and stop may utilize the same sequence)
Sequences are usually implemented in the form of a step sequence.
FUNCTION_BLOCK PickerAutomaticSequence EXTENDS PickerSequence IMPLEMENTS ZCore.ISequence
VAR_INPUT
DelayAufnehmen : LREAL := 0.5; // s
DelayAblegen : LREAL := 0.2; // s
TransportSpeed : LREAL := 70; // %
END_VAR
VAR
_step : ZCore.Step(PickerStep.AutomaticBegin, PickerStep.AutomaticEnd);
_timer : ZAux.Timer;
END_VAR
(* -------------------------------------------------------------------------------------------------- *)
IF(OnStart(_step)) THEN
// init custom sequence variables here ...
END_IF
REPEAT
LogStep();
CASE _step.Index OF
(* ------------------------------------------------------------- *)
PickerStep.AutomaticBegin:
(* ------------------------------------------------------------- *)
_step.SetNext(PickerStep.AutomaticBeginVerticalUp);
(* ------------------------------------------------------------- *)
PickerStep.AutomaticBeginVerticalUp:
(* ------------------------------------------------------------- *)
IF _step.OnEntry()
THEN
_actuator.VerticalLift.MoveUpAsync(THIS^);
END_IF
Await(_actuator.VerticalLift, nextStep:=PickerStep.AutomaticWaitPartAtEnd);
(* ------------------------------------------------------------- *)
PickerStep.AutomaticWaitPartAtEnd:
(* ------------------------------------------------------------- *)
IF _io.PartIsAtEnd.Enabled THEN
_step.SetNext(PickerStep.AutomaticMoveRight);
END_IF
(* ------------------------------------------------------------- *)
PickerStep.AutomaticMoveRight:
(* ------------------------------------------------------------- *)
IF _step.OnEntry()
THEN
_actuator.HorizontalMove.MoveRightAsync(THIS^);
_actuator.VerticalLift.MoveDownAsync(THIS^);
END_IF
Await2(obj1:=_actuator.HorizontalMove, obj2:=_actuator.VerticalLift, nextStep:=PickerStep.AutomaticVerticalDown);
(* ------------------------------------------------------------- *)
PickerStep.AutomaticSwitchMagnetOn:
(* ------------------------------------------------------------- *)
IF _step.OnEntry()
THEN
_io.MagnetEin.Enable(TRUE);
_timer.RunAsync(THIS^, DelayAufnehmen);
END_IF
Await(obj1:=_timer, nextStep:=PickerStep.AutomaticAufnehmenVertikalAuf);
(* ------------------------------------------------------------- *)
PickerStep.AutomaticFetchVerticalUp:
(* ------------------------------------------------------------- *)
IF _step.OnEntry()
THEN
_actuator.VerticalLift.MoveUpAsync(THIS^);
END_IF
Await(obj1:=_actuator.VerticalLift, nextStep:=PickerStep.AutomaticMoveLeft);
(* ------------------------------------------------------------- *)
PickerStep.AutomaticMoveLeft:
(* ------------------------------------------------------------- *)
IF _step.OnEntry()
THEN
_actuator.HorizontalMove.MoveLeftAsync(THIS^);
_actuator.VerticalLift.MoveDownAsync(THIS^);
END_IF
Await2(obj1:=_actuator.HorizontalMove, obj2:=_actuator.VerticalLift, nextStep:=PickerStep.AutomaticMoveDown);
(* ------------------------------------------------------------- *)
PickerStep.AutomaticSwitchMagnetOff:
(* ------------------------------------------------------------- *)
IF _step.OnEntry()
THEN
_io.MagnetEin.Enable(FALSE);
_timer.RunAsync(THIS^, DelayAblegen);
END_IF
Await(obj1:=_timer, nextStep:=PickerStep.AutomaticReleaseVerticalUp);
(* ------------------------------------------------------------- *)
PickerStep.AutomaticReleaseVerticalUp:
(* ------------------------------------------------------------- *)
IF _step.OnEntry()
THEN
_actuator.VerticalLift.MoveUpAsync(THIS^);
END_IF
Await(obj1:=_actuator.VerticalLift, nextStep:=PickerStep.AutomaticEnd);
(* ------------------------------------------------------------- *)
PickerStep.AutomaticEnd:
(* ------------------------------------------------------------- *)
// repeat the automatic sequence, and exit could be triggered by calling SetBusy(FALSE);
_step.SetNext(PickerStep.AutomaticBegin);
ELSE
Abort('sequence contains unhandled step');
END_CASE
UNTIL _step.IsNotRepeatable() OR_ELSE NOT Busy END_REPEAT
Note
This implementation allows to run multiple steps per cycle because of the REPEAT UNTIL statement arround the steps. This makes a sequencer a lot faster but can lead to problems sometimes. If this is not suitable simply remove the REPEAT UNTIL loop and every step is executed in one separate PLC-cycle.