IO Link Process Input/Output X20 DS 438A


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


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

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


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 ?

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.

	FlatStreamRead : fltRead; (*FUB: Read data via FlatStream mode*)
	FlatStreamWrite : fltWrite; (*FUB: Write data via FlatStream mode*)
	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*)


	(* 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);
	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;
			brsmemcpy(ADR(X20AP31x1_Data), ADR(ReadBuffer[1]), Length);

	(* / 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]);
	IF (FlatStreamWrite.status = ERR_OK) THEN
	(* / Flat Stream Handling Write*)

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

All the best

1 Like