I seem to be making some progress here, but please see attached for a discrepancy that I don't understand. Supposedly the request got a 15 byte response? The response should actually be 14 bytes, as can be seen in the other screen capture. The Codesys string display also has the first character missing, and and only shows 13 characters. What is the 21262 number shown for uiLength? All this is extremely confusing.
The ODVA CIP Standard defines several encodings for strings. A CIP STRING has 2 bytes to indicate length, and then 1 byte per character. A CIP SHORT_STRING has 1 byte to indicate length and then 1 byte per character. In your screenshot this is the byte containing 0E.
So you could try changing the UINT of your STRING64 definition to a USINT, and then rename it to SHORT_STRING.
Whether to use a STRING or SHORT_STRING should be defined by your end device.
Caveat 1:
Some systems always put gaps between variables, so every variable starts on a memory address divisible by 2, 4, or 8.
Caveat 2:
Codesys strings are stroed in memory as a series of bytes followed by a terminating character, 0x00. If you were to call this code again, and this time get a string of only 3 characters (e.g. 'new'), you would end up with a string displayed in codesys like:
'new 20-24-100D'
So you need to now have a 0x00 byte at byte 4. You can do this 2 ways:
Clear the memory before you call the function, so it is all zeros. easiest way ould be to declare a
VAR CONSTANT blankSHORT_STRING : SHORT_STRING; END_VAR
and then do an assign:
ssHostnameToGet := blankSHORT_STRING;
Just write a zero after you call the function, to the index of the length.
Now you can access the individual bytes of a string, first byte is myString[0], second byte is myString[1]
so you could do:
terminateAt := MIN(63,ssHostnameToGet.usiLength);
// maybe some alarm, if ssHostnameToGet.usiLength > 63
ssHostnameToGet.sString[terminateAt] := 16#00;
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Thanks a lot for the explanation, I will give that a try. I have a related question - does the standard allow for both string data as well as binary data of different sizes, for the same class, instance and attribute? If so, how exactly are they differentiated, or would the user have to know in advance the format of the data and process the response accordingly?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Are there any practical examples of how the Ethernet/IP service function blocks are used in PLC programs? https://help.codesys.com/webapp/_cds_obj_function_block;product=codesys;version=3.5.17.0 - this says that "insert with arguments" should show the input and output arguments, but that didn't seem to be happening. The video at https://www.youtube.com/watch?v=-YcEYccH88U shows the visualization, but not the usage. I looked at https://help.codesys.com/webapp/8kboBg6ZzK46zifJPwfAWmWbaa0%2Ffld-Function-Blocks;product=EtherNetIP%20Services;version=3.5.17.0, but it was somewhat confusing. Would appreciate any help.
Please see attached for what I need, how can that be coded with the function block in CodeSys?
I seem to be making some progress here, but please see attached for a discrepancy that I don't understand. Supposedly the request got a 15 byte response? The response should actually be 14 bytes, as can be seen in the other screen capture. The Codesys string display also has the first character missing, and and only shows 13 characters. What is the 21262 number shown for uiLength? All this is extremely confusing.
The ODVA CIP Standard defines several encodings for strings. A CIP STRING has 2 bytes to indicate length, and then 1 byte per character. A CIP SHORT_STRING has 1 byte to indicate length and then 1 byte per character. In your screenshot this is the byte containing 0E.
So you could try changing the UINT of your STRING64 definition to a USINT, and then rename it to SHORT_STRING.
Whether to use a STRING or SHORT_STRING should be defined by your end device.
Caveat 1:
Some systems always put gaps between variables, so every variable starts on a memory address divisible by 2, 4, or 8.
Caveat 2:
Codesys strings are stroed in memory as a series of bytes followed by a terminating character, 0x00. If you were to call this code again, and this time get a string of only 3 characters (e.g. 'new'), you would end up with a string displayed in codesys like:
'new 20-24-100D'
So you need to now have a 0x00 byte at byte 4. You can do this 2 ways:
and then do an assign:
ssHostnameToGet := blankSHORT_STRING;
Now you can access the individual bytes of a string, first byte is myString[0], second byte is myString[1]
so you could do:
Thanks a lot for the explanation, I will give that a try. I have a related question - does the standard allow for both string data as well as binary data of different sizes, for the same class, instance and attribute? If so, how exactly are they differentiated, or would the user have to know in advance the format of the data and process the response accordingly?