IO Link Process Input/Output X20 DS 438A

Hello,

I am working with a IFM DSU100 IO Link Storage Unit. The module is sending 32 Bytes of Input and Output Data. In AS Config page for X20DS438A Module I can only set up to 27 Byte array.
How is it possible to get the whole 32 Bytes ?

The X20DS438A Module has Software version 2.4.2.0

Hello,

If you set the input process data in multiplex mode, it allows you to get whole 32bytes

Hello,
the number of Bytes per module is limited for cyclic communication. If I’m not wrong it should be 30 Bytes IN and 30 Bytes OUT per module. When you configure a second channel with also 27 Bytes of Input, Automation Studio should give you an error when trying to build the project.

As @wenbo.ruan wrote, you can use the Option “Octet-Array Multiplexed” to get more information up to 32 Bytes of data.

“Unlimited” data can accessed using the AsFlatGen Library where you access the registers of the module via the asynchronous channel of X2X.

X2X was designed as an IO Bus not as a data Bus and therefore there are some limitations with the Bytes per module or per cycle. If the limits are exceeded then AsFlatGen is your choice.

BR Fabian

2 Likes

Thanks you Fabian for the reply. I can only use the Octet Array Multiplexed for the INPUT Data. The OUTPUT Data can only be set as a 27 bits Octet Array. How do I manage to get 32 Bytes of data with AsFlatGen ?

Hello,
unfortunately I do not have a AsFlatGen Sample using the IO Link Module.
In General, you can find information about the AsFlatGen here:
For the module: Using IO-Link with FlatStream
For the library: AsFltGen

The section of the library does contain some samples you could import.

When using the AsFltGen approach, make sure to disable the cyclic datapoints. Some modules have exclusive access to the registers, in terms of, if cyclic communication is active for register 1234, then the AsFltGen does not get access to register 1234.

This is an excerpt from a task I used in the past to communicate via AsFltGen to an X20AP31x1. In this case the received array is copied to a datastruct (ADC_REG_typ), provided by the X20AP module.

(*FUBs*)
VAR
	FlatStreamRead : fltRead; (*FUB: Read data via FlatStream mode*)
	FlatStreamWrite : fltWrite; (*FUB: Write data via FlatStream mode*)
END_VAR
(*Locals*)
VAR
	FlatStream_Read_MTU : ARRAY[0..7] OF USINT; (*MTU receiving, same as input MTU in module configuration*)
	FlatStream_Write_MTU : ARRAY[0..3] OF USINT; (*MTU sending, just answering the read request*)
	BlockRecv : USINT; (*Received block in array*)
	Length : UINT; (*Length of received data*)
	ReadBuffer : ARRAY[0..SIZEOF_READ_BUFFER] OF USINT; (*Receiving buffer*)
	X20AP31x1_Data : ADC_REG_typ; (*Datastruct of  X20AP3131*)
END_VAR

PROGRAM _CYCLIC

	(* Flat Stream Handling Read *)
	FlatStreamRead.enable		:= TRUE;
	FlatStreamRead.cfg			:= fltMODE_FRAME;		(* Mode Frame, Received data will be buffered until an end of frame is detected *)
														(* Buffer will be filled until status  flt_ERR_FRAME_FINISHED *)
	FlatStreamRead.pBuf			:= ADR(ReadBuffer);
	FlatStreamRead.bufLen		:= SIZEOF(ReadBuffer);
	FlatStreamRead.pRxBytes		:= ADR(FlatStream_Read_MTU);
	FlatStreamRead.rxBytesLen	:= SIZEOF(FlatStream_Read_MTU);
	FlatStreamRead();
	
	IF (FlatStreamRead.status = fltERR_FRAME_FINISHED) THEN
		IF (FlatStreamRead.validBytes <> 0) THEN
			BlockRecv	:= ReadBuffer[0];							(* The first entry is the "Read back status" and does not contain data *)
			Length		:= SIZEOF(X20AP31x1_Data);
			
			IF (Length > FlatStreamRead.validBytes) THEN
				Length	:= FlatStreamRead.validBytes;
				
			END_IF
			
			brsmemcpy(ADR(X20AP31x1_Data), ADR(ReadBuffer[1]), Length);

		END_IF
	END_IF
	(* / Flat Stream Handling Read *)	
	
	(* Flat Stream Handling Write*)
	FlatStreamWrite.enable		:= TRUE;
	FlatStreamWrite.cfg			:= (fltMODE_SYNCHRON + (SHL(1, 4)));	(* This parameter is used to optimize the communication. It is using the forwarding functionality. SHL (1,4) Forwarding count, max number of unacknowledged send Sende MTU's (max. 7 due to configuration) *)
	FlatStreamWrite.readSequ	:= FlatStreamRead.readSequ;
	FlatStreamWrite.pBuf		:= ADR(ADC_BLK_ALL);
	FlatStreamWrite.bufLen		:= SIZEOF(ADC_BLK_ALL);
	FlatStreamWrite.pTxBytes	:= ADR(FlatStream_Write_MTU[0]);
	FlatStreamWrite.txBytesLen	:= SIZEOF(FlatStream_Write_MTU);
	FlatStreamWrite.pSequ		:= ADR(FlatStream_Read_MTU[0]);
	FlatStreamWrite();
	
	IF (FlatStreamWrite.status = ERR_OK) THEN
		
	END_IF
	(* / Flat Stream Handling Write*)
	
END_PROGRAM

Maybe someone else has an example for IO Link and AsFlatGen available.

All the best
Fabian

2 Likes

Hi Oliver, can you update us, did reply from colleague help you?

Hi Jaroslav , it actually helped me to understand a bit more about flat stream altough I didn’t continue on this way. It may be a little to difficult for me but thanks alot for the tips.

Hi Oliver, thanks for feedback. Feel free to return any time you need something to discuss :slight_smile: And if you find good solution for you, you can describe it in Share info & ideas for other members of this community :slight_smile:

1 Like