> For the complete documentation index, see [llms.txt](https://wiki.codeandcompile.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://wiki.codeandcompile.com/product-reviews/smart-devices/ctrlx-core/06-interfacing-ctrlx-core-with-io-link-master-using-ethercat.md).

# 06- Interfacing ctrlX CORE with IO-Link master using EtherCAT

This video will teach you how to interface ctrlX CORE with IO-Link master using EtherCAT. The following are the examples covered in the video:

{% embed url="<https://www.youtube.com/watch?v=2bgYXHP2zOQ>" %}

### Video Timeline:

[0:00](https://www.youtube.com/watch?v=2bgYXHP2zOQ\&t=0s) - Introduction\
[0:50](https://www.youtube.com/watch?v=2bgYXHP2zOQ\&t=50s) - What are we going to see?\
[1:25](https://www.youtube.com/watch?v=2bgYXHP2zOQ\&t=85s) - Connections\
[2:11](https://www.youtube.com/watch?v=2bgYXHP2zOQ\&t=131s) - Adding IO-Link master in the networks\
[6:28](https://www.youtube.com/watch?v=2bgYXHP2zOQ\&t=388s) - Assign memories for IO-Link devices\
[11:27](https://www.youtube.com/watch?v=2bgYXHP2zOQ\&t=687s) - Example 1: Actuating Signal Lamp using Distance sensor\
[19:45](https://www.youtube.com/watch?v=2bgYXHP2zOQ\&t=1185s) - Example 2: Reading Vendor and Product ID of the IO-Link device using AoE\
[28:35](https://www.youtube.com/watch?v=2bgYXHP2zOQ\&t=1715s) - Example 3: Reading the set-point of the sensor using AoE \
[31:52](https://www.youtube.com/watch?v=2bgYXHP2zOQ\&t=1912s) - Example 4: Writing the set-point of the sensor using AoE \
[34:10](https://www.youtube.com/watch?v=2bgYXHP2zOQ\&t=2050s) - Example 5: Visualizing IO-Link data on the Node-RED dashboard \
[37:49](https://www.youtube.com/watch?v=2bgYXHP2zOQ\&t=2269s) - Outroduction

### **Hardware and Software information**

* Software: ctrlX Works Software Version: 1.18.1
* Hardware: ctrlX CORE Plus

### **ESI description for IO-Link master AL1332**

{% embed url="<https://www.ifm.com/de/de/product/AL1332?tab=documents>" %}

### **Exam**ple 1: How to actuate IO-Link actuator using IO-Link sensor connected to ctrlX CORE via IO-Link master device AL1332.&#x20;

{% code title="GVL declaration" overflow="wrap" lineNumbers="true" %}

```iecst
{attribute 'qualified_only'}
VAR_GLOBAL
	//Distance Sensor
	rawbyte0 AT %IB0 : BYTE;
	rawbyte1 AT %IB1 : BYTE;

	//SignalLamp
	//Segment1
	segment1 AT %QB5 : BYTE;
	segment2 AT %QB4 : BYTE;
	segment3 AT %QB3 : BYTE;
	segment4 AT %QB2 : BYTE;
	segment5 AT %QB1 : BYTE;
END_VAR
```

{% endcode %}

{% code title="PLC variable declaration" overflow="wrap" lineNumbers="true" %}

```iecst
PROGRAM PLC_PRG
VAR
	wData : WORD;
	iDistance : INT;
	bOutput : BOOL;
	bySegment1 : BYTE;
END_VAR
```

{% endcode %}

{% code title="PLC code" overflow="wrap" lineNumbers="true" %}

```iecst
// -------------------- Reading Distance sensor process output --------------------

//Concatinate the byte 0 and byte 1
wData := IL_ConcatByte(GVL.rawbyte0,GVL.rawbyte1);

//Right shift the word by 4 bit
iDistance := WORD_TO_INT(SHR(wData,4));

//Defining limits
IF iDistance > 200 THEN
	iDistance := 200;
END_IF

IF iDistance < 5 THEN
	iDistance := 5;
END_IF

//Set point output
bOutput := GVL.rawbyte1.0;

//SignalLamp condition
IF bOutput = TRUE THEN
  // 2= Green
	GVL.segment1 := 2;
	GVL.segment2 := 2;
	GVL.segment3 := 2;
	GVL.segment4 := 2;
	GVL.segment5 := 2;
	ELSE //4= RED
	GVL.segment1 := 4;
	GVL.segment2 := 4;
	GVL.segment3 := 4;
	GVL.segment4 := 4;
	GVL.segment5 := 4;
END_IF
```

{% endcode %}

### **Exam**ple 2: How to read Vendor and Product ID of IO-Link device in PLC Engineering app using AoE protocol?

{% code title="GVL declaration" overflow="wrap" lineNumbers="true" %}

```iecst
{attribute 'qualified_only'}
VAR_GLOBAL
	//Distance Sensor
	rawbyte0 AT %IB0 : BYTE;
	rawbyte1 AT %IB1 : BYTE;

	//SignalLamp
	//Segment1
	segment1 AT %QB5 : BYTE;
	segment2 AT %QB4 : BYTE;
	segment3 AT %QB3 : BYTE;
	segment4 AT %QB2 : BYTE;
	segment5 AT %QB1 : BYTE;
END_VARde
```

{% endcode %}

{% code title="PLC variable declaration" overflow="wrap" lineNumbers="true" %}

```iecst
PROGRAM PLC_PRG
VAR
	wData : WORD;
	iDistance : INT;
	bOutput : BOOL;
	bySegment1 : BYTE;
	
// ---------------- Read AoE -----------------------------	

//Name of instance
	strMasterName : STRING := 'ethercatmaster';

//Ethercat address of ifm AL1332
	uiEthercatAddr : UINT := 1005;
	strTargetNetId   : IL_ECAT_AOE_NET_ID := (Byte0:= 172, Byte1:=31, Byte2:= 254, Byte3:= 254, Byte4:= 0, Byte5:= 1);

//Vendor variable declaration for IO Link read
	strVendor : STRING(32) := '';  //Variable in which the read result (vendor) value will be copied
	fbIOLinkRead_Vendor: IL_ECATAoeRead;
		
	uiIoLinkPortNbr_Vendor  : UINT := 1;//X1 = Plug, the IO-Link device is connected
	wIoLinkIndex_Vendor     : WORD := 16;   //IO-Link index = 16 (vendor)
	byIoLinkSubIndex_Vendor : BYTE := 0; 	//IO-Link Subindex = 0 (vendor)
	
	bVendor_Error: BOOL;
	bVendor_Done: BOOL;
	bRead_Vendor: BOOL;

	
// X01 Product ID variable declaration for IO Link Read
	strProductID : STRING(32) := '';  //Variable in which the read result (Product ID) value will be copied
	fbIOLinkRead_ProductID: IL_ECATAoeRead;
		
	uiIoLinkPortNbr_ProductID  : UINT := 1;	//X1 = Plug, the IO-Link device is connected
	wIoLinkIndex_ProductID     : WORD := 19;//IO-Link index = 19 (product ID)
	byIoLinkSubIndex_ProductID : BYTE :=0;//IO-Link Subindex = 0 (product ID)
	
	bProductID_Error: BOOL;
	bProductID_Done: BOOL;
	bRead_ProductID: BOOL;
	
END_VAR
```

{% endcode %}

{% code title="PLC code" overflow="wrap" lineNumbers="true" %}

```iecst
//Read Aoe vendor ID
	//Read function
	fbIOLinkRead_Vendor(
	Execute:= bRead_Vendor,  //Execute bit 						
	MasterName:= ADR(strMasterName), //Instance name
	SlaveAddress:= uiEthercatAddr,  //EtherCAT address of IO-Link master
	TargetNetId:= strTargetNetId ,  //Refer from ctrlX I/O
	TargetPort:= 16#1000 + uiIoLinkPortNbr_Vendor, //ADS communication port = 16#1000 + IO-Link port number 
	IndexGroup:= 16#F302, //Fixed for IFM IO-Link
	//IDXOFFS Index Offset 
	//Bits 0-7: IO-Link subindex
	//Bits 8-15: 00000000
	//Bits 16-31: IO-Link index
	IndexOffset:= (16#FFFF0000 AND SHL(ANY_TO_UDINT(wIoLinkIndex_Vendor),16))
					OR (16#000000FF AND ANY_TO_UDINT(byIoLinkSubIndex_Vendor)), 
	SizeOfValue:= SIZEOF(strVendor), //Byte requirement
	ValueAdr:= ADR(strVendor)); //Value
	
IF TRUE = fbIOLinkRead_Vendor.Done THEN
	bVendor_Error := FALSE;  // Reset error
	bVendor_Done := TRUE;    
END_IF;

IF TRUE = fbIOLinkRead_Vendor.Error THEN
	bVendor_Error := TRUE;   // Error handling
	bVendor_Done := FALSE;
END_IF;
	
//Read Aoe Product ID
	fbIOLinkRead_ProductID(
	Execute:= bRead_ProductID, 
	MasterName:= ADR(strMasterName), 
	SlaveAddress:= uiEthercatAddr, 
	TargetNetId:= strTargetNetId , 
	TargetPort:= 16#1000 + uiIoLinkPortNbr_ProductID, 
	IndexGroup:= 16#F302, 
	IndexOffset:= (16#FFFF0000 AND SHL(ANY_TO_UDINT(wIoLinkIndex_ProductID),16))
					OR (16#000000FF AND ANY_TO_UDINT(byIoLinkSubIndex_ProductID)), 
	SizeOfValue:= SIZEOF(strProductID), 
	ValueAdr:= ADR(strProductID), 
);

// -------------------- Reading Distance sensor process output --------------------

//Concatinate the byte 0 and byte 1
wData := IL_ConcatByte(GVL.rawbyte0,GVL.rawbyte1);

//Right shift the word by 4 bit
iDistance := WORD_TO_INT(SHR(wData,4));

//Defining limits
IF iDistance > 200 THEN
	iDistance := 200;
END_IF

IF iDistance < 5 THEN
	iDistance := 5;
END_IF

//Set point output
bOutput := GVL.rawbyte1.0;

//SignalLamp condition
IF bOutput = TRUE THEN
	GVL.segment1 := 2;
	GVL.segment2 := 2;
	GVL.segment3 := 2;
	GVL.segment4 := 2;
	GVL.segment5 := 2;
	ELSE
	GVL.segment1 := 4;
	GVL.segment2 := 4;
	GVL.segment3 := 4;
	GVL.segment4 := 4;
	GVL.segment5 := 4;
END_IF
```

{% endcode %}

### **Exam**ple 3: How to read the Set-Point of distance sensor in crtlX CORE?

{% code title="GVL declaration" overflow="wrap" lineNumbers="true" %}

```iecst
{attribute 'qualified_only'}
VAR_GLOBAL
	//Distance Sensor
	rawbyte0 AT %IB0 : BYTE;
	rawbyte1 AT %IB1 : BYTE;

	//SignalLamp
	//Segment1
	segment1 AT %QB5 : BYTE;
	segment2 AT %QB4 : BYTE;
	segment3 AT %QB3 : BYTE;
	segment4 AT %QB2 : BYTE;
	segment5 AT %QB1 : BYTE;
END_VAR
```

{% endcode %}

{% code title="PLC variable declaration" overflow="wrap" lineNumbers="true" %}

```iecst
PROGRAM PLC_PRG
VAR
	wData : WORD;
	iDistance : INT;
	bOutput : BOOL;
	bySegment1 : BYTE;
	
// ---------------- Read AoE -----------------------------	

//Name of instance
	strMasterName : STRING := 'ethercatmaster';

//Ethercat address of ifm AL1332
	uiEthercatAddr : UINT := 1005;
	strTargetNetId   : IL_ECAT_AOE_NET_ID := (Byte0:= 172, Byte1:=31, Byte2:= 254, Byte3:= 254, Byte4:= 0, Byte5:= 1);

//Vendor variable declaration for IO Link read
	strVendor : STRING(32) := '';  				//Variable in which the read result (vendor) value will be copied
	fbIOLinkRead_Vendor: IL_ECATAoeRead;
		
	uiIoLinkPortNbr_Vendor  : UINT := 1;			//X1 = Plug, the IO-Link device is connected
	wIoLinkIndex_Vendor     : WORD := 16;    		//IO-Link index = 16 (vendor)
	byIoLinkSubIndex_Vendor : BYTE := 0; 		//IO-Link Subindex = 0 (vendor)
	
	bVendor_Error: BOOL;
	bVendor_Done: BOOL;
	bRead_Vendor: BOOL;

	
// X01 Product ID variable declaration for IO Link Read
	strProductID : STRING(32) := '';  			//Variable in which the read result (Product ID) value will be copied
	fbIOLinkRead_ProductID: IL_ECATAoeRead;
		
	uiIoLinkPortNbr_ProductID  : UINT := 1;		//X1 = Plug, the IO-Link device is connected
	wIoLinkIndex_ProductID     : WORD := 19;    	//IO-Link index = 19 (product ID)
	byIoLinkSubIndex_ProductID : BYTE :=0; 		//IO-Link Subindex = 0 (product ID)
	
	bProductID_Error: BOOL;
	bProductID_Done: BOOL;
	bRead_ProductID: BOOL;

// X01 Set point of Variable declaration for IO Link Read  
	uiSetPointRead: UINT;
	uiSetPointRead_swap: UINT; //Varible for byte swap output
	bRead_SetPoint: BOOL;
	
	fbIOLinkRead_ProductID_SetPoint: IL_ECATAoeRead;

	uiIoLinkPortNbr_ProductID_SetPoint  : UINT := 1;		//X1 = Plug, the IO-Link device is connected
	wIoLinkIndex_ProductID_SetPoint     : WORD := 60;    	//IO-Link index = 60 (Set Point)
	byIoLinkSubIndex_ProductID_SetPoint : BYTE := 1; 		//IO-Link Subindex = 1 (Set Point)
	
	bProductID_SetPoint_Error: BOOL;
	bProductID_SetPoint_Done: BOOL;
	
END_VAR
```

{% endcode %}

{% code title="PLC code" overflow="wrap" lineNumbers="true" %}

```iecst
//Read Aoe vendor ID
	
	//Read function
	fbIOLinkRead_Vendor(
	Execute:= bRead_Vendor,  //Execute bit 						
	MasterName:= ADR(strMasterName), //Instance name
	SlaveAddress:= uiEthercatAddr,  //EtherCAT address of IO-Link master
	TargetNetId:= strTargetNetId ,  //Refer from ctrlX I/O
	TargetPort:= 16#1000 + uiIoLinkPortNbr_Vendor, //ADS communication port = 16#1000 + IO-Link port number 
	IndexGroup:= 16#F302, //Fixed for IFM IO-Link
	//IDXOFFS Index Offset 
	//Bits 0-7: IO-Link subindex
	//Bits 8-15: 00000000
	//Bits 16-31: IO-Link index
	IndexOffset:= (16#FFFF0000 AND SHL(ANY_TO_UDINT(wIoLinkIndex_Vendor),16))
					OR (16#000000FF AND ANY_TO_UDINT(byIoLinkSubIndex_Vendor)), 
	SizeOfValue:= SIZEOF(strVendor), //Byte requirement
	ValueAdr:= ADR(strVendor)); //Value
	
IF TRUE = fbIOLinkRead_Vendor.Done THEN
	bVendor_Error := FALSE;  // Reset error
	bVendor_Done := TRUE;    
END_IF;

IF TRUE = fbIOLinkRead_Vendor.Error THEN
	bVendor_Error := TRUE;   // Error handling
	bVendor_Done := FALSE;
END_IF;
	
//Read Aoe Product ID
	fbIOLinkRead_ProductID(
	Execute:= bRead_ProductID, 
	MasterName:= ADR(strMasterName), 
	SlaveAddress:= uiEthercatAddr, 
	TargetNetId:= strTargetNetId , 
	TargetPort:= 16#1000 + uiIoLinkPortNbr_ProductID, 
	IndexGroup:= 16#F302, 
	IndexOffset:= (16#FFFF0000 AND SHL(ANY_TO_UDINT(wIoLinkIndex_ProductID),16))
					OR (16#000000FF AND ANY_TO_UDINT(byIoLinkSubIndex_ProductID)), 
	SizeOfValue:= SIZEOF(strProductID), 
	ValueAdr:= ADR(strProductID), 
);

//Read Aoe Product ID Set Point
fbIOLinkRead_ProductID_SetPoint(
	Execute:= bRead_SetPoint, 
	MasterName:= ADR(strMasterName), 
	SlaveAddress:= uiEthercatAddr, 
	TargetNetId:= strTargetNetId , 
	TargetPort:= 16#1000 + uiIoLinkPortNbr_ProductID_SetPoint, 
	IndexGroup:= 16#F302, 
	IndexOffset:= (16#FFFF0000 AND SHL(ANY_TO_UDINT(wIoLinkIndex_ProductID_SetPoint),16))
					OR (16#000000FF AND ANY_TO_UDINT(byIoLinkSubIndex_ProductID_SetPoint)), 
	SizeOfValue:= SIZEOF(uiSetPointRead), 
	ValueAdr:= ADR(uiSetPointRead), 
);

//Byte swap of Set Point read
uiSetPointRead_swap := WORD_TO_UINT(IL_SwapWord(uiSetPointRead));

IF TRUE = fbIOLinkRead_ProductID_SetPoint.Done THEN
	bProductID_SetPoint_Error := FALSE;  // Reset error
	bProductID_SetPoint_Done := TRUE;
END_IF;

IF TRUE = fbIOLinkRead_ProductID_SetPoint.Error THEN
	bProductID_SetPoint_Error := TRUE;  // Error handling
	bProductID_SetPoint_Done := FALSE;
END_IF;

// -------------------- Reading Distance sensor process output --------------------

//Concatinate the byte 0 and byte 1
wData := IL_ConcatByte(GVL.rawbyte0,GVL.rawbyte1);

//Right shift the word by 4 bit
iDistance := WORD_TO_INT(SHR(wData,4));

//Defining limits
IF iDistance > 200 THEN
	iDistance := 200;
END_IF

IF iDistance < 5 THEN
	iDistance := 5;
END_IF

//Set point output
bOutput := GVL.rawbyte1.0;

//SignalLamp condition
IF bOutput = TRUE THEN
	GVL.segment1 := 2;
	GVL.segment2 := 2;
	GVL.segment3 := 2;
	GVL.segment4 := 2;
	GVL.segment5 := 2;
	ELSE
	GVL.segment1 := 4;
	GVL.segment2 := 4;
	GVL.segment3 := 4;
	GVL.segment4 := 4;
	GVL.segment5 := 4;
END_IF
```

{% endcode %}

### **Exam**ple 4: How to write the Set-Point of distance sensor in crtlX CORE?

{% code title="GVL declaration" overflow="wrap" lineNumbers="true" %}

```iecst
{attribute 'qualified_only'}
VAR_GLOBAL
	//Distance Sensor
	rawbyte0 AT %IB0 : BYTE;
	rawbyte1 AT %IB1 : BYTE;

	//SignalLamp
	//Segment1
	segment1 AT %QB5 : BYTE;
	segment2 AT %QB4 : BYTE;
	segment3 AT %QB3 : BYTE;
	segment4 AT %QB2 : BYTE;
	segment5 AT %QB1 : BYTE;
END_VAR
```

{% endcode %}

{% code title="PLC variables declaration" overflow="wrap" lineNumbers="true" %}

```iecst
PROGRAM PLC_PRG 
VAR 

wData : WORD; 
iDistance : INT; 
bOutput : BOOL; 
bySegment1 : BYTE;

// ---------------- Read AoE -----------------------------
//Name of instance
strMasterName : STRING := 'ethercatmaster';
//Ethercat address of ifm AL1332 
uiEthercatAddr : UINT := 1005; strTargetNetId : IL_ECAT_AOE_NET_ID := (Byte0:= 172, Byte1:=31, Byte2:= 254, Byte3:= 254, Byte4:= 0, Byte5:= 1);

//Vendor variable declaration for IO Link read 
strVendor : STRING(32) := ''; //Variable in which the read result (vendor) value will be copied 
fbIOLinkRead_Vendor: IL_ECATAoeRead;
uiIoLinkPortNbr_Vendor  : UINT := 1;//X1 = Plug, the IO-Link device is connected
wIoLinkIndex_Vendor     : WORD := 16; 	//IO-Link index = 16 (vendor)
byIoLinkSubIndex_Vendor : BYTE := 0; 	//IO-Link Subindex = 0 (vendor)
bVendor_Error: BOOL;
bVendor_Done: BOOL;
bRead_Vendor: BOOL;

// X01 Product ID variable declaration for IO Link Read 
strProductID : STRING(32) := ''; //Variable in which the read result (Product ID) value will be copied 
fbIOLinkRead_ProductID: IL_ECATAoeRead;
uiIoLinkPortNbr_ProductID  : UINT := 1;	//X1 = Plug, the IO-Link device is connected
wIoLinkIndex_ProductID     : WORD := 19; //IO-Link index = 19 (product ID)
byIoLinkSubIndex_ProductID : BYTE :=0; 	//IO-Link Subindex = 0 (product ID)
bProductID_Error: BOOL;
bProductID_Done: BOOL;
bRead_ProductID: BOOL;

// X01 Set point of Variable declaration for IO Link Read 
uiSetPointRead: UINT;
uiSetPointRead_swap: UINT; //Varible for byte swap output
bRead_SetPoint: BOOL;
fbIOLinkRead_ProductID_SetPoint: IL_ECATAoeRead;
uiIoLinkPortNbr_ProductID_SetPoint  : UINT := 1;//X1 = Plug, the IO-Link device is connected
wIoLinkIndex_ProductID_SetPoint     : WORD := 60;//IO-Link index = 60 (Set Point)
byIoLinkSubIndex_ProductID_SetPoint : BYTE := 1; //IO-Link Subindex = 1 (Set Point)
bProductID_SetPoint_Error: BOOL;
bProductID_SetPoint_Done: BOOL;

//------------------Write AoE------------------------- 
uiSetPointWrite : UINT := 25;
uiSetPointWrite_swap: UINT;
bWrite_SetPoint: BOOL;
fbIOLinkWrite_ProductID_SetPoint_write: IL_ECATAoeWrite;
bProductID_SetPoint_Write_Error: BOOL;
bProductID_SetPoint_Write_Done: BOOL;

END_VAR
```

{% endcode %}

{% code title="PLC code" overflow="wrap" lineNumbers="true" %}

```iecst
//Read Aoe vendor ID
	
	//Read function
	fbIOLinkRead_Vendor(
	Execute:= bRead_Vendor,  //Execute bit 						
	MasterName:= ADR(strMasterName), //Instance name
	SlaveAddress:= uiEthercatAddr,  //EtherCAT address of IO-Link master
	TargetNetId:= strTargetNetId ,  //Refer from ctrlX I/O
	TargetPort:= 16#1000 + uiIoLinkPortNbr_Vendor, //ADS communication port = 16#1000 + IO-Link port number 
	IndexGroup:= 16#F302, //Fixed for IFM IO-Link
	//IDXOFFS Index Offset 
	//Bits 0-7: IO-Link subindex
	//Bits 8-15: 00000000
	//Bits 16-31: IO-Link index
	IndexOffset:= (16#FFFF0000 AND SHL(ANY_TO_UDINT(wIoLinkIndex_Vendor),16))
					OR (16#000000FF AND ANY_TO_UDINT(byIoLinkSubIndex_Vendor)), 
	SizeOfValue:= SIZEOF(strVendor), //Byte requirement
	ValueAdr:= ADR(strVendor)); //Value
	
IF TRUE = fbIOLinkRead_Vendor.Done THEN
	bVendor_Error := FALSE;  // Reset error
	bVendor_Done := TRUE;    
END_IF;

IF TRUE = fbIOLinkRead_Vendor.Error THEN
	bVendor_Error := TRUE;   // Error handling
	bVendor_Done := FALSE;
END_IF;
	
//Read Aoe Product ID
	fbIOLinkRead_ProductID(
	Execute:= bRead_ProductID, 
	MasterName:= ADR(strMasterName), 
	SlaveAddress:= uiEthercatAddr, 
	TargetNetId:= strTargetNetId , 
	TargetPort:= 16#1000 + uiIoLinkPortNbr_ProductID, 
	IndexGroup:= 16#F302, 
	IndexOffset:= (16#FFFF0000 AND SHL(ANY_TO_UDINT(wIoLinkIndex_ProductID),16))
					OR (16#000000FF AND ANY_TO_UDINT(byIoLinkSubIndex_ProductID)), 
	SizeOfValue:= SIZEOF(strProductID), 
	ValueAdr:= ADR(strProductID), 
);

//Read Aoe Product ID Set Point
fbIOLinkRead_ProductID_SetPoint(
	Execute:= bRead_SetPoint, 
	MasterName:= ADR(strMasterName), 
	SlaveAddress:= uiEthercatAddr, 
	TargetNetId:= strTargetNetId , 
	TargetPort:= 16#1000 + uiIoLinkPortNbr_ProductID_SetPoint, 
	IndexGroup:= 16#F302, 
	IndexOffset:= (16#FFFF0000 AND SHL(ANY_TO_UDINT(wIoLinkIndex_ProductID_SetPoint),16))
					OR (16#000000FF AND ANY_TO_UDINT(byIoLinkSubIndex_ProductID_SetPoint)), 
	SizeOfValue:= SIZEOF(uiSetPointRead), 
	ValueAdr:= ADR(uiSetPointRead), 
);

//Byte swap of Set Point read
uiSetPointRead_swap := WORD_TO_UINT(IL_SwapWord(uiSetPointRead));

IF TRUE = fbIOLinkRead_ProductID_SetPoint.Done THEN
	bProductID_SetPoint_Error := FALSE;  // Reset error
	bProductID_SetPoint_Done := TRUE;
END_IF;

IF TRUE = fbIOLinkRead_ProductID_SetPoint.Error THEN
	bProductID_SetPoint_Error := TRUE;  // Error handling
	bProductID_SetPoint_Done := FALSE;
END_IF;


//Write Aoe Product ID Set Point
	//uiSetPointWrite_conv := ROR(SetPointWrite,8);
	uiSetPointWrite_swap := WORD_TO_UINT(IL_SwapWord(uiSetPointWrite));
	fbIOLinkWrite_ProductID_SetPoint_write(
	Execute:= bWrite_SetPoint, 
	MasterName:= ADR(strMasterName), 
	SlaveAddress:= uiEthercatAddr, 
	TargetNetId:= strTargetNetId, 
	TargetPort:= 16#1000 + uiIoLinkPortNbr_ProductID_SetPoint, 
	IndexGroup:= 16#F302, 
	IndexOffset:= (16#FFFF0000 AND SHL(ANY_TO_UDINT(wIoLinkIndex_ProductID_SetPoint),16))
					OR (16#000000FF AND ANY_TO_UDINT(byIoLinkSubIndex_ProductID_SetPoint)), 
	ValueAdr:= ADR(uiSetPointWrite_swap), 	
	SizeOfValue:= SIZEOF(uiSetPointWrite_swap), 
	//SizeOfValue:= 2,
);

IF TRUE = fbIOLinkWrite_ProductID_SetPoint_write.Done THEN
	bProductID_SetPoint_Write_Error := FALSE;// FB Finished -> Product name was read,
	bProductID_SetPoint_Write_Done := TRUE;
END_IF;

IF TRUE = fbIOLinkWrite_ProductID_SetPoint_write.Error THEN
	bProductID_SetPoint_Write_Error := TRUE;// Error handling
	bProductID_SetPoint_Write_Done := FALSE;
END_IF;


// -------------------- Reading Distance sensor process output --------------------

//Concatinate the byte 0 and byte 1
wData := IL_ConcatByte(GVL.rawbyte0,GVL.rawbyte1);

//Right shift the word by 4 bit
iDistance := WORD_TO_INT(SHR(wData,4));

//Defining limits
IF iDistance > 200 THEN
	iDistance := 200;
END_IF

IF iDistance < 5 THEN
	iDistance := 5;
END_IF

//Set point output
bOutput := GVL.rawbyte1.0;

//SignalLamp condition
IF bOutput = TRUE THEN
	GVL.segment1 := 2;
	GVL.segment2 := 2;
	GVL.segment3 := 2;
	GVL.segment4 := 2;
	GVL.segment5 := 2;
	ELSE
	GVL.segment1 := 4;
	GVL.segment2 := 4;
	GVL.segment3 := 4;
	GVL.segment4 := 4;
	GVL.segment5 := 4;
END_IF
```

{% endcode %}

### Example 5: Visualize the parameters on the Node-RED dashboard

<figure><img src="/files/32hf5E6pDI10XdZWReUS" alt="Node-RED Dashboard"><figcaption><p>Node-RED Dashboard</p></figcaption></figure>

{% file src="/files/ARdzIomXXsn8crYgPlPk" %}
Node-RED flow
{% endfile %}
