Uno + XBee S2 + GY-521 Serial Garbage issue

I have an Uno with a Series 2 XBee, for the most part working well together using SoftwareSerial. However, now and again I get garbage on the RX serial line. For example and expected message from the other side of the XBee is:

2 0 0 -1\n

Every now and again I get a bunch of extra garbage that looks like the image attached to this post, the extended characters don't come out in a copy/paste here.

This wouldn't be so bad if it only happened once every few dozen messages, I could just drop that one and fill in the gap with the previous message until the next message arrives but the problem appears to be magnified when I have a GY-521 6dof sensor using interrupts. With that connected I get more than one "corrupted" message every 10 messages or so. It seems that when I disconnect the interrupt wire the serial noise is reduced greatly but not entirely.

I have a voltage divider on the tx line so the xbee never sees more than 3.3v. I've checked the other side of the xbee connection and I'm seeing zero noise going into the messages being sent so its something happening from that point forward.

Board: Uno
Connections:
XBeeS2 vcc/vref/rx/tx: 3.3/3.3/12/13
GY-521 scl/sda/ad0/int: A5/A4/GND/2(INT 0)

Is there anything I can do to get cleaner output?

This is how I'm reading from the xbee (SoftwareSerial). I've tried a few different ways and I see the same result with both methods.

void processXBeeMessage()  {
  String foo = xbee.readStringUntil('\n');
  Serial.println(foo);
  
  char array[32] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
  foo.toCharArray(array, 32);
/*  int x=0;
  while( xbee.available() )  {
    if( xbee.peek() == '\n' )  {
      xbee.read();//clear buffer
      array[x++] = '\0';  //end of string
      break;
    } else  {
      array[x++] = xbee.read();
    }
  }*/
  
  Serial.print("XBEE STR: ");
  Serial.println(array);
}

garbage.png

Perhaps you need to reconsider your interrupt strategy. The serial communication uses interrupts and the interrupts from the sensor device may be interfering with the timing.

Make sure that any interrupt routine that you use, is very short. If the interrupt is informing you that the sensor data is "ready", then don't try and read the data using the interrupt routine. Just set a flag so that the next iteration of loop( ) can collect it, while it is not trying to do serial communications.

The work being done in the interrupt can't get much shorter unfortunately, its just setting a bool to flag that its ready. I'm using Jeff Rowberg's DMP work (i2cdevlib/Arduino/MPU6050 at master · jrowberg/i2cdevlib · GitHub) for the MPU6050 and I'm not entirely sure of the ramifications of removing the interrupt and just polling the dmp instead, any idea?

I agree a rethink is a must, given the results of everything I've tried so far. I hooked up the xbee to its usb serial counterpart and verified using coolterm that the data stream was clean. Of a few thousand messages I only had 1 message that I saw (quick scroll but longer lines are obvious) that was doubled up where the first value klobbered the value of the second string overlapped the final character of the previous string.

I'm still getting, relatively, significantly more noise using the xbee + arduino as opposed to the xbee + usb dongle.

But perhaps that is for the is for the networking forum.

I spent another few hours today trying to sort out this "noise" issue. Changing the baud rate on my xbees is a pain in the ass but I found I was getting even more noise at lower baud rates, I have a pair of 24ZBs. So perhaps even less noise could be achieved by using even higher baud rates but I am maxed out.

I also tried changing the way I was reading input by buffering only the data that was available instead of waiting to read the whole string, no change. Also tried swapping the interrupt for 1 instead of 0, no change.

I need both of these things, this is for autopilot on my quadcopter so...

My workaround is simply using sscanf to spec. I noticed in all of the testing all of the garbled messages were intact and at the end of the string, every time. This is strange because every time I detect a complete message and process it, I am zeroing the char array responsible for buffering the xbee input. When the GY-521 is hooked up I'm still getting every message, just at the cost of a little extra processing. If sscanf returns the wrong number of arguments that were properly scanned, I run the string through a filter function that will strip the valid string off the end of the garbled message and run sscanf again on the new array, if sscanf fails again I tally and reuse previous input. I'm yet to have sscanf fail a second time or miss a message. Not the solution I was looking for but its what I'm going with for now.