1

I made a setup which consists of 3 Zigbee's, 2 routers(Zigbee S2C's) and 1 coordinator(Zigbee S2). The routers are each connected to arduino nano which collects data from 2 FSR's and an IMU(frame type: zigbee transmit request and packet size 46 bytes) and sends it to the Coordinator attached to an arduino UNO. All the Xbees are in API mode 2 and working at a baud rate of 115200. I am using a library called "Simple Zigbee Library" to send all the collected data to the Coordinator. The collection and sending of data works fine except that there are packets lost in the way. The nano's sample data at a frequency of around 25Hz independently. The coordinator tries to read the data send from the zigbees(using the library of course) in every loop, but unfortunately, it seems to receive only around 40-45 samples.(Should have been 25*2=50 samples total from the 2 xbees). Can anybody suggest why this is happening. I need as less data loss as possible for my setup to achieve its motive. Any kind of help is appreciated.

P.S: It may be important to mention that the coordinator is reading the data only from one xbee in each loop.

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

Thank you.

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();
}
tomlogic
  • 11,489
  • 3
  • 33
  • 59
Aniket
  • 13
  • 6
  • did you consider *packet collision* and *data corruption*? Is the communication protocol advanced enough to handle these situations? – Patrick Trentin Feb 19 '17 at 14:30
  • This link says that: The radio being used by these modules (MAC & PHY layer) is defined by the IEEE 802.15.4 standard which specifies the use of Carrier sense multiple access with collision avoidance or abbreviated as CSMA/CA.http://electronics.stackexchange.com/questions/36932/xbee-how-does-it-deal-with-collisions – Aniket Feb 19 '17 at 20:09
  • Great, but I had in mind something more high level than that. *CSMA/CA* can and will definitively fail to prevent *collisions* under the right circumstances, although it is definitively better to have it than not. The *higher-level protocol* should require each packet to be *acknowledged*, and force a packet being sent again if no *ACK* is received within a given *timeout*. Last time I worked with *ZigBee*, although I admit I was not using *Arduino*, I had to implement this myself. – Patrick Trentin Feb 19 '17 at 20:39
  • Thanks for the quick answer @PatrickTrentin.. I am using the Xbees in API mode, and the data packets are acknowledged as you described. The library that I am using("Simple Zigbee library") does all the heavy lifting for me. Also my actual code runs at 115200 baud and not 9600 baud as given in the example. – Aniket Feb 20 '17 at 06:44
  • That's good to know, thank you – Patrick Trentin Feb 20 '17 at 07:03
  • Having said that, is there anything I need to change to get data more reliably? – Aniket Feb 20 '17 at 13:35

2 Answers2

0

Although you claim to be using 115,200bps, posted code shows you opening the serial ports at 9600 baud, definitely not fast enough for 2500 bytes/second (50 packets/second * 45 bytes/packet * 110% for overhead) received from XBee and dumped by printPacket()). Remember that 802.15.4 is always 250kbps over the air, and the XBee module's serial port configuration is just for local communications with the host.

Make sure your routers are sending unicast (and not broadcast) packets to keep the radio traffic down.

You should verify that sending is working before troubleshooting code on the coordinator. Update the code on your routers to see if you get a successful Transmit Status packet for every packet sent. Aiming for 50Hz seems like a bit much -- you're trying to send 45 bytes (is that the full size of the API frame?) every 20ms.

Are you using a hardware serial port on the Arduino for both the XBee module and Serial.print()? How much time does each call to printPacket() take? If you reduce the code in printPacket() to a bare minimum (last byte of sender's address and the 1-byte frame ID), do you see all packets come through (an indication that you're spending too much time dumping the packets).

tomlogic
  • 11,489
  • 3
  • 33
  • 59
  • thanks for replying @tomlogic I am using a baud rate of 115200 for all the three arduino's. The mistake in the example code has been rectified. The sending is working as I am getting acknowledge messages for both the routers. But some of the packets don't get acknowleged. Happens in around 2 in 10 of the packets.(In both the xbees). 50 Hz is not compulsory, but the higher the better for me. I am using software serial on all the 3 xbees. Even when I reduce the code in printPacket to a bare minimum, all the packets dont come through. – Aniket Feb 20 '17 at 13:34
  • You're still printing a lot of information on every received packet (100 characters * 50 messages = 50kbps of a 115.2kbps max) -- reduce it to just a few bytes for testing. You might be spending so much time printing packets that you're falling behind. How big are the serial buffers on the Arduino? Can you use hardware handshaking (CTS/RTS) to prevent buffer overflows? – tomlogic Feb 21 '17 at 15:46
  • I toned down the code to the bare minimum data(8 bytes) that is necessary. The serial buffer size is 64bytes for the arduino's. I tried increasing the buffer size of the UNO using the method shown in http://www.hobbytronics.co.uk/arduino-serial-buffer-size, but it still loses data bytes. Any ideas on what else can be tried? – Aniket Feb 21 '17 at 19:11
0

I'm concerned with the code you're using in loop. I don't know the deep internals of how the Arduino works, but does that 10ms delay block other code from processing data? What if you simplify it:

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

But before going too far, you should isolate the problem would by connecting the coordinator to a terminal emulator on a PC to monitor the frame rate. If all frames arrive then there's an issue on the coordinator. If they don't, work on your router code first.

tomlogic
  • 11,489
  • 3
  • 33
  • 59
  • I removed the delay in the code for the Coordinator, trimmed down the packet size to 8 bytes of payload(earlier it was 45, Total packet size is around 15 bytes)even then it just seems to be stubbornly dropping data points. The output shown in the link in the original post was taken using a terminal emulator on a PC connected to the Uno with a Xbee shield. When I directly connect the Coordinator to the PC using Xbee Explorer, I get gibberish displayed. That may be because I am in API mode. But I just cant figure out why its not working. I need this for my thesis. Any help is appreciated. – Aniket Feb 21 '17 at 19:40
  • You'll need to view the data as hex to make sense of it. Watch for `0x7E` as the start of frame character, followed by a two-byte length and frame type. Like I've said, you need to first confirm that you're actually sending the data from the routers before spending more time troubleshooting the coordinator. The easiest solution to this might be to lower your refresh rate until you get reliable communications. – tomlogic Feb 21 '17 at 21:55
  • On one monitoring project I worked on, the end devices captured data for 5 minutes and then sent a single packet up with the minimum, maximum and average reading over that 5 minute window. Maybe something similar would work for your project. – tomlogic Feb 21 '17 at 21:57
  • You could also try running with a single router providing data to see if you get reliable communications. That would be a quick way to confirm proper operation on both ends. At that point, it's either an issue of network congestion on the ZigBee network, or too much processing on the coordinator to keep up. If one works, try two with half of the sampling rate. – tomlogic Feb 21 '17 at 21:58