Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to write STRUCT value #7

Open
uthaman opened this issue Jun 21, 2016 · 13 comments
Open

Unable to write STRUCT value #7

uthaman opened this issue Jun 21, 2016 · 13 comments

Comments

@uthaman
Copy link

uthaman commented Jun 21, 2016

Hi,

I am not able to write Message type data to PLC, When i read the value and check the Type , it says "STRUCT" and when I use the same to write it says "(CIP type does not match object type)"

final byte[] data = new byte[] { (byte)0xCE, (byte)0x0F, 7, 0, 0, 0, 'w', 'j', 'h', ' ', '1', '2', '4' };
CIPData value1 = new CIPData(Type.STRUCT, data);
plc.writeTag("S1_ScreenId", value1);

Below is the finest logs.

Jun 21, 2016 4:32:07 PM etherip.protocol.Connection write
FINER: Protocol Encoding
Encapsulation Header
UINT command : SendRRData (0x006F)
UINT length : 64
UDINT session : 0x1002D600
UDINT status : 0x00000000
USINT context[8] : 'Funstuff'
UDINT options : 0x00000000
Send RR Data
UDINT interface handle : 0
UINT timeout : 0
UINT count (addr., data): 2
UINT address type : 0x0 (UCMM)
UINT address length : 0x00
UINT data type : 0xB2 (Unconnected Message)
UINT data length : 48
MR Request
USINT service : CM_Unconnected_Send (0x52)
USINT path : Path (2 el) Class(0x20) 0x6 (ConnectionManager), instance(0x24) 1
CM_Unconnected_Send
USINT tick_time : 10
USINT ticks : -16
UINT message size : 33
/// embedded message /// (33 bytes)
MR Request
USINT service : CIP_WriteData (0x4D)
USINT path : Path Symbol(0x91) 'S1_ScreenId', 0x00
USINT type, data : 'wjh 124'
///\ embedded message ///
USINT pad : 0 (odd length message)
USINT path size : 1 words
USINT reserved : 0
USINT port 1, slot 0

Jun 21, 2016 4:32:07 PM etherip.protocol.Connection write
FINEST: Data sent (88 bytes):
0000 - 6F 00 40 00 00 D6 02 10 00 00 00 00 46 75 6E 73 - [email protected]
0010 - 74 75 66 66 00 00 00 00 00 00 00 00 00 00 02 00 - tuff............
0020 - 00 00 00 00 B2 00 30 00 52 02 20 06 24 01 0A F0 - ......0.R. .$...
0030 - 21 00 4D 07 91 0B 53 31 5F 53 63 72 65 65 6E 49 - !.M...S1_ScreenI
0040 - 64 00 A0 02 01 00 CE 0F 07 00 00 00 77 6A 68 20 - d...........wjh
0050 - 31 32 34 00 01 00 01 00 - 124.....

Jun 21, 2016 4:32:07 PM etherip.protocol.Connection read
FINEST: Data read (46 bytes):
0000 - 6F 00 16 00 00 D6 02 10 00 00 00 00 46 75 6E 73 - o...........Funs
0010 - 74 75 66 66 00 00 00 00 00 00 00 00 00 00 02 00 - tuff............
0020 - 00 00 00 00 B2 00 06 00 CD 00 FF 01 07 21 - .............!

Jun 21, 2016 4:32:07 PM etherip.protocol.Connection read
FINER: Protocol Decoding
Encapsulation Header
UINT command : SendRRData (0x006F)
UINT length : 22
UDINT session : 0x1002D600
UDINT status : 0x00000000 (OK)
USINT context[8] : 'Funstuff'
UDINT options : 0x00000000
Received RR Data
UDINT interface handle : 0
UINT timeout : 0
UINT count (addr., data): 2
UINT address type : 0x0 (UCMM)
UINT address length : 0
UINT data type : 0xB2 (Unconnected Message)
UINT data length : 6
MR Response
USINT service : CIP_WriteData_Reply (0xCD)
USINT reserved : 0x0
USINT status : 0xffffffff ()
USINT ext. stat. size : 0x1
USINT ext status : 0x2107 (CIP type does not match object type)

Jun 21, 2016 4:32:07 PM etherip.protocol.Connection write
FINER: Protocol Encoding
Encapsulation Header
UINT command : UnRegisterSession (0x0066)
UINT length : 0
UDINT session : 0x1002D600
UDINT status : 0x00000000
USINT context[8] : 'Funstuff'
UDINT options : 0x00000000

Jun 21, 2016 4:32:07 PM etherip.protocol.Connection write
FINEST: Data sent (24 bytes):
0000 - 66 00 00 00 00 D6 02 10 00 00 00 00 46 75 6E 73 - f...........Funs
0010 - 74 75 66 66 00 00 00 00 - tuff....

@kasemir
Copy link
Contributor

kasemir commented Jun 22, 2016

The only struct related data type that the driver handles for now is strings, see comments on STRUCT_STRING in src/etherip/types/CIPData.java.
You'll need to find documentation from Allen Bradley on the struct that you want to read & write.
Good luck.

@uthaman
Copy link
Author

uthaman commented Jun 22, 2016

Allen Bradley message type says I/O Message as the Tag Type. Is there any way to write on this tag type?

@kasemir
Copy link
Contributor

kasemir commented Jun 22, 2016

No idea. I've developed the driver based on the generic EtherNet/IP specification available from http://www.odva.org which describes the basic CIP commands, and Allen Bradley document 1756-RM005A-EN-E.pdf, "Logix5000 Data Access", which describes the CIP service codes specific to the ControlLogix 5000 series for reading and writing tags. In those documents I found no detail on structures. 1756-RM005A-EN-E.pdf only mentions that they exist. It was pure luck that the string read/write worked out.
You'll have to find somebody at Allen Bradley who can help you get details on this tag type that you want to handle.

@uthaman
Copy link
Author

uthaman commented Jun 23, 2016

Hi Kasemir, I was able to get the details on this tag type from PLC, when I read the value the CIPData type is STRUCT. But I am not ablle to write using that. Tag name is S1_ScreenId, please let me know how to write values to this tag.

image

READ OutPut
tag=S1_ScreenId, value='wjh 122', type=STRUCT, time in ms=6

@kasemir
Copy link
Contributor

kasemir commented Jun 23, 2016

Again, no idea about the STRUCT, you'll have to figure that out on your own.

What might be easier, though, is reading/writing "S1_ScreenID.DATA" as an SINT array.
With the C implementation of the driver, https://github.com/EPICSTools/ether_ip, one could simply use that as a tag name and read/write the array field of the struct that way.
In principle, the Java version should also allow that, except there's a shortcoming in the API when it comes to arrays. See #6: There's just EtherNetIP.readTag(String tag) which always gets just the first array element. We'd need EtherNetIP.readTag(String tag, int elements) to read more elements. Maybe you can fix #6 and then you should be able to read your structure field-by-field.

@uthaman
Copy link
Author

uthaman commented Jun 23, 2016

Hi, tried as per your suggestion above, NPE in decode.

CIPData value1 = plc.readTag("S1_ScreenId.DATA[0]",1);

java.lang.NullPointerException
at etherip.protocol.CIPReadDataProtocol.decode(CIPReadDataProtocol.java:56)
at etherip.protocol.MessageRouterProtocol.decode(MessageRouterProtocol.java:103)
at etherip.protocol.UnconnectedSendProtocol.decode(UnconnectedSendProtocol.java:92)
at etherip.protocol.SendRRDataProtocol.decode(SendRRDataProtocol.java:94)
at etherip.protocol.Encapsulation.decode(Encapsulation.java:190)
at etherip.protocol.Connection.read(Connection.java:142)
at etherip.protocol.Connection.execute(Connection.java:158)
at etherip.EtherNetIP.readTag(EtherNetIP.java:171)
at etherip.EtherIPDemo.testEtherIP(EtherIPDemo.java:76)

@kasemir
Copy link
Contributor

kasemir commented Jun 23, 2016

java.lang.NullPointerException at etherip.protocol.CIPReadDataProtocol.decode(CIPReadDataProtocol.java:56):

CIPReadDataProtocol has no code in line 56 that could throw an NPE, https://github.com/EPICSTools/etherip/blob/master/src/etherip/protocol/CIPReadDataProtocol.java

Look, I really can't help you with that.
If you have improvements to the code and submit a pull request, I can consider it.
But I cannot solve your struct access problem.

@uthaman
Copy link
Author

uthaman commented Jun 27, 2016

Hey kasemir, I figured out the request error and corrected it. Now i am getting the below error, do you know why PLC would send this?

Jun 27, 2016 11:03:49 AM etherip.protocol.Connection write
FINEST: Data sent (84 bytes):
0000 - 6F 00 3A 00 02 4E 02 10 00 00 00 00 46 75 6E 73 - o.:..N......Funs
0010 - 74 75 66 66 00 00 00 00 00 00 00 00 00 00 02 00 - tuff............
0020 - 00 00 00 00 B2 00 2A 00 52 02 20 06 24 01 0A F0 - ......*.R. .$...
0030 - 1B 00 4D 07 91 0B 53 31 5F 53 63 72 65 65 6E 49 - ..M...S1_ScreenI
0040 - 64 00 A0 02 CE 0F 07 00 77 6A 68 20 31 32 34 00 - d.......wjh 124.
0050 - 01 00 01 00 - ....

Jun 27, 2016 11:03:49 AM etherip.protocol.Connection read
FINEST: Data read (48 bytes):
0000 - 6F 00 18 00 02 4E 02 10 00 00 00 00 46 75 6E 73 - o....N......Funs
0010 - 74 75 66 66 00 00 00 00 00 00 00 00 00 00 02 00 - tuff............
0020 - 00 00 00 00 B2 00 08 00 D2 00 01 01 05 02 34 00 - ..............4.

java.lang.Exception: Expected CIP_WriteData_Reply (0xCD), got CM_Unconnected_Send_Reply (0xD2)

@kasemir
Copy link
Contributor

kasemir commented Jun 27, 2016

I figured out the request error and corrected it

If you found an error in the code or have a suggested addition, please consider a pull request.

Expected CIP_WriteData_Reply (0xCD), got CM_Unconnected_Send_Reply (0xD2)

I would hope that when you dump the complete protocol at a higher log level there's been an error code in there that helps to understand why the PLC didn't send a WriteDataReply to a WriteDataRequest.

@csobsidian
Copy link

@uthaman This driver was not created for handling UDT structures. It could certainly be modified to do so using Logix5000 Data Access which outlines how to use the GetInstance Attribute List Service (0x55) and the Read Template Service (0x4c) to get a list of tags and the definitions for UDTs in the processor. There are many examples on then accessing the data in these UDTs.

@kasemir
Copy link
Contributor

kasemir commented May 25, 2017

Not sure about writing, but for reading, #11 fixed the tag parsing, so "some_struct.element" as a tag name should now allow accessing an element of a structure, and as long as that element is a plain REAL, DINT, ... it should read and maybe also write it.

@andresilveira89
Copy link

Hi,
I don't have experience with java, but i know to do communication with Omron PLC using FINS Protocol.

Today, anybody has already comunication with Omron PLC using Java Ethernet/IP ?

@TheFern2
Copy link

TheFern2 commented Apr 14, 2019

Hi Kasemir, I was able to get the details on this tag type from PLC, when I read the value the CIPData type is STRUCT. But I am not ablle to write using that. Tag name is S1_ScreenId, please let me know how to write values to this tag.

image

READ OutPut
tag=S1_ScreenId, value='wjh 122', type=STRUCT, time in ms=6

Just wanted to add this for future user reference. The easiest thing to do here is, count the length of the string you want to write. Your screenshot appears to be 8, so then convert characters to ascii code, and foorloop to write one at a time. If the datatype is String then you can read without doing all this, but if is a custom string UDT you might need to read as below. Example below:

Read example:

    String stringID_LenTag = "S1_ScreenID.LEN"; // Tag for length
    CIPData tagData= plc.readTag(stringID_LenTag);  
    int tagDataIDLength = tagData.getNumber(0).intValue();  // string length
      
    StringBuilder stringSb = new StringBuilder();  
      
    for(int i = 0; i < tagDataIDLength; i++)  
    {  
      CIPData tempData = plc.readTag(String.format("S1_ScreenID.DATA[%d]", i));  
      stringSb.append(Character.toString ((char) tempData.getNumber(0).intValue()));  
    }

Write example:

    // convert your string to ascii somewhere here
    int[] stringAsciiValues = new int[]{ 72,101,108,108,111 };  
      
    // Set length of string in case is shorter or longer  
    stringID_LenData.set(0, stringAsciiValues.length);  
    plc.writeTag(stringID_LenTag, stringID_LenData);  
      
    for(int i = 0; i < stringAsciiValues.length; i++)  
    {  
      CIPData tempData = plc.readTag(String.format("S1_ScreenID.DATA[%d]", i));  
      tempData.set(0, stringAsciiValues[i]);  
      plc.writeTag(String.format("S1_ScreenID.DATA[%d]", i), tempData);  
    } 

Note that my tag name is different.
image

Hope this helps someone in the future. : )

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants