%%%
  VERSION: 1
  LANGUAGE: ENGLISH
%%%

MODULE SWUSER (SYSMODULE)

!---------------------------------------
! G L O B A L  D A T A
!--------------------------------------- 

  ! Description: 
  ! CONST string Version_XXXXXXXX := "1.2";
  !
  !          XXXXXXXX - Module name
  !                 1 - version number  (changed of SEROP) 
  !                 2 - revision number (changed of SEROP)
  CONST string Version_SWUSER := "5.0";

  ! Gundata
  !
  PERS gundata curr_gundata{SW_NOF_GUNS} := [["SERVOGUN", 1, 0.1, 0.1, 0, 0, 0, 1000, 0, 10, 0, 2, 0],
  			           	     ["PNEUGUN", 2, 0.05, 0.02, 0, 0, 0, 1000, 0, 0, 2, 2, 2]];

  ! Spotdata
  !
  PERS spotdata curr_spotdata{2} := [[0, 0, 0, 0],
  				     [0, 0, 0, 0]];

  ! Simulatedata for testing.
  !
  PERS simdata curr_simdata := [0, 0.5, FALSE, FALSE];

  ! Forcedata.
  PERS forcedata curr_forcedata{2} := [[0, 0, 0, 0],
                                       [0, 0, 0, 0]];

  ! Forcedata. Only used in manual actions
  PERS forcedata man_forcedata{2} := [[1000, 1, 0, 0],
                                      [1, 1, 0, 0]];


!-------------------------------------------
! U S E R  I O  -  P N E U M A T I C  G U N
!-------------------------------------------

  ! User signal (DO) to close the gun
  VAR signaldo close_gun;

  ! User signal (DO) to open the gun to the retract stroke
  VAR signaldo open_hlift;

  ! User signal (DO) to close the gun to the workstroke
  VAR signaldo close_hlift;

  ! User signal (DO) to set the equalize signal
  VAR signaldo equalizing;

  ! User signal (GO) to set the pressure
  VAR signalgo press_group;

  ! User signal (DI) to check if pressure is established
  VAR signaldi pressure_ok;

  ! User signal (DI) to check if the gun is open
  VAR signaldi gun_open;

  ! User signal (DI) to check if the highlift position is reached
  VAR signaldi hlift_open;

!---------------------------------------
! W E L D   T I M E R   S I G N A L S
!---------------------------------------

  ! User signal (DO) to reset the timer
  VAR signaldo reset_fault;

  ! User signal (DI) to check if the timer is ready
  VAR signaldi timer_ready;

!---------------------------------------
! G U N   S I G N A L S
!---------------------------------------

  ! User signal (DI) to check the weld contactor
  VAR signaldi weld_contactor;

  ! User signal (DI) to check the water supply1
  VAR signaldi flow1_ok;

  ! User signal (DI) to check the water supply1
  VAR signaldi flow2_ok;

  ! User signal (DI) to check if over temperature
  VAR signaldi temp_ok;

  ! User signal (DI) to check the air pressure in
  ! the equalise cylinder
  VAR signaldi air_ok;

  ! User signal (DI) to check if the equipment is ok
  VAR signaldi equipment_ok;

!---------------------------------------
! P R O C E S S   H O O K S
!---------------------------------------

  ! Common comment for the following process hooks:
  !
  !   If a fault is detected, just put an error message in
  !   the variable ErrText. Then the operator must decide
  !   what to do. If Errtext = TxtRetry then no interaction
  !   with the operator will be performed and the process is restarted.

  ! Define the signals used in all process hooks.
  ! SwInitUserIO is called at the start of motion
  ! just before calling the first process hook
  ! SwPrepare
  !
  PROC SwInitUserIO(num GunNum)

    TEST GunNum
    CASE 1:
      AliasIO g1_reset_fault,reset_fault;
      AliasIO g1_timer_ready,timer_ready;
      AliasIO g1_weld_contact,weld_contactor;
      AliasIO g1_flow1_ok,flow1_ok;
      AliasIO g1_flow2_ok,flow2_ok;
      AliasIO g1_air_ok,air_ok;
      AliasIO g1_temp_ok,temp_ok;
      AliasIO g1_equipment_ok,equipment_ok;
    CASE 2:
      AliasIO g2_close_gun,close_gun;
      AliasIO g2_open_hlift,open_hlift;
      AliasIO g2_close_hlift,close_hlift;
      AliasIO g2_pressure_ok,pressure_ok;
      AliasIO g2_gun_open,gun_open;
      AliasIO g2_hlift_open,hlift_open;
      AliasIO g2_equalize,equalizing;
      AliasIO g2_reset_fault,reset_fault;
      AliasIO g2_timer_ready,timer_ready;
      AliasIO g2_weld_contact,weld_contactor;
      AliasIO g2_flow1_ok,flow1_ok;
      AliasIO g2_flow2_ok,flow2_ok;
      AliasIO g2_air_ok,air_ok;
      AliasIO g2_temp_ok,temp_ok;
      AliasIO g2_equipment_ok,equipment_ok;
      AliasIO g2_press_group,press_group;
    ENDTEST

  ENDPROC

  ! This routine is called at the start of motion. Therefor
  ! most of the dependent equipment should be checked here.
  !
  PROC SwPrepare(num GunNum,
  		 INOUT string ErrText)

    IF curr_simdata.sim_type = 0 THEN
      IF equipment_ok = 0 THEN
        IF flow1_ok = 0 THEN
          ErrText := TxtNoWater1;
          RETURN;
        ENDIF
        IF flow2_ok = 0 THEN
          ErrText := TxtNoWater2;
          RETURN;
        ENDIF
        IF temp_ok = 0 THEN
          ErrText := TxtOverTemp;
          RETURN;
        ENDIF
        IF air_ok = 0 THEN
          ErrText := TxtLowAirPress;
          RETURN;
        ENDIF
      ENDIF
    ENDIF

    IF curr_gundata{GunNum}.gun_type = 2 THEN
      TEST curr_spotdata{GunNum}.tip_force
      CASE 1:
        SetGO press_group, 1;
      CASE 2:
        SetGO press_group, 2;
      CASE 3:
        SetGO press_group, 3;
      CASE 4:
        SetGO press_group, 4;
      ENDTEST
    ENDIF

  ENDPROC

  ! This routine is called a predefined time, pre_close_time
  ! (gundata), before the robot reaches the weldposition.
  ! Order the gun to close within this routine if a pneumatic gun is used.
  ! A servo gun will be ordered to close from the process kernel
  ! when leaving this hook successfully.
  !
  ! There is a possibility to update the current tip_force/plate_thickness/plate_tolerance of the gun.
  ! (eg. int_spotdata{GunNum}.tip_force := new force value;)
  ! (eg. int_spotdata{GunNum}.plate_thickness := new plate thickness;)
  ! (eg. int_spotdata{GunNum}.plate_tolerance := new plate tolerance;)
  !
  ! NOTE! changes here will affect the cycletime.
  ! If a check must be done make it fast.
  !
  PROC SwCloseGun(num GunNum,
  		  INOUT string ErrText)

    VAR bool timeout;
    VAR bool inhib_close;

    IF curr_gundata{GunNum}.gun_type = 2 THEN
      IF (curr_simdata.sim_type <> 0 AND curr_simdata.inhib_close) inhib_close := TRUE;

      IF close_highlift THEN
      SetDO open_hlift, 0;
      SetDO close_hlift, 1;
      ENDIF
      WaitDI gun_open, 1\MaxTime:=curr_gundata{GunNum}.close_timeout\TimeFlag:=timeout;
      IF timeout THEN
        ErrText := SwPadString (TxtCloseTimeout1) + TxtCloseTimeout2;
        RETURN;
      ENDIF

      IF NOT(inhib_close) THEN
        SetDO close_gun, 1;
        IF manage_equalize SetDO \SDelay := curr_gundata{GunNum}.pre_equ_time, equalizing, 1;
      ENDIF
    ENDIF

  ENDPROC

  ! This routine is called in the weldposition and is the
  ! last routine to be called before the start signal is
  ! sent to the timer. Therefor make the final check and
  ! make it fast.
  !
  PROC SwPreWeld(num GunNum,
  		 INOUT string ErrText)

    VAR bool timeout;

    IF curr_simdata.sim_type = 0 THEN
      IF equipment_ok = 0 THEN
        IF flow1_ok = 0 THEN
          ErrText := TxtNoWater1;
          RETURN;
        ENDIF
        IF flow2_ok = 0 THEN
          ErrText := TxtNoWater2;
          RETURN;
        ENDIF
        IF temp_ok = 0 THEN
          ErrText := TxtOverTemp;
          RETURN;
        ENDIF
        IF air_ok = 0 THEN
          ErrText := TxtLowAirPress;
          RETURN;
        ENDIF
      ENDIF
    ENDIF

    IF ((curr_simdata.sim_type = 0) AND (timer_ready = 0)) THEN
      SwResetFault GunNum;
      ErrText := TxtTimerReady;
      RETURN;
    ENDIF

    IF (curr_simdata.sim_type = 0) AND (weld_contactor = 0) THEN
      ErrText := TxtWeldContactor;
      RETURN;
    ENDIF

    IF curr_gundata{GunNum}.gun_type = 2 THEN
      IF curr_simdata.sim_type = 0 THEN
        WaitDI pressure_ok,1\MaxTime:=curr_gundata{GunNum}.close_timeout\TimeFlag:=timeout;
        IF timeout THEN
          ErrText := TxtPressNok;
          RETURN;
        ENDIF
      ENDIF
    ENDIF

  ENDPROC

  ! This routine is called just after receiving the
  ! weld_complete. A servo gun will be ordered to open from
  ! the process kernel just after receiving the signal. If
  ! check must be done make it fast.
  !
  PROC SwOpenGun(num GunNum,
  		 INOUT string ErrText)

    VAR bool timeout;

    IF curr_gundata{GunNum}.gun_type = 2 THEN
      SetDO close_gun, 0;
    IF manage_equalize SetDO \SDelay := curr_gundata{GunNum}.post_equ_time, equalizing, 0;

      IF open_highlift THEN
      SetDO close_hlift, 0;
      SetDO open_hlift, 1;
      ENDIF

      WaitTime curr_gundata{GunNum}.open_time;

      WaitDI gun_open,1\MaxTime:=curr_gundata{GunNum}.open_timeout\TimeFlag:=timeout;
      IF timeout THEN
        ErrText := SwPadString (TxtOpenTimeout1) + TxtOpenTimeout2;
        RETURN;
      ENDIF
    ENDIF

    IF (curr_simdata.sim_type = 0) THEN
      curr_gundata{GunNum}.weld_counter := curr_gundata{GunNum}.weld_counter + 1;
    ENDIF

  ENDPROC

  ! This routine is called when the time weld_timeout has
  ! elapsed without receiving the weld_complete signal or when
  ! receiving the fault signal from the weld timer during the
  ! weld sequence.A servo gun will be ordered to open from
  ! the process kernel just before this hook is called.
  ! If TxtRetry or TxtReweld is returned from this routine
  ! the process will start from the beginning.
  !
  PROC SwWeldFault(num GunNum,
  		   INOUT string ErrText)

  ENDPROC

  ! This routine is called when the info button has been pressed.
  ! The type of error is presented in the string variable ErrType.
  ! The reason for the stop is presented in the string variable ErrText.
  ! Errtype can be equal to TxtSwPrepare, TxtSwCloseGun, TxtSwPreWeld, TxtSwOpenGun and TxtGenWeldTitle. 
  ! ErrText can be equal to TxtGunNotOpen, TxtGenWeldTimout, TxtGenWeldFault or the text returned from 
  ! the user hooks SwPrepare, SwClosegun, SwPreweld or SwOpengun.
  !
  PROC SwErrorInfo(num GunNum,
                   string ErrType,
                   string ErrText)
  
    VAR num in_key;

    TPErase;
    TPWrite ErrType;
    TPWrite ErrText;
    TPWrite "No further information";

    TPReadFK in_key,"","","","","","Return";

    TPErase;

    TEST in_key
    CASE 5:
      RETURN;
    DEFAULT:
      RETURN;
    ENDTEST

  ENDPROC

  ! This routine resets the weld timer fault and is called
  ! from the hook SwPreWeld if the signal timer_ready is 0.
  ! This routine is also called from the kernal, so do not
  ! change the name.
  !
  PROC SwResetFault (num GunNum)

    PulseDO \PLength:=reset_fault_time, reset_fault;
    WaitTime reset_fault_idle;

  ENDPROC

ENDMODULE
