Examples of getAttributeSingle and setAttributeSingle in PLC programs

nlsri
2022-02-23
2022-02-25
  • nlsri - 2022-02-24

    Please see attached for what I need, how can that be coded with the function block in CodeSys?

     
  • nlsri - 2022-02-24

    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.

     
    • i-campbell

      i-campbell - 2022-02-25

      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:

      1. 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;
      
      1. 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;
      
       
  • nlsri - 2022-02-25

    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?

     

Log in to post a comment.