cmseaton42 / node-ethernet-ip

A Lightweight Ethernet/IP API written to interface with Rockwell ControlLogix/CompactLogix Controllers.
MIT License
265 stars 106 forks source link

String Tags in Compact Logix / Control Logix #92

Open anandanatarajan opened 3 years ago

anandanatarajan commented 3 years ago

Hi, how to read and write string values to AB Compact /Control Logix it seems types does not have a string datatype

radrevere commented 11 months ago

I haven't seen activity for the project for 4 years at this point so I decided to implement the LGX string type on my own. For anyone interested following is my solution:

  1. In the cip data-types add the following data type to the array: LGXSTR: 0x2a0

  2. Next go to parseReadMessageResponseValueForAtomic and add LGXSTR to the types: const { SINT, INT, DINT, REAL, BOOL, LGXSTR } = Types;

  3. Then add the case for it in the switch statement:

    case LGXSTR: // struct for string
                var len = data.readUInt32LE(4);
                this.controller_value = "";
                for(var i = 0; i < len; i++)
                {
                    // LGX string header = 8 bytes 
                    this.controller_value += String.fromCharCode(data[8+i]);
                }
                break;

    There may be a better way to convert the bytes to string so feel free to modify as needed. If you create custom string lengths then you will may need to modify this in order to accomodate the size.

  4. find generateWriteMessageRequestForAtomic and add LGXSTRZ to the types: const { SINT, INT, DINT, REAL, BOOL, LGXSTR } = Types;

  5. Finally add the following case to the switch statement:

    case LGXSTR: // LGX string
                // override size with struct handle in header
                buf.writeUint16LE(0x0FCE,2);
    
                // string struct is a total of 90 by default
                var header = Buffer.alloc(6);
                header.writeInt16LE(1); // writing only one string
                header.writeInt32LE(tag.value.length,2); // length of string
                valBuf = Buffer.alloc(84); // standard string length
                valBuf.write(tag.value);
    
                buf = Buffer.concat([buf,header,valBuf]);
                break;

    Again, if you use strings that are not the default size you may need to make changes in order to accommodate it. We never use anything but the default size at work and so I have no need to accommodate anything else.