Huge Latency + Errors when Sending Analog Values using XBees

Status
Not open for further replies.
Dear all,

I am building a wireless musical interface using three XBees and two Teensy 3.2s. When I try to send analog potentiometer values using the Arduino XBee Library, I run into huge (+10 second) latency and errors. Why is this happening? Has anyone encountered this problem before? My wireless hardware setup involves:

  • One XBee 3 module set up as a coordinator running in API 1 Mode (without escapes). This module is connected to a Sparkfun USB explorer which is connected to my Macbook.
  • Two XBee 3 modules set up as routers running in transparent mode.
  • Two Teensy 3.2's connected to the XBee routers via two Teensy XBee adapters

All XBee 3 modules are configured to run using 802.15.4 firmware. Everything works fine when I am simply running two modules in transparent mode and just printing serial values. Everything also works fine when I am running the two routers in transparent mode and one coordinator in API mode and send unchanging integer values using the Arduino XBee library. The latency/error issue arises when I am reading and sending a variable potentiometer value using the Arduino XBee library. Numbers received on my Macbook are totally mangled and often take 5-10 seconds to update and correspond to the physical potentiometer position. I've pinpointed the issue to the code running on the Teensy's. It seems to me as if the XBee library somehow can't keep up with the rate of transmission. Has anyone ever encountered this problem before? I'm going to wait a couple of days and then attempt to bypass the library and write my own packet sending functions on the Teensy to see if this solves the issue. Any advice is appreciated. My Teensy code is attached below for reference.

Thanks in advance,
Bernard Le Chevre

Code:
#include <XBee.h>

XBee xbee = XBee();
uint8_t payload[] = {0, 0};
int pot;

// 16-bit addressing: Enter address of remote XBee, typically the coordinator
Tx16Request tx = Tx16Request(0000, payload, sizeof(payload));

void setup()
{
  //Startup delay
  delay(5000);
  //Begin HW serial
  Serial1.begin(115200);
  xbee.setSerial(Serial1);
}

void loop() {

    //Break down 10-bit analog reading into two bytes and place in payload
    pot = analogRead(A0);
    payload[0] = pot >> 8 & 0xff;
    payload[1] = pot & 0xff;
    //Send to coordinator
    xbee.send(tx);
    delay(10);
}
 
I use the XBees a bit but only between two modules. Even then it's been very tricky to get them to operate quickly because the default settings seem to be optimized around minimizing packet loss, not to maximize throughput or to lower latency. For example, I use two set up as endpoints (no routing) and could only get bi-directional communication to top out at around 40Hz on each module with each sending 128byte payloads back and forth. This was only possible after I changed the settings to not use any rebroadcasts, confirmations, or other delays. In addition, when sending a data often (seems like you're trying to reach 100Hz), it's crucial that only one module speaks at a time. If you have numerous XBees you should try to make them take turns to talk as I found that it's hard to find a setting in XCTU that strikes a good balance of latency and throughput.

For a quick fix, if you can afford it, you can set up multiple XBee networks if you set the CM parameter (channel mask) on each device pair to their own range. It's not MIMO, but it can help bridge the gap. This would look like having two XBees attached to your laptop and one with each teensy. Theoretically then you can have them run in transparent mode like before while having communication to multiple teensies.
 
I use the XBees a bit but only between two modules. Even then it's been very tricky to get them to operate quickly because the default settings seem to be optimized around minimizing packet loss, not to maximize throughput or to lower latency. For example, I use two set up as endpoints (no routing) and could only get bi-directional communication to top out at around 40Hz on each module with each sending 128byte payloads back and forth. This was only possible after I changed the settings to not use any rebroadcasts, confirmations, or other delays. In addition, when sending a data often (seems like you're trying to reach 100Hz), it's crucial that only one module speaks at a time. If you have numerous XBees you should try to make them take turns to talk as I found that it's hard to find a setting in XCTU that strikes a good balance of latency and throughput.

For a quick fix, if you can afford it, you can set up multiple XBee networks if you set the CM parameter (channel mask) on each device pair to their own range. It's not MIMO, but it can help bridge the gap. This would look like having two XBees attached to your laptop and one with each teensy. Theoretically then you can have them run in transparent mode like before while having communication to multiple teensies.

Thanks linarism! Everything you're saying makes sense. I ended up switching to a slightly simpler packet library (SerialTransfer.h -> packets went down in size from 16 to 11), but the really big difference came when I increased my delay to 100ms. Now I can receive accurate values from separate Teensy's. Decreasing the delay to something like 10-50ms results in the errors I was describing. So yes, there does appear to be a limit on the XBee's packet throughput. 100ms delay is obviously not ideal for live music, so this will inform the design of my interface. I've definitely been thinking about your quick fix even before this but wanted to try using the XBees "properly" beforehand. Now that I understand what the throughput limit is I will have to resort to the quick fix if I want real-time values e.g low-latency accelerometer values to control sound.
 
Status
Not open for further replies.
Back
Top