Dissect string into individual hex bytes

Hi folks, what I thought would be easy is not turning out to be as such.

I'm reading a string from another device via OPC. The string follows;

image

It's a ten byte string filled with hex data. I'd like to take the string on the Ignition side and break each byte into it's Hex values utilizing expression tags.

I thought that expression tags would work , because I could write a script to separate the specific byte from the string....and to have the tag available for other means to check/change data depending on production events.

So depending on events I would change the hex (byte) values and then re assemble the original string to make it available to my other control device from which the string originally came from.

Below are my tag examples Pblock being the string (of hex bytes) and Pblock_0 through PBlock_9 of the desired individual expression tag (bytes).

image

Also this is an example of the byte expression tags.

With what I thought I could use would be the Substring command as such, taking the first byte starting at position 0 for a length of 1...for the entire ten bytes of the string

image

But not having much luck with that....

I apologize if I missed a topic that may have covered this...there are a lot of entries for strings and string manipulation but not one that I've tried work. I'm also having some issues with Python script integration, and perhaps this is what I need.

I appreciate your time (in advance) thank you for your help.

If you want raw bytes, I would avoid any string related operations.
What driver are you using to retrieve the raw value?

1 Like

I'm talking to an Opto-22 device, one of their newer PLCs, and on the ignition side I'm using the OPC UA Server to do so. The Opto side is broken down into strings/bytes, and I thought that I would match what their doing, and pull the string in then pull it apart and convert it to what I need, then send the string back updated.

The problem is that if you start trying to deal with strings, suddenly you're adding encoding problems to the mix. Sticking to bytes (perhaps treating the top-level tag as a byte array? That might "just work") is going to be a lot easier to keep consistent.

The Substring command in the script seems to be doing exactly what I want it to do, grabbing X amount of characters at a time out of the string (tag), but I get the error " Error_TypeConversion("Error trying to coerce to a number" . I'm assuming this error is coming from the software wanting to display the tag contents (value) within the tag browser.

I've played with Format String (under) Numeric Properties within the tag properties without much success.

As Paul said, the top level tag should probably be a byte array instead. Accessing items in an array should be very easy. And would probably avoid a whole nest of type conversion errors.

Where ?

Yeah you have to be careful with strings, see this?
image
image

This means you are already haveing encodign problems, and this will cause your values to change if you are not careful.
If you want the bites as data, send it as bites.

Thank you for your replies,

True I'd love to have the abilities to send/receive in bytes...but I do not. The only thing I have is to receive the data from another controller in a string format. My focus now is to dissect the received string into bytes....and that's my problem.

I just found out yesterday that expression tags do not allow a use of a Python script...I'm limited to using it's own 'expression tools/language/functions', and that's where the problem lies. I have not figured out how to pull this string apart, with the tools given...

Questions;

I want to use Python, is there any other tag or memory variable that I could do so instead of the Expression tag to get away from the limited programmability? Or am I just not using the Expression tag correctly?

Once on the Python track, what script would get me started to pull the string apart, placing the byte data into (memory locations, variables, tags) that would be available to all aspects of Ignition functions...

Phew...seemingly simple and ultimately trying to do is from operators HMI selections, set the byte data to his/her selections, join the bytes back together into a string then send the string back to the controller.

Kinda weird that this other controller sends bytes as strings xd
You an run python scripts in expressions like this
https://docs.inductiveautomation.com/display/DOC81/runScript

If I may be so bold, which one?

Or, what happens if you set the data type of PBlock to Long (Int8)?

1 Like

Sure, its the Opto22 Groov-Epic-PR1.

If I change the data type to anything other than string, I'll get an ' Error trying to coerce 'string value' to a number

I've not had a chance to use one yet, but those are Codesys under the hood, right?

If so, you may need to either change the data type on the groov, or do a bitwise copy to a long, or to an array, or something similar.

Being stuck to a String is not doing you any favors, I'm afraid.

Thanks, its not the PLC that is causing the problems, its the machine that it is connected to where the string originates. We are in the process of updating controller/HMI hardware and software on an older (1980's) machine

If you end up using python, bytes() can help.

s = "FooBar"

b = bytes(s, 'utf8')

for c in b:
    print c, type(c)

first_byte = b[0]

b.hex()

there's also bytearray()

Thank you for the Runscript information, this is exactly what I was looking for, and had no idea that it existed!

Also, Pascal, thank you for the Python example, this will get me going to provide a Python solution.

I appreciate everyone's help and ideas...