String Format byte order

I have a string array in Omron NJ memory that is bound to CJ memory type “D” and manipulated by a vijeo designer HMI to display a recipe name. This is edited by the HMI and stored in the PLC array for manipulation. I am trying to replicate the HMI function in Ignition to allow editing the string text .
The data is string characters are displaying byte swapped where " Recipe 123" is displaying as “eRicep1 32”
How do I swap each pair of characters to read/write correctly?

I would use a derived tag, with a character-swapping runScript() expression in both directions.

Thanks, I was hoping there was an automatic function for this. I’ll need to practice my script writing, Cheers

Just so you don’t scratch your head for too long on this:

s = "eRicep1 32"
s = ''.join(c for pair in zip(s[1::2], s[::2]) for c in pair)

s[1::2] and s[::2] will produce strings with even or odd characters ([1::2] = start from 1, stop at the end, step 2),
zip will take one character from each,
then it’s simply a matter of putting things in the right order.
So, with "eRicep1 32", s[1::2] will be "Rcp 2" and s[::2] "eie13"
zip("Rcp 2", "eie13") produces the pairs [('R', 'e'), ('c', 'i'), ('p', 'e'), (' ', '1'), ('2', '3')]
and iterating through those pairs and picking single extracts them from the tuples to produce the list ['R', 'e', 'c', 'i', 'p', 'e', ' ', '1', '2', '3']
All that’s left to do is join them on nothing with ''.join()

There might be libraries with builtins for this, but, well…

1 Like

Thanks Pascal,

Managed to script a solution which works fine. See below

Script

Swap

def ByteSwap(text): ## Swap each pair of characters to match byte order of string characters

result ="" #clear result

if (len(text)%2) ==1: # test if odd number of bytes

text=text+" " #Add extra character

for x in range (1,len(text),2): #loop through each second byte of entire string

result = result+(text) #add second character

result =result+(text[x-1]) #add first character

return result #output final concatenated byte swapped string

Derived Tag Read expression

runScript(“Swap.ByteSwap”,0,{source})

Derived Tag Write expression

runScript(“Swap.ByteSwap”,0,{value})

Thanks

Paul Reynolds

Electrotech Controls Ltd

Automation & Controls Manager

P 06 835 2260 F 06 835 2253 M 021 431 153 E paul@electrotech.co.nz W www.techgroup.co.nz

12 Sheffield Place, PO Box 3016, Napier 4142, New Zealand

image001.jpg

A member of the Tech Group of Companies Ltd

image002.jpg

Thanks Pascal,
Managed to script a solution which works fine. See below

Script
Swap

def ByteSwap(text):                                                      ## Swap each pair of characters to match byte order of string characters

               result =""                                                          #clear result
               if (len(text)%2) ==1:                                   # test if odd number of bytes
                              text=text+" "                                #Add extra character
               for x in range (1,len(text),2):                      #loop through each second byte of entire string
                              result = result+(text[x])                #add second character
                              result =result+(text[x-1])              #add first character
               return result                                                #output final concatenated byte swapped string

Derived Tag Read expression
runScript("Swap.ByteSwap",0,{source})

Derived Tag Write expression
runScript("Swap.ByteSwap",0,{value})

Cheers

It’s a good thing you found a solution by yourself, but I’d suggest you use the snippet I posted above.
It’s a more pythonic way of doing things, using very pythonic things (zip, generators, comprehensions…)

def swap_bytes(s):
    return ''.join(c for pair in zip(s[1::2], s[::2]) for c in pair)

If it’s a bit too obscure as it is, I’ll deconstruct and explain it in more details.

On the other hand, there is the struct library that could allow you to do this, but frankly I’m not familiar with it and couldn’t help figure out how to use it.