FUNCTION "Sick_ABS_single" : Void
{ S7_Optimized_Access := 'TRUE' }
VERSION : 0.1
   VAR_INPUT 
      ZSW2_ENC : Word;   // Statuswort 2, Encoder
      G1_ZSW : Word;   // Statuswort, Sensor 1
      G1_XIST1 : DWord;   // Positionswert 1, Sensor 1
      G1_XIST2 : DWord;   // Positionswert 2, Sensor 1
      Resolution : DInt;   // Icremete / Umdrehung der Geberwelle
      MaxValue : DInt;   // Maximalwert, danach automatisch nullen
      Error_Quit : Bool;   // Fehler quittieren
   END_VAR

   VAR_OUTPUT 
      STW2_ENC : Word;   // Steuerwort 2, Encoder
      G1_STW : Word;   // Steuerwort, Sensor 1
      Inkgeber_Err : Bool;   // Ikrementalgeber meldet Störung
   END_VAR

   VAR_IN_OUT 
      Ink_Wert : DInt;   // Aktueller Zählerwert
      Last_Singelturn_Wert : DInt;   // Speicherung des aktuellen Singelturnwerts
      Lauf_Flag : Bool;   // Zähl-Lauf mit Flag ist aktiv
      Flag_Lauf_fertig : Bool;   // Flag-Lauf wurde beendet
      Ohne_Lauf_fertig : Bool;   // Ohne Flag-Lauf wurde beendet
      Null_laden : Bool;   // Zähler mit 0000 laden
   END_VAR

   VAR_TEMP 
      tG1_XIST2 : DInt;   // Positionswert 1, Sensor 1
      Differenz : DInt;
      Nullpunkt : DInt;
   END_VAR


BEGIN
	REGION INIT
	    #STW2_ENC.%X10 := TRUE;        // Steuerung durch SPS aktivieren
	    #G1_STW.%X13 := TRUE;          // Absolutpostiotn zyklisch anfordern
	END_REGION
	
	REGION DATA-FROM ENCODER
	     #tG1_XIST2 := DWORD_TO_DINT(#G1_XIST2);     // Geber - Positionswert 1, Sensor 1
	END_REGION
	
	REGION MULTITURN-EMULATION_FLEX-ENCODER    
	    #Differenz := #tG1_XIST2 - #Last_Singelturn_Wert;
	    #Last_Singelturn_Wert := #tG1_XIST2;
	    
	    IF DINT_TO_REAL(#Differenz) > 0.9 * DINT_TO_REAL(#Resolution)
	        OR DINT_TO_REAL(#Differenz) < -0.9 * DINT_TO_REAL(#Resolution)
	    THEN
	        #Nullpunkt := 1;
	         
	    ELSE
	        #Nullpunkt := 0;
	    END_IF;
	    
	    IF #Differenz >= 1
	    THEN
	        #Ink_Wert := #Ink_Wert + #Differenz - #Nullpunkt * #Resolution;
	    END_IF;
	    
	    IF #Differenz <= -1
	    THEN
	        #Ink_Wert := #Ink_Wert + #Differenz + #Nullpunkt * #Resolution;
	    END_IF;
	    
	END_REGION
	
	REGION MaxWert erreicht   
	    IF #Ink_Wert > #MaxValue THEN            //Wert für Geber nullen erreicht?
	        #Ink_Wert := #Ink_Wert - #MaxValue;     // Flexgeber auf aktuellen Geberwert setzen
	        
	//Laufflag toggeln        
	        IF #Lauf_Flag = 1
	        THEN
	            #Lauf_Flag := 0;
	            #Flag_Lauf_fertig := 1;
	        ELSE
	            #Lauf_Flag := 1;
	            #Ohne_Lauf_fertig := 1;
	        END_IF;
	    ELSE
	        #Flag_Lauf_fertig := 0;
	        #Ohne_Lauf_fertig := 0;
	        
	    END_IF;
	END_REGION
	
	REGION Encoder Null laden
	    IF #Null_laden = true THEN
	        #Ink_Wert := 0;
	        #Last_Singelturn_Wert := #tG1_XIST2;
	        #Null_laden := FALSE;
	        
	    END_IF;
	    
	END_REGION
	
	REGION ERROR_HANDLING
	    IF #G1_ZSW.%X15 = TRUE      // Hat Geber Fehler ?
	    THEN
	        #Inkgeber_Err := 1;
	        
	        IF #Error_Quit THEN                               // Taste Start nach Störung
	            #G1_STW.%X15 := TRUE;     // Geber Fehler quittieren
	        ELSE
	            #G1_STW.%X15 := FALSE;
	        END_IF;
	        
	    ELSE
	        #Inkgeber_Err := 0;
	    END_IF;
	        
	END_REGION
	
	
END_FUNCTION

