Python xbee library no output for incoming frames - python

I am using 2 XBee pro S1, I want to read the packets received by the co-ordinator on my PC , it is enabled with API_2 and all other connections are done properly, I can see the packets with XCTU, I am using the python xbee library , but it gives no output :
The Code :
import serial.tools.list_ports
from xbee import XBee
import serial
ports = list(serial.tools.list_ports.comports())
for p in ports: #print the list of ports
print p
def toHex(s):
lst = []
for ch in s:
hv = hex(ord(ch)).replace('0x', '')
if len(hv) == 1:
hv = '0'+hv
hv = '0x' + hv
lst.append(hv)
def decodeReceivedFrame(data):
source_addr_long = toHex(data['source_addr_long'])
source_addr = toHex(data['source_addr'])
id = data['id']
samples = data['samples']
options = toHex(data['options'])
return [source_addr_long, source_addr, id, samples]
PORT = '/dev/ttyUSB0'
BAUD_RATE = 9600
ser = serial.Serial(PORT, BAUD_RATE)
print "Serial ports initialised...."
xbee = XBee(ser,escaped=True)
print "XBee object created"
while True:
try:
response = xbee.wait_read_frame()
sleep(0.5)
decodedData = decodeReceivedFrame(response)
print decodedData
print "data decoded"
except KeyboardInterrupt:
break
ser.close()
The port number and baudrate are connect, I change it to the appropriate portnumber every time I replug the coordinator to my PC.
My output looks like :
Serial ports initialised....
XBee object created
It stays like that and gives no output, even if I see the RX led blinking.
Below is the code written with only pyserial :
import serial
from time import sleep
port = '/dev/ttyUSB0'
baud = 9600
ser = serial.Serial(port, baud)
data = ""
while True:
try:
while ser.in_waiting:
sleep(1)
data = ser.read()
print data
except KeyboardInterrupt:
break
ser.close()
It gives the following output.
Could someone kindly help.

Are you sure you have the correct serial port and baud rate? Does the xbee package support API mode 2? It might only work with API mode 1.
Does that package have methods for accessing the raw byte stream instead of trying to read frames? Can you configure it to throw exceptions on parsing errors?
I would start with just printing response until you see that you're receiving data. And why include the sleep() call in that loop?
I'm not sure what you're trying to accomplish in toHex() but you might want to look at the Python method struct.unpack() or replace all of the work you do on hv with '0x%02X' % ord(ch).

Related

Read incorrect data from UART in BananaPi

I am using a BananaPi to read UART data coming from a device. I know for sure what is the data generated by the device, it's the same 40 byte sequence sent in a loop, I know for sure because I mesure it with an oscilloscope. The data sent looks like(on the oscilloscope): 6A000496ED47.... 6A000496ED47....
I want to read this data in the BananaPi and I write a python script that looks like:
import serial
import time
if __name__ == '__main__':
connection = serial.Serial()
connection.port = "/dev/ttyS2"
connection.baudrate = 4000000
connection.timeout = 1
try:
connection.open()
print("serial port open")
idx = 0
while(idx < 10):
data = connection.read(size=40)
newData = data.encode('hex')
print newData
idx += 1
connection.close()
except:
print("Opening serial error")
The output is:
b777fbdc63e76....
So I get different sets of 40 bytes data on every of the 10 while loops.
Any ideea what might be wrong?
The serial setup is the same as in the oscilloscope meaning the baudrate is 4000000

Python - read from the serial port data line by line into a list when available

I am aiming to write a code that will be indefinitely listening and reading from to a serial port that will have this output produced every few seconds
serial port output:
aaaa::abcd:0:0:0
//printf("%d\n",data[0]);
2387
//printf("%d\n",data[1]);
14
-9
244
-44
108
I want the data to be appended in a list like this, python supposed output
[abcd::abcd:0:0:0, 2387, 14, -9, 244, -44, 108]
I tried this code amongst many others but nothing worked, I keep on getting no output
EDIT- the code below gives me this output
'''[['abcd::', 'abcd::', 'abcd::', 'abcd::', 'abcd::']] #or
[['abcd::abcd:0:0:c9\n', '2406\n', '14\n', '-7\n']] # and so on, different output for each iteration'''
#[['aaaa::c30c:0:0:c9\n', '2462\n', '11\n', '-9\n', '242\n', '-45\n', '106\n']] apparently it worked only once.
ser = serial.Serial('/dev/ttyUSB1',115200, timeout=10)
print ser.name
while True:
data = []
data.append(ser.readlines())
print data
# further processing
# send the data somewhere else etc
print data
ser.close()
readline will keep reading data until read a terminator(new line). please try: read.
UPDATED:
use picocom -b 115200 /dev/ttyUSB0 or putty(serial model) to detect the port and baud-rate is right. I got two different ports in your two questions.if open error port, read() will keep waiting until read a byte. like this:
import serial
# windows 7
ser = serial.Serial()
ser.port = 'COM1'
ser.open()
ser.read() # COM1 has no data, read keep waiting until read one byte.
if you type this code in console, console will no output like this:
>>> import serial
>>> ser = serial.Serial()
>>> ser.port = 'COM1'
>>> ser.open()
>>> ser.read()
_
we need add timeout for read to fix it.
you can try this:
import serial
import time
z1baudrate = 115200
z1port = '/dev/ttyUSB0' # set the correct port before run it
z1serial = serial.Serial(port=z1port, baudrate=z1baudrate)
z1serial.timeout = 2 # set read timeout
# print z1serial # debug serial.
print z1serial.is_open # True for opened
if z1serial.is_open:
while True:
size = z1serial.inWaiting()
if size:
data = z1serial.read(size)
print data
else:
print 'no data'
time.sleep(1)
else:
print 'z1serial not open'
# z1serial.close() # close z1serial if z1serial is open.

Communicating with air-conditioner controller using pyserial

I am trying to the first time to send and receive information through serial port. The manual for the device with which I am trying to talk can be found here. I am trying for a start to send a set of hexadecimals to ask about the condition of the system and my purpose is to ask in real time about the temperature and store it. Until now my code is this:
import serial
import time
#import serial.tools.list_ports
#ports = list(serial.tools.list_ports.comports())
#for p in ports:
# print p
ser = serial.Serial(port= '/dev/ttyUSB0',
baudrate=9600,
parity=serial.PARITY_EVEN,
stopbits=serial.STOPBITS_ONE,
bytesize=serial.EIGHTBITS, timeout=0, xonxoff=1, rtscts=1, dsrdtr=1)
command = "\x10\xFF\x29\x2C\x16"
command = command.decode("hex")
ser.write(command)
print command
#time.sleep(10)
ReceivedData = "\n nothing"
while ser.inWaiting() > 0:
ReceivedData = ser.read()
print ReceivedData
The problem is that I cannot get any response.
EDIT:
So I solved the communication problem. It turned out I was using an extension cable so the T and R channels were not correctly connected. Now The response that I receive is "\x00\x10\xFF\x29\x2C\x16" which is the same that I put in only with a \x00 in the front. Does this mean it is an error message? How do I calculate the 4th bit? Until now I am using an example from the manual.
dont use command = command.decode("hex")
just
command = "\x10\xFF\x29\x2C\x16"
ser.write(command)
should work i am sure it expects bytes like this
to put it differently
START_BYTE = "\x10"
ADDR_BYTE = "\xff"
FN_BYTE = "\x29"
CS_BYTE = "\x2C" # We assume you have calculated this right
END_BYTE = "\x16"
msg = START_BYTE+ADDR_BYTE+FN_BYTE+CS_BYTE+END_BYTE
ser.write(msg)
you can abstract this out since start and end and address are always the same
def send_fn(ser,FN_CMD):
START_BYTE = "\x10"
ADDR_BYTE = "\xff"
END_BYTE = "\x16"
CS_BYTE = chr((ord(ADDR_BYTE) + ord(FN_CMD))&0xFF)
msg = START_BYTE+ADDR_BYTE+FN_CMD+CS_BYTE+END_BYTE
ser.write(msg)

Reading bytes with PySerial: Empty results (Java works)

I am trying to read bytes from a digital meter via PySerial. It all works with Processing/Java. But i need it to port to Raspberry Pi.
While Java receives the correct bytes, Python does not receive anything at all. The digital meter simply sends 16 bytes delimited by 13.
Working Java / Processing code (receives byte array):
import processing.serial.*;
String portName = "/dev/tty.PL2303-00001004";
myPort = new Serial(this, portName, 9600);
...
if ( myPort.available() > 0)
{
byte[] inBuffer = new byte[16];
myPort.readBytesUntil(13, inBuffer);
println("Buffer: " + inBuffer.length);
}
Not working Python code (receives nothing / ''):
import serial
import time
ser = serial.Serial('/dev/tty.PL2303-00001004', 9600, timeout=None) # tried different timeout
print(ser.isOpen())
while True:
tmp = ser.read()
print tmp
print tmp.__len__()
time.sleep(1)
Reading an Arduino Board with this Python code works fine.
Solution: ser.setDTR(1) got it working!
ser.setDTR(1) got it working! Thanks!
import serial
import time
ser = serial.Serial('/dev/tty.PL2303-00001004', 9600, timeout=None) # tried different timeout
ser.setDTR(1)
print(ser.isOpen())
while True:
tmp = ser.read()
print tmp
print tmp.__len__()
time.sleep(1)

How to read input from port and print to terminal

here's the situation:
I have two stamps, one connected to port: /dev/ttyUSB1, and one external one, unconnected. The external one has a (Contiki based) program on it to send (every 2 seconds) a single letter across to the stamp that is plugged into the computer. stamp plugged into the computer has a program, also Contiki based, which reads this information via a radio signal.
Now, I have written a python program, making use of pyserial, which aims to read the information coming into the port and display it in terminal. I know the message is arriving correctly as I can print the message from the stamp connected via USB to terminal fine. But I am having trouble reading the information from the python code.
import serial, time, threading
ser = serial.Serial()
ser.port = "/dev/ttyUSB1"
ser.baudrate = 9600
ser.bytesize = serial.SEVENBITS
ser.parity = serial.PARITY_EVEN
ser.timeout = 0.1
ser.rtscts = 1
try:
ser.open()
except Exception, e:
print "error open serial port: " + str(e)
exit()
if ser.isOpen():
try:
numOfLines = 0
while True:
print ser.read()
numOfLines = numOfLines + 1
time.sleep(2)
if (numOfLines >= 50):
break
ser.close()
except Exception, e1:
print "error communicating...: " + str(e1)
else:
print "cannot open serial port "
When run, instead of printing the expected letter sent from the stamp every couple of seconds, it will print a few consistent, yet random letters. For example:
w
z
z
w
g
z
g
z
z
z
w
z
w
There is no output from the program when I remove the USB connected to the stamp. So it must be reading something from the port... Any help would be much appreciated.
It sounds like it could be a problem with the baudrate. you didn't post the code that does this:
ser = serial.Serial('/dev/ttyUSB1', timeout=1, baudrate=9600, rtscts=1)

Categories