从 XBee 接收的 pySerial 数据未正确显示 [英] pySerial data received from XBee not properly displayed

查看:70
本文介绍了从 XBee 接收的 pySerial 数据未正确显示的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图让多个 XBee 作为传感器和输出设备运行,以将它们的样本发送到如下所示连接的协调器 XBee,并在收到指示时打开和关闭这些远程 XBee 上的东西.我的这个接收数据"问题似乎类似于堆栈溢出问题 已经表明它是错误的.另外,所有的串口参数都已经检查过了,XBee小心地在Vcc和地引脚之间去耦或过滤等.

更新,经过进一步调查,似乎问题可能与 pySerial 库有关,而不是与 python-XBee 库有关.我基于以下内容(参考我帖子前面部分列出的预期结果,以及上面列出的实际结果:

x40 = ascii @ 和x79 = ascii y 和xe6 = 在 [ASCII][7] 中似乎未定义,因此似乎像 xe6 一样通过 OK,然后最后,x5f = ascii 下划线 (_)

因此,我的理论是,由于某种原因,pySerial 停止处理 \x00\x13\x2A\x00 中最后一个 x00 之后的流/字符串(或任何正确的技术术语),然后开始添加 ASCII 字符等效改为十六进制字符/值.使用依赖于 pySerial 库 (Miniterm) 的终端程序,在 Raspberry Pi 上,我已经接收到错误的数据.这是在我的脚本之前.(作为后来发现的结果,请参阅对这篇文章的评论.)

正确接收硬件地址"对我来说很重要,因为 XBee 中的 MY 地址可以动态更改(我认为协调器会即时分配它).当向特定 XBee 模块发送特定命令时,这将是一个问题,显然考虑到非常特定的结果.我该如何解决这个问题?

解决方案

事实上@ is \x40.而y \x79.所以值"是正确的...

<预><代码>>>>'\x13\xa2\x00\x40\x79\xe6\x5f' == '\x13\xa2\x00@y\xe6_'真的

如果只是格式问题,您可以使用类似的东西来漂亮地显示您的地址:

<预><代码>>>>值 = '\x13\xa2\x00@y\xe6_'>>>Pretty_value = ':'.join("{:02X}".format(ord(c)) for c in value)>>>打印(pretty_value)13:A2:00:40:79:E6:5F

<小时>

另一方面,在我看来,您在访问地址时偏离了一个字节:

预期:\x13\xa2\x00\x40\x79\xe6\x5f实际值:\x00\x13\xa2\x00\x40\x79\xe6

一个可能的原因是您忽略了在 API 2 模式下某些字符可以转义的事实.所以改变数据帧中各个字段的实际偏移量.由于您使用的是库,您确定它可以正确处理 API 2 模式吗?它的配置是否正确?

<小时>

关于你的框架:

<前>7E 00 16 92 00 13 A2 00 40 79 E6 5FDF 13 01 01 00 40 09 00 40 02 04 0207 2E

只解码头部的第一个字段:

  • 这是一个 16 字节长的 0x92IO Sample Rx"帧.
  • 64 位源地址为 00:13:A2:00:40:79:E6:5F
  • 16 位源地址为 DF:13
  • 打包已确认 (0x01)

I am trying to get multiple XBees running as sensors and output devices to send their samples to a coordinator XBee hooked up as below and to turn things on and off on these remote XBees when instructed to. This 'received data' problem of mine seems similar to Stack Overflow question pySerial and reading binary data, but I do not consider it answered by that problem and its resolution.

So what steps will reproduce the problem?

  1. Using python-xbee (ver 2.1.0, or 2.0.0), pySerial latest version 2.6.0, Python 2.7.3 on Raspberry Pi running Debian Wheezy (7.0).

  2. Run the script below

  3. All XBees are XB24-Z7-WIT-004 Series 2. The Co-ordinator is in API2 mode. I tried my two- sensor XBee's in both AT and API1 or API2 modes without any difference (notes on the firmware version is reflected as comments in the attached .py script)

What is the expected output? What do I see instead?

I expect the address received as a result of the script, or as the output from Minicom to be the correct 'source_addr_long', namely x13\xa2\x00\x40\x79\xe6\x5f, but instead I receive \x00\x13\xa2\x00@y\xe6. The 'source_addr' returns \xe3+. (The 'source addr' related stuff is handled / done by python_XBee libraries.) Here is my script:

#!/usr/bin/env python2.7

# NOTE - Not my own code - Abrie Willemse
# NOTE - I am not a programmer - Abrie Willemse

# I am using XBee XB24-Z7 WIT-004 for all devices
# Coordinator is running API
# SENSOR_1 and SENSOR_2 are Sensor Routers running AT (firmware XB24ZB 22A7) (I have tried API firmware XB24ZB 23A7) too)

import serial
from xbee import ZigBee
import time, sys, datetime

serial_port = serial.Serial('/dev/ttyAMA0', 9600)

zb = ZigBee(serial_port)


while True:
    try:
        data = zb.wait_read_frame() #Get data for later use
        print data # To check what comes in before processing / parsing (already buggered up)
        addr = repr(data ['source_addr_long']) # Working sort of, but with @y... issue in results
        file = open('/media/log/senslog.txt','a')
        value = float(((data['samples'])[0])['adc-0'])
        num = (value * 3.0) / 1023.0
        file.write(datetime.datetime.now().strftime('%d-%m-%Y %H:%M:%S') + ' ' + str(addr) + ' ' + str(value) + ' ' + str(num) + '\n')
        print str(datetime.datetime.now().strftime('%d-%m-%Y %H:%M:%S') + ' ' + str(addr) + ' ' + str(value) + ' ' + str(num) + '\n')
        file.close()

    except KeyboardInterrupt:
        break

serial_port.close()

This is the output:

{'source_addr_long': '\x00\x13\xa2\x00@y\xe6_', 'source_addr': '\xe3+', 'id': 'rx_io_data_long_addr', 'samples': [{'adc-0': 516, 'adc-3': 519, 'dio-6': False}], 'options': '\x01'}
18-06-2013 14:32:15 '\x00\x13\xa2\x00@y\xe6_' 516.0 1.51319648094

Note the problem starting at the @y above in the output. Note the correct data received, when I connect that very same co-ordinator to a Windows PC (this is the entire packet received from a remote XBee):

What versions am I using? On what operating system?

Using python-xbee (ver 2.1.0, or 2.0.0), PySerial latest version 2.6.0, Python 2.7.3 on Raspberry Pi Model B running Debian Wheezy (7.0) (upgraded to the latest version recently, in an attempt to address this matter.

Notes:

When I use ZigBee Operator software (Windows based, via an old-fashioned COM port), the addresses and entire messages are sent and received properly. Finally, it is quite possible that nothing is wrong with pySerial, I might just be buggering it up in code, although that does not explain why Miniterm already shows it wrong. Also, all serial port parameters have been checked, the XBee carefully decoupled or filtered between Vcc and ground pins, etc.

UPDATE, following further investigation, it would appear that if anything, the problem is possibly related to the pySerial library, and not with the python-XBee libraries. I base that on the following (referring to the expected results listed in the earlier part of my post, as well as the actual results, also listed above:

x40 = ascii @ and
x79 = ascii y and
xe6 = seems undefined in [ASCII][7], therefore seems to be coming through OK as xe6 and then finally,
x5f = ascii underscore (_)

Therefore, my theory is that for some reason, pySerial stops treating the stream / string (or whatever the correct technical term is) following the last x00 in \x00\x13\x2A\x00 and then start adding the ASCII characters equivelant to the hex characters / values instead. Using a terminal program which is reliant on the pySerial library (Miniterm), on the Raspberry Pi, I already receive the data wrong. This is before my script. (See comment to this post as the result of later discovery.)

It is important for me to receive the 'hardware address' correctly, since the MY address in XBee can change dynamically (I think the coordinator assigns it on the fly). This would be a problem when sending specific commands to a specific XBee module, obviously with a very specific outcome in mind. How can I fix this problem?

解决方案

As a matter of fact @ is \x40. And y is \x79. So the "values" are correct...

>>> '\x13\xa2\x00\x40\x79\xe6\x5f' == '\x13\xa2\x00@y\xe6_'
True

If it is only a matter of formatting, you could use something like that to pretty display your addresses:

>>> value = '\x13\xa2\x00@y\xe6_'

>>> pretty_value = ':'.join("{:02X}".format(ord(c)) for c in value)
>>> print(pretty_value)
13:A2:00:40:79:E6:5F


On the other hand, it seems to me that you are off by one byte while accessing the address:

Expected:         \x13\xa2\x00\x40\x79\xe6\x5f
Actual value: \x00\x13\xa2\x00\x40\x79\xe6

One possible reason is that you missed tha fact that in API 2 mode some characters could be escaped. So changing the actual offset of the various fields in the data frame. Since you are using a library, are you sure it handle properly API 2 mode? Is it correctly configured to do so?


Concerning your frame:

7E 00 16 92 00 13 A2 00 40 79 E6 5F
DF 13 01 01 00 40 09 00 40 02 04 02
07 2E

Just decoding the first fields fields of the header:

  • This is a 0x92 "IO Sample Rx" frame of 16 bytes long.
  • The source address 64 bits is 00:13:A2:00:40:79:E6:5F
  • The source address 16 bits is DF:13
  • The packed was acknowledged (0x01)

这篇关于从 XBee 接收的 pySerial 数据未正确显示的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆