PLCS.net - Interactive Q & A

PLCS.net - Interactive Q & A (http://www.plctalk.net/qanda/index.php)
-   LIVE PLC Questions And Answers (http://www.plctalk.net/qanda/forumdisplay.php?f=2)
-   -   Read Tag from Rockwell PLC from Codesys? (http://www.plctalk.net/qanda/showthread.php?t=127087)

theColonel26 November 10th, 2020 09:54 PM

Read Tag from Rockwell PLC from Codesys?
 
Read Tag from Rockwell PLC from Codesys 3.5?



Rockwell PLCs would be 5370s, 5380s, 5570s, and 5580s etc.



It seems everyone's EtherNet/IP Adapters aren't tag aware, and they just use the Base CIP protocol on top of Ethernet. I assume Codesys's is the same way but I will ask anyway.



Is there a way to communicated with a Rockwell PLC over Ethernet/IP using Tag names? or would you have to create some convoluted Middleman bridge to do it?




Note: Cross posted on Reddit.

Ken Roach November 10th, 2020 10:57 PM

What is your CoDeSys host; Windows, Linux, or a major vendor PLC ?

The EtherNet/IP Scanner and Adapter objects only do Assembly objects, and the "EtherNet/IP Services" example supports generic CIP objects, not the tag read/write services. I am unaware of any libraries that do support Tag reads/writes, though I'm sure some privately developed ones do exist.

I've seen some examples of executing external routines using the SysProcess.SysProces***ecuteCommand2 function, so there might be a way to use the PyLogix library, or some other library to execute a tag read or write, without adding another element of middleware.

theColonel26 November 10th, 2020 11:00 PM

As of right now it would be a IFM CR series HMC with full access to the Linux OS.

AlfredoQuintero November 11th, 2020 04:22 PM

If it is necessary to exchange data from Codesys tags to Logix tags, and if it is possible to use either a PC or a gateway, there is a very easy way to do this, especially the Windows option, which could run in your HMI. This would cost around US$ 1,400 or in this neighbourhood. If such an option can be considered I can elaborate.

JordanCClark November 12th, 2020 12:29 PM

Discussion here in the codesys forum.

https://forge.codesys.com/forge/talk...ad/e351394aa8/

AustralIan November 12th, 2020 03:12 PM

I think you would need to implement chapter 2 of 1756-pm020 .
You could use the ENIP.Generic_Service function block from the EtherNetIP Services library to send all of those messages.


It shouldn't be too hard to follow along, but you could ask CODESYS to implement it for you.

Ken Roach November 12th, 2020 03:31 PM

Ian, where do you see a Generic Service function block in the CoDeSys EtherNet/IP Services library ?

The ones I see in version 3.5.6.0 are:

Apply_Attributes
Get_Attributes_All
Get_Attribute_Single
NOP
Reset
Set_Attributes_All
Set_Attribute_Single
Start
Stop

It seems clear to me that the Read Tag and Write Tag services (0x4C and 0x4D) or their related services are not implemented by CoDeSys yet.

EDIT: I updated to 3.5.14 and see the Attribute services have been moved to the "Data Exchange" folder, and there is now a Generic Service function block.

But I don't see a way to use Generic Service to execute a Read Tag or Write Tag. They only let you enumerate the CIP Objects by name (a bunch of them, but none related to tags) and require the traditional CIP Class/Instance/Attribute arguments.

theColonel26 November 12th, 2020 04:33 PM

So based on a reply in my Reddit thread on the same topic


This is what I have so far.

only problem is a I don't have a runtime with a EtherNetIP license at the moment. I have a RPi with a license but it is at my office and I have been working from home so I will have to make a trip to go get it.


The simulator doesn't seem to support EtherNet/IP



Code:

TestDINTFromPLC: DINT;

tagRequest: ENIP.Generic_Service;
Trigger: BOOL;
RemoteTagName1: STRING;

Code:

RemoteTagName1 := 'HMIScreenNumber';

tagRequest.xExecute := Trigger;
tagRequest.itfEtherNetIPDevice := ABPLC;
tagRequest.eClass := ENIP.CIPClass.MessageRouterObject;
tagRequest.dwInstance := 1;
tagRequest.wAttribute := 0;
tagRequest.eService := 16#4C; //ABTagReadServiceType.DataTableRead;
tagRequest.pWriteData := ADR(RemoteTagName1);
tagRequest.udiWriteDataSize := SIZEOF(RemoteTagName1);
tagRequest.pReadData := ADR(TestDINTFromPLC);
tagRequest.udiReadDataSize := SIZEOF(TestDINTFromPLC);
tagRequest();


Ken Roach November 12th, 2020 04:48 PM

My RPi with the license is on the boat, and I'm in the office, so I get it. Sent myself some notes on how to finally get around to setting up my VPN, too.

Using the MessageRouter is not something I'm familiar with. Thanks for bringing up this topic !

I will try to poke around with this tonight with my RPi/CoDeSys and 1756-L61/ENBT testbench.

AustralIan November 13th, 2020 04:14 AM

> I have a RPi with a license but it is at my office
> My RPi with the license is on the boat
You can use the soft PLC (Codesys Control Win V3 [x64]) that can be installed with the codesys IDE.
You'll get 30 minute Ethernet/IP demo then need to restart it.
You should be able to start it from the taskbar systray.

I do not have a Logix Processor or Studio 5K.

> This is what I have so far.
Yeah, that message router there looks useful.
Check out "Multiple Service Packet Service" Example in the 1756-pm020.
It looks like you could use it to get around the fact the Generic_Service FB does not support symbolic paths.


Code:

PROGRAM PLC_PRG
VAR
        i : INT;
       
        TestDINTFromPLC: DINT;
        tagRequest: ENIP.Generic_Service;
        Trigger: BOOL;
        RemoteTagName1: STRING := 'testDINT';
        numBytesTagName : BYTE;
        Request: ARRAY [0..255] OF BYTE;
        numBytesRequest : UDINT;
       
        Response : ARRAY [0..255] OF BYTE;
        ReceivedBytes : UDINT;
END_VAR

Code:

// https://literature.rockwellautomation.com/idc/groups/literature/documents/pm/1756-pm020_-en-p.pdf
// See Example under Multiple Service Packet Service
RemoteTagName1 := 'testDINT1';

Request[0] := 1; //Multi Service contains 1 service request
Request[1] := 0;
Request[2] := 4; //BYTE position of first request
Request[3] := 0;
Request[4] := 16#4C;//Service code Read Tag Service

//get length of tag name
numBytesTagName := TO_BYTE(Standard.LEN(RemoteTagName1));

//byte 5 is size of path in words. 1 word for 16#91 and length of tag name.
IF (numBytesTagName.0) THEN
        //ODD tag name length
        Request[5] := 1 + (numBytesTagName / 2) + 1;
ELSE
        //EVEN tag name length
        Request[5] := 1 + (numBytesTagName / 2);
END_IF

//byte 6 is 91
Request[6] := 16#91;

//byte 7 is number of bytes in tagname
Request[7] := numBytesTagName;

//Copy tag name
FOR i := 0 TO numBytesTagName - 1 DO
        Request[i+8] := RemoteTagName1[i];
END_FOR

IF (numBytesTagName.0) THEN
        //ODD tag name length
        Request[8 + numBytesTagName] := 16#00; // need to fill the WORD of the tagname
        Request[9 + numBytesTagName] := 16#01; // Read 1 element LOW BYTE
        Request[10 + numBytesTagName] := 16#00; // Read 1 element HIGH BYTE
        numBytesRequest := 11 + numBytesTagName;
ELSE
        //EVEN tag name length
        Request[8 + numBytesTagName] := 16#01; // Read 1 element LOW BYTE
        Request[9 + numBytesTagName] := 16#00; // Read 1 element HIGH BYTE
        numBytesRequest := 10 + numBytesTagName;
END_IF


tagRequest(
        xExecute:= trigger,
        xDone=> ,
        xBusy=> ,
        xError=> ,
        itfEtherNetIPDevice:= ABPLC,
        eClass:= 16#02,    //Message Router
        dwInstance:= 16#01, //Message Router
        eError=> ,
        wAttribute:= , //none
        eService:= 16#0A, //Multiple Service Packet Service (Request)
        pWriteData:= ADR(Request),
        udiWriteDataSize:= numBytesRequest,
        pReadData:= ADR(Response),
        udiReadDataSize:= SIZEOF(Response),
        udiReceivedDataSize=> ReceivedBytes);
       
// TODO: process the returned data


theColonel26 November 13th, 2020 09:17 AM

Holy Heck!! How have I never found the 1756-pm020 document before?
I didn't think there was any public documentation like this from rock well.


:beer::dance:

theColonel26 November 13th, 2020 11:35 PM

2 Attachment(s)
OK I have the Win V3 Demo running and I cam connected to it with my programming running.

When I got on line it says my EtherNet/IP Scanner is not running.

I don't get it. I don't need to do anything with the EtherNet/IP Scanner I/O Mapping and EtherNet/IP Scanner IEC Objects tabs do I?

I am trying to trying to use a FB to manually make the requests. Those are if you want to setup cyclical polling for like a Remote IO module or something correct?

Or am I completely off?

theColonel26 November 13th, 2020 11:45 PM

Quote:

Originally Posted by AustralIan (Post 867743)
It looks like you could use it to get around the fact the Generic_Service FB does not support symbolic paths.

What do you mean doesn't support Symbolic Paths. Do you just mean Tags? or is this another layer of CIP that I haven't heard of yet?

Also what is the difference between Symbolic Segment addressing and Symbolic Instance addressing? I am referring to page 18 of the 1756-pm020 document.

dmroeder November 14th, 2020 12:00 AM

Quote:

Originally Posted by theColonel26 (Post 867813)
What do you mean doesn't support Symbolic Paths. Do you just mean Tags? or is this another layer of CIP that I haven't heard of yet?

Also what is the difference between Symbolic Segment addressing and Symbolic Instance addressing? I am referring to page 18 of the 1756-pm020 document.

Symbolic paths = read by tag names, as described in the PM020 document you have.

Symbolic instance is reading by instance ID, which is probably the way that CODESYS does it.

theColonel26 November 14th, 2020 12:29 AM

ok, So this comment on Reddit explains the example that AustralIan posted.


I though the Data I needed to send was just the tag name so I was confused by AustralIan example until I read this

https://www.reddit.com/r/PLC/comment...eb2x&context=3
Quote:


I suspect your tag name will have to be translated into a symbol path, in some documents referred to the IOI, where it starts with 0x91 followed by the number of bytes in the tag name, then the tag name. The IOI is always an even number of bytes, so odd counts need padded with a 0
AustralIan example is with the Multi Request Service, so there is more too it. With the Single request, I think I just need to worry about Request[6] and above. Which would be request[0] with the Read Tag Service.

I still have my issue with the EtherNet/IP scanner not running though. Obviously I am doing something wrong I am just not sure what it is.


All times are GMT -5. The time now is 06:14 AM.

.