Table of Contents

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.