Join us today!

Notifications
Clear all

Passing a structure between PLCs via ADS using symbolic addressing

3 Posts
2 Users
4 Reactions
1,376 Views
Posts: 16
Topic starter
(@duncan)
Eminent Member
Joined: 2 years ago

Hey folks,

 

Looking to pass a data structure between two Beckhoff PLCs.

This is only intermittent data, as trays are passed between systems, so not occurring every scan.

 

Can see it's possible via either ADS or EAP.

EAP looks like a little more work, so preferring ADS.

 

Found examples here: 

https://www.dmcinfo.com/latest-thinking/blog/id/9149/sharing-tags-between-beckhoff-plcs-using-ads-read

 

and here:

https://www.plccoder.com/communicating-between-beckhoff-controllers-part-2-ads/

 

But seems to rely on either a fixed offset in the PLC, or mapping to %MB areas and trying to avoid overlapping the addresses.

Is there a way to use symbolic comms, as is done from the ADS .Net library?

 

Thanks!

Duncan

Reply
Topic Tags
2 Replies
2 Replies
benhar-dev
(@benhar-dev)
Joined: 2 years ago

Eminent Member
Posts: 17

@duncan this is possible.  The two function blocks below use symbols instead of index/offset.  👍 

FB_ReadAdsSymByName

https://infosys.beckhoff.com/english.php?content=../content/1033/tcplclib_tc2_dataexchange/1783919627.html

FB_WriteAdsSymByName

https://infosys.beckhoff.com/english.php?content=../content/1033/tcplclib_tc2_dataexchange/1783921547.html

Small example

PROGRAM MAIN
VAR
	
	trigger : BOOL;
	adsWriteStatus : (IDLE, WRITE, BUSY, ERROR);

	adsWrite : FB_WriteAdsSymByName := ( 
			sNetId := '192.168.0.2.1.1', 
			nPort := 851,
			eComMode := E_AdsComMode.eAdsComModeSecureCom, 
			tTimeout := DEFAULT_ADS_TIMEOUT 
		);
		
	sendTrayData : MyTrayStructure;
	
END_VAR
CASE adsWriteStatus OF
	
	IDLE : 
	
		IF trigger THEN
			trigger := FALSE;
			adsWriteStatus := WRITE;
		END_IF
	
	WRITE :

		adsWrite(bWrite := FALSE);
		adsWrite(
			sVarName := 'Main.receivedTrayData',
			nLen := SIZEOF(sendTrayData), 
			nSrcAddr := ADR(sendTrayData), 	
			bWrite := TRUE 	
		);
		
		adsWriteStatus := BUSY;

	BUSY :

		adsWrite(bWrite := FALSE);
		IF NOT adsWrite.bBusy THEN
			IF NOT adsWrite.bError THEN
				adsWriteStatus := IDLE;
			ELSE
				adsWriteStatus := ERROR;
			END_IF
		END_IF
	
	ERROR : // something went wrong...
	
END_CASE

 

Reply
(@duncan)
Joined: 2 years ago

Eminent Member
Posts: 16

@benhar-dev
Thank you Ben, this is perfect!

 

Cheers

Duncan

Reply
Share: