Fixing escaped characters python-xbee

Discussion in 'Python' started by pabloblo85@gmail.com, Apr 24, 2013.

  1. Guest

    I am using a XBee to receive data from an arduino network.

    But they have AP=2 which means escaped characters are used when a 11 or 13 appears (and some more...)

    When this occurs, XBee sends 7D and inmediatly XOR operation with char and 0x20.

    I am trying to recover the original character in python but I don't know ho to do it.

    I tried something like this:

    read = ser.read(4) #Read 4 chars from serial port
    for x in range (0,4):
    if(toHex(read[x]) != '7d'): #toHex converts it to hexadecimal just for checking purposes
    if(x < 3):
    read[x] = logical_xor(read[x+1], 20) #XOR
    for y in range (x+1,3):
    read[y] = read[y+1]
    read[3] = ser.read()
    else:
    read[x] = logical_xor(ser.read(), 20) #XOR

    data = struct.unpack('<f', read)[0]

    logical_xor is:

    def logical_xor(str1, str2):
    return bool(str1) ^ bool(str2)

    I check if 7D character is in the first 3 chars read, I use the next char to convert it, if it is the 4th, I read another one.

    But I read in python strings are inmutables and I can't change their value once they have one.

    What would you do in this case? I started some days ago with python and I don't know how to solve this kind of things...
    , Apr 24, 2013
    #1
    1. Advertising

  2. MRAB Guest

    On 24/04/2013 08:33, wrote:
    > I am using a XBee to receive data from an arduino network.
    >
    > But they have AP=2 which means escaped characters are used when a 11 or 13 appears (and some more...)
    >
    > When this occurs, XBee sends 7D and inmediatly XOR operation with char and 0x20.
    >
    > I am trying to recover the original character in python but I don't know ho to do it.
    >
    > I tried something like this:
    >
    > read = ser.read(4) #Read 4 chars from serial port
    > for x in range (0,4):
    > if(toHex(read[x]) != '7d'): #toHex converts it to hexadecimal just for checking purposes
    > if(x < 3):
    > read[x] = logical_xor(read[x+1], 20) #XOR
    > for y in range (x+1,3):
    > read[y] = read[y+1]
    > read[3] = ser.read()
    > else:
    > read[x] = logical_xor(ser.read(), 20) #XOR
    >
    > data = struct.unpack('<f', read)[0]
    >
    > logical_xor is:
    >
    > def logical_xor(str1, str2):
    > return bool(str1) ^ bool(str2)
    >
    > I check if 7D character is in the first 3 chars read, I use the next char to convert it, if it is the 4th, I read another one.
    >
    > But I read in python strings are inmutables and I can't change their value once they have one.
    >
    > What would you do in this case? I started some days ago with python and I don't know how to solve this kind of things...
    >

    You could try converting to a list, which is mutable.

    # Python 3
    read = list(ser.read(4))

    pos = 0
    try:
    while True:
    pos = read.index(0x7D, pos)
    del read[pos]
    read.extend(ser.read())
    read[pos] ^= 0x20
    except ValueError:
    # There are no (more) 0x7D in the data.
    pass

    data = struct.unpack('<f', bytes(read))[0]


    # Python 2
    read = [ord(c) for c in ser.read(4)]

    pos = 0
    try:
    while True:
    pos = read.index(0x7D, pos)
    del read[pos]
    read.append(ord(ser.read()))
    read[pos] ^= 0x20
    except ValueError:
    # There are no (more) 0x7D in the data.
    pass

    data = struct.unpack('<f', b"".join(chr(c) for c in read))[0]
    MRAB, Apr 24, 2013
    #2
    1. Advertising

  3. Peter Otten Guest

    wrote:

    > I am using a XBee to receive data from an arduino network.
    >
    > But they have AP=2 which means escaped characters are used when a 11 or 13
    > appears (and some more...)
    >
    > When this occurs, XBee sends 7D and inmediatly XOR operation with char and
    > 0x20.
    >
    > I am trying to recover the original character in python but I don't know
    > ho to do it.
    >
    > I tried something like this:
    >
    > read = ser.read(4) #Read 4 chars from serial port
    > for x in range (0,4):
    > if(toHex(read[x]) != '7d'): #toHex converts it to hexadecimal just for
    > checking purposes if(x < 3):
    > read[x] = logical_xor(read[x+1], 20) #XOR
    > for y in range (x+1,3):
    > read[y] = read[y+1]
    > read[3] = ser.read()
    > else:
    > read[x] = logical_xor(ser.read(), 20) #XOR
    >
    > data = struct.unpack('<f', read)[0]
    >
    > logical_xor is:
    >
    > def logical_xor(str1, str2):
    > return bool(str1) ^ bool(str2)
    >
    > I check if 7D character is in the first 3 chars read, I use the next char
    > to convert it, if it is the 4th, I read another one.
    >
    > But I read in python strings are inmutables and I can't change their value
    > once they have one.
    >
    > What would you do in this case? I started some days ago with python and I
    > don't know how to solve this kind of things...


    As you cannot change the old string you have to compose a new one. I think
    the simplest approach is to always read one byte, and if it's the escape
    marker read another one and decode it. The decoded bytes/chars are then
    stored in a list and finally joined:

    # Python 2
    # untested
    def read_nbytes(ser, n):
    accu = []
    for i in xrange(n):
    b = ser.read(1)
    if b == "\x7d":
    b = chr(ord(ser.read(1)) ^ 0x20)
    accu.append(b)
    return "".join(accu)

    b = read_nbytes(ser, 4)
    data = struct.unpack('<f', b)[0]
    Peter Otten, Apr 24, 2013
    #3
  4. On Wed, 24 Apr 2013 00:33:30 -0700 (PDT), declaimed
    the following in gmane.comp.python.general:

    > I am using a XBee to receive data from an arduino network.
    >
    > But they have AP=2 which means escaped characters are used when a 11 or 13 appears (and some more...)
    >
    > When this occurs, XBee sends 7D and inmediatly XOR operation with char and 0x20.
    >
    > I am trying to recover the original character in python but I don't know ho to do it.
    >
    > I tried something like this:
    >
    > read = ser.read(4) #Read 4 chars from serial port


    Why read 4 at a time if you need to detect the escape marker...

    PSEUDO_CODE -- UNTESTED:

    for c in ser.read(): #presumes it will function as an iterator
    if ord(c) == 0x7D:
    c =chr(ord(ser.read(1)) ^ 0x20)
    #do something with c (save to a list for later joining as a
    string?)
    #probably need some condition to exit the read loop too
    > def logical_xor(str1, str2):
    > return bool(str1) ^ bool(str2)
    >

    bool() returns True or False based on the argument... Any non-empty
    string will be True. Instead what you want is to x-or the bits of the
    character itself.
    --
    Wulfraed Dennis Lee Bieber AF6VN
    HTTP://wlfraed.home.netcom.com/
    Dennis Lee Bieber, Apr 25, 2013
    #4
  5. Guest


    >
    > the following in gmane.comp.python.general:
    >
    >
    >
    > > I am using a XBee to receive data from an arduino network.

    >
    > >

    >
    > > But they have AP=2 which means escaped characters are used when a 11 or 13 appears (and some more...)

    >
    > >

    >
    > > When this occurs, XBee sends 7D and inmediatly XOR operation with char and 0x20.

    >
    > >

    >
    > > I am trying to recover the original character in python but I don't know ho to do it.

    >
    > >

    >
    > > I tried something like this:

    >
    > >

    >
    > > read = ser.read(4) #Read 4 chars from serial port

    >
    >
    >
    > Why read 4 at a time if you need to detect the escape marker...
    >
    >
    >
    > PSEUDO_CODE -- UNTESTED:
    >
    >
    >
    > for c in ser.read(): #presumes it will function as an iterator
    >
    > if ord(c) == 0x7D:
    >
    > c =chr(ord(ser.read(1)) ^ 0x20)
    >
    > #do something with c (save to a list for later joining as a
    >
    > string?)
    >
    > #probably need some condition to exit the read loop too
    >
    > > def logical_xor(str1, str2):

    >
    > > return bool(str1) ^ bool(str2)

    >
    > >

    >
    > bool() returns True or False based on the argument... Any non-empty
    >
    > string will be True. Instead what you want is to x-or the bits of the
    >
    > character itself.
    >
    > --


    It works! Thank you so much. Now I can go ahead with my work!
    , Apr 26, 2013
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    2
    Views:
    759
  2. Ben Finney
    Replies:
    2
    Views:
    338
    Josiah Carlson
    Apr 3, 2004
  3. Henrik S. Hansen

    Translating escaped characters

    Henrik S. Hansen, Nov 1, 2004, in forum: Python
    Replies:
    2
    Views:
    287
    Henrik S. Hansen
    Nov 2, 2004
  4. Derek Basch
    Replies:
    2
    Views:
    455
    Derek Basch
    Mar 25, 2005
  5. Thea
    Replies:
    2
    Views:
    621
Loading...

Share This Page