Incomplete data from xbee series 2 in python

Hi all, I am working with a pair of Series 2 Xbees and python. I can send data and turn my led off and on no problem, but when i go to read the response back the data comes back always missing the start byte and missing some of the end. I ran the same packet in x-ctu to compare the differences in the data that python is seeing to verify this. Any pointers or help is greatly appreciated.

Python script

import serial
import serial.tools.list_ports as getPorts


# Get list of ports available

portList = (getPorts.comports())
portNumber = 0
for item in portList:
	print (portNumber,' <---> ', item[0])
	portNumber = portNumber + 1
	


usePort = input('Enter device port: ')


ser = (serial.Serial(usePort,9600,timeout=2, rtscts=True, dsrdtr=True))
ledOff = bytes ([0x7e, 0x00, 0x10, 0x17, 0x05, 0x00, 0x13, 0xA2, 0x00, 0x40, 0x8a, 0xda, 0x38, 0xff, 0xfe, 0x02, 0x44, 0x32, 0x04, 0xd9])
ledOn = bytes ([0x7e, 0x00, 0x10, 0x17, 0x05, 0x00, 0x13, 0xA2, 0x00, 0x40, 0x8a, 0xda, 0x38, 0xff, 0xfe, 0x02, 0x44, 0x32, 0x05, 0xd8])

option = input('Turn Led off or on? : ')
if option == ('on'):
	print ('Turn on')
	ser.write(ledOn)
	incoming = ser.readline()
elif option == ('off'):
	print ('Turn off')
	ser.write(ledOff)
	incoming = ser.readline()
else:
	print ('invalid')
	incoming = ('no data received')
print (incoming)
ser.close()

Results of Python script

0  <--->  /dev/tty.Bluetooth-PDA-Sync
1  <--->  /dev/tty.Bluetooth-Modem
2  <--->  /dev/tty.usbserial-A501D90P
Enter device port: /dev/tty.usbserial-A501D90P
Turn Led off or on? : off
Turn off
b'~\x00\x0f\x97\x05\x00\x13\xa2\x00@\x8a\xda8\x15\rD2\x00:'

start with C or C++.

I have used the following python code to read data from an XBee:

n = ser.inWaiting()

if n > 0:

d = ord(ser.read())

print d

The ser.readline() doesn’t work the way the think.

Read this:

http://pyserial.sourceforge.net/shortintro.html

readline sounds text-oriented.

Whereas the LED on/off look like the XBee is in the binary API mode (non-textual)

Thanks all for the input. Waltr, i tried your example and the results were the same unfortunately.

stevech, sending the led on/off does have the desired effect of turning the led on or off on the remote xbee, it just seems like pyserial is chopping the first few bytes and last few bytes which make it impossible to verify the data coming back.

I am gonna have a look at working with c again, its been a while :wink:

Could it be that the Xbee is sending without the PC having the Serial (comm) port open and ready?

Try starting the Python script before turning on the XBee.

When I open the serial port I only specify the COM# and the baud rate. All other parameters I leave as the defaults.

Try that and see.

What are the two platforms hosting Python?

Please describe how the XBee 3.3V serial data is interfaced to the two Python-capable computers. And the common GND for the XBee and computer.

I can’t help too much with Series 2- these are ZIgBee devices, whereas Series 1 are universal non-ZIgBee.

Hi cschwemin,

I am having the same issues receiving data in Python. I have wasted weeks of my life (and still am) trying to get this working properly, especially since I need the 64 bit address properly received. See: http://stackoverflow.com/questions/1724 … -displayed

All XBees are XB24-Z7-WIT-004 Series 2. The Co-ordinator is in API2 mode (I also tried API1). I tried my two sensor XBee’s in both AT and API1 or API2 modes with no difference. I receive data without any issues (and my sample data (DIO and ADC comes through beautifully), but the escape codes seems to mess around things with the ‘source_addr_long’ and ‘source_addr’. I have narrowed it down to the pyserial library handling / not handling the data properly. For instance, I expext this: x13\xa2\x00\x40\x79\xe6\x5f, but instead I receive \x00\x13\xa2\x00@y\xe6_

now, x40 = @, x79 = y, etc. so you can see where the problem comes in. I need to get this to work on the Raspberry Pi, where my co-ordinator is located, so I seem pretty stuck with the libraries that is available to Python. I have not yet tried to turn on anything on my remote XBees, since it is important for me to sort the ‘address’ issue. In my final project there will be many remote XBees sensing things, and turning things on and off, and using the MY address which is not really fixed, feel I cannot rely on it for addressing. The final system will need to be robust, since I might be too far from the implemented solution to offer support.

Did you get your problem sorted, or did you just go with C?

I am not a programmer, so I am really battling along.

Warm Regards,

Abrie

What is output from the “print data” statement after the zb.wait_read_frame()?

This should be the straight hex values of the packet.

This line is not doing what you expect and is mis-interpreting the API values as ESC sequences.

addr= repr(data [‘source_addr_long’])

I attached the Python files I use to read/write XBee ZigBee API packets (change the extension to .py to use. the forum does not allow an attachment with a .py ext).

In the xbee_api Class is the unpackMsg process that is the workhouse to decode a packet.

And then the over-riden onData process for ‘printing’ the data and writing to a file.

What is output from the “print data” statement after the zb.wait_read_frame()?

This should be the straight hex values of the packet.

No, it’s not. It is already “processed” by the pyserial lib and then the XBee lib (This is the output from ‘print data’:

{'source_addr_long': '\x00\x13\xa2\x00@y\xe6_', 'source_addr': "'W", 'id': 'rx_io_data_long_addr', 'samples': [{'adc-0': 515}], 'options': '\x01'}

If I use pyserial’s miniterm terminal, it already shows ‘misinterpreted’ API for ESC, but in the miniterm I can force a ‘debug level 3’ which then performs a hex dump (without any formatting or delimiting, but at least not mixing API and ESC). That’s why I think if the pyserial lib had the same parameter options for it’s output, I would have been OK, and the XBee lib would then return straight hex.

I will check your attached scripts as soon as I can.

Thanks for your help.

Actually, zb.wait_read_frame() probably does more than just receive data bytes from pyserial. Do you have the source code for that function to see what it really does? Is there any settings to use/not use ESC sequences in that function?

In the code I posted it does a serial.read() which obtains the raw data bytes from the serial COM port’s buffer. This does not change or interpret any byte received.

res=self.ser.read()

#header found

if ord(res)==0x7e:

The ord() function does data type conversion. Read and play with this to learn how it works.

Be aware of how data can be represented, raw data value verse displayed values. This can be confusing in assembler and C but seems even harder in Python. Try writing values to a file then use a binary/hex viewer to see what the real values are to learn about how Python handles conversions.

I’m not even close to being an expert in Python but can muddle along to get it working. So hope some of this is helpful.

@waltr

Thanks a lot for the help, I will read up on this some more. I made some headway by realising that it is (like you said) the way in which the data is displayed.