Fixing escaped characters python-xbee

P

pabloblo85

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...
 
M

MRAB

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]
 
P

Peter Otten

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]
 
D

Dennis Lee Bieber

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.
 
P

pabloblo85

the following in gmane.comp.python.general:






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




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!
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,766
Messages
2,569,569
Members
45,042
Latest member
icassiem

Latest Threads

Top