2017-02-19 99 views
1

我做了一个由3个Zigbee,2个路由器(Zigbee S2C's)和1个协调器(Zigbee S2)组成的设置。每个路由器都连接到从2个FSR和一个IMU(帧类型:zigbee传输请求和包大小为46字节)收集数据的arduino nano,并将其发送给连接到arduino UNO的协调器。所有的Xbe都处于API模式2并且工作在115200的波特率。我正在使用名为“Simple Zigbee Library”的库将所有收集的数据发送给协调器。数据的收集和发送工作正常,除了有丢包的情况。纳米的采样数据在25Hz左右的频率独立。协调员试图在每个循环中读取Zigbees发送的数据(当然使用库),但不幸的是,它似乎只能接收大约40-45个样本(应该是25 * 2 =从2 xbees)。有人可以提出为什么会发生这种情况。我需要尽可能少的数据丢失,以便我的设置实现其动机。任何形式的帮助表示赞赏。为什么Zigbee arduino设置中的数据包丢失?

P.S:可能很重要的一点是协调器只从每个循环中的一个xbee读取数据。

As can be seen under the "Source" heading of this image of data received by the coordinator, "19" and "106" are the addresses of the routers and there are data packets dropped intermittently

谢谢。

void setup() 
{ 
    // Start the serial ports ... 
    Serial.begin(115200); 
    while(!Serial){;} // Wait for serial port (for Leonardo only). 
    xbeeSerial.begin(115200); 
    // ... and set the serial port for the XBee radio. 
    xbee.setSerial(xbeeSerial); 
    // Set a non-zero frame id to receive Status packets. 
    xbee.setAcknowledgement(true); 
} 
void loop() 
{ 
    // While data is waiting in the XBee serial port ... 
    while(xbee.available()) 
    { 
     // ... read the data. 
     xbee.read(); 
     // If a complete message is available, display the contents 
     if(xbee.isComplete()){ 
      Serial.print("\nIncoming Message: "); 
      printPacket(xbee.getIncomingPacketObject()); 
     } 
    } 
    delay(10); // Small delay for stability 
    // That's it! The coordinator is ready to go. 
} 
// Function for printing the complete contents of a packet // 
void printPacket(SimpleZigBeePacket & p) 
{ 
    //Serial.print(START, HEX); 
    //Serial.print(' '); 
    //Serial.print(p.getLengthMSB(), HEX); 
    //Serial.print(' '); 
    //Serial.print(p.getLengthLSB(), HEX); 
    //Serial.print(' '); 
    // Frame Type and Frame ID are stored in Frame Data 
    uint8_t checksum = 0; 
    for(int i=10; i<p.getFrameLength(); i++){ 
     Serial.print(p.getFrameData(i), HEX); 
     Serial.print(' '); 
     checksum += p.getFrameData(i); 
    } 
    // Calculate checksum based on summation of frame bytes 
    checksum = 0xff - checksum; 
    Serial.print(checksum, HEX); 
    Serial.println(); 
} 
+0

你认为*包冲突*和*数据损坏*?通信协议是否足够先进以处理这些情况? –

+0

该链接指出:这些模块使用的无线电(MAC和PHY层)由IEEE 802.15.4标准定义,该标准规定了使用具有冲突避免的载波侦听多路访问或缩写为CSMA/CA.htm: /电子学.stackexchange.com/questions/36932/xbee-how-does-it-deal-with-collisions – Aniket

+0

好极了,但我想到的是比这更高的水平。* CSMA/CA *在合适的情况下可以并最终不会阻止*冲突*,尽管拥有它肯定会更好。 *更高级别的协议*应该要求每个数据包被确认*,并且如果在给定的*超时*内没有收到* ACK *,则强制再次发送数据包。上次我和* ZigBee *一起工作时,虽然我承认我没有使用Arduino *,但我必须自己实现这一点。 –

回答

0

虽然声称使用115,200bps,贴代码显示在9600波特打开串行端口,绝对速度不够快2500个字节/秒(50个分组/秒* 45个字节/分组* 110%为开销)从XBee收到并倾销printPacket())。请记住,802.15.4总是250kbps无线传输,而XBee模块的串行端口配置仅用于与主机进行本地通信。

确保您的路由器正在发送单播(而不是广播)数据包以保持无线电流量。

您应该在诊断协调器上的代码之前验证发送是否正在运行。更新路由器上的代码,以查看是否为每个发送的数据包获得了成功的传输状态数据包。瞄准50Hz似乎有点多 - 你想每20ms发送45个字节(就是API帧的全部大小?)。

您是否在Arduino上使用XBee模块和Serial.print()的硬件串行端口?每次拨打printPacket()需要多少时间?如果您将printPacket()中的代码减少到最小值(发送者地址的最后一个字节和1个字节的帧ID),您是否看到所有数据包都已通过(表明您花费了太多时间来转储数据包)。

+0

感谢您回复@tomlogic我对所有三个arduino的波特率都是115200。示例代码中的错误已被纠正。发送正在工作,因为我得到了两个路由器的确认消息。但有些数据包没有得到确认。在10个数据包中大约有2个(在两个xbees中)。 50赫兹不是强制性的,但对我来说越高越好。我在所有3个xbees上使用软件序列。即使当我将printPacket中的代码减少到最低限度时,所有的数据包都不会通过。 – Aniket

+0

您仍然在打印大量关于每个收到的数据包的信息(100个字符* 50条消息=最大115.2kbps的50kbps) - 将其减少到几个字节进行测试。你可能花了很多时间打印你落后的数据包。 Arduino上的串行缓冲区有多大?你可以使用硬件握手(CTS/RTS)来防止缓冲区溢出吗? – tomlogic

+0

我将代码调低至必要的最小数据量(8字节)。 Arduino的串行缓冲区大小为64bytes。我尝试使用http://www.hobbytronics.co.uk/arduino-serial-buffer-size中显示的方法增加UNO的缓冲区大小,但仍然丢失数据字节。关于还有什么可以尝试的任何想法? – Aniket

0

我关心你在循环中使用的代码。我不知道Arduino如何工作的深入内部,但是延迟10毫秒延迟阻止处理数据的其他代码?如果您简化它:

void loop() 
{ 
    xbee.read(); 
    // Process any complete frames. 
    while (xbee.isComplete()){ 
     Serial.print("\nIncoming Message: "); 
     printPacket(xbee.getIncomingPacketObject()); 
    } 
} 

但在此之前走得太远,你应该找出问题会由协调连接到终端模拟器在PC上监视的帧速率。如果所有帧都到达,那么协调器上有一个问题。如果他们不这样做,请首先处理您的路由器代码。

+0

我删除了协调器代码中的延迟,将数据包大小调整为8个字节的有效负载(之前为45,总的数据包大小为15个字节左右),即使它似乎是固执地删除数据点。原始帖子中链接中显示的输出是通过使用Xbee屏蔽连接到Uno的PC上的终端仿真器获取的。当我使用Xbee Explorer直接将协调器连接到PC时,显示乱码。这可能是因为我处于API模式。但我不知道为什么它不工作。我的论文需要这个。任何帮助表示赞赏。 – Aniket

+0

您需要将数据视为十六进制来理解它。注意'0x7E'作为帧字符的开始,接着是两个字节的长度和帧类型。正如我所说的,您需要先确认您实际上是从路由器发送数据,然后再花费更多时间对协调器进行故障排除。最简单的解决方案可能是降低刷新率,直到获得可靠的通信。 – tomlogic

+0

在我所研究的一个监测项目中,终端设备在5分钟内捕获数据,然后在5分钟窗口内发送一个数据包,并显示最小值,最大值和平均值。也许类似的东西可以用于你的项目。 – tomlogic