Go Down

Topic: Data over XBee works for a few seconds then stops... (Read 7 times) previous topic - next topic

kriista

I have a series1 XBee (http://www.sparkfun.com/products/8664) connected to an ArduIMU (http://www.sparkfun.com/products/9956) which is basically an arduino and a 6DOF board.

I have DIN connected to TX and DOUT connected to RX. I also have 3.3v and ground connected.

On the receiving side I have a USB shield (http://www.sparkfun.com/products/8687) for the XBee and that's connecting directly to a laptop, which will then receive the data via Max/MSP.

The baud rate for the XBees and Arduino are set to 115200, and the DL address of my transmitting XBee is set to the MY address of the receiving one.

The code I have is working (though I'm tweaking/improving it) and it looks like this:

Code: [Select]
const int ax = A0;
const int ay = A1;
const int az = A2;
const int gx = A6;
const int gy = A7;
const int gz = A3;

void setup()
{
  Serial.begin(115200);
}

void loop()
{
  Serial.print("2 ax ");
  Serial.print(analogRead(ax));
  Serial.println();
  Serial.print("2 ay ");
  Serial.print(analogRead(ay));
  Serial.println();
  Serial.print("2 az ");
  Serial.println(analogRead(az));
  Serial.println();
  Serial.print("2 gx ");
  Serial.print(analogRead(gx));
  Serial.println();
  Serial.print("2 gy ");
  Serial.print(analogRead(gy));
  Serial.println();
  Serial.print("2 gz ");
  Serial.println(analogRead(gz));
  Serial.println();
}


It's basically a tweaked version of the "VirtualColorMixer" example that comes built-in with the Arduino IDE.

With that code on the Arduino, I get data on my computer just fine, in both Max/MSP and Serial Monitor. Now when I transmit over the XBee I get a short spurt of data (maybe 2-3 seconds) filled with errors (I get a bunch of error messages from my parsing routine in Max/MSP) then it stops working altogether. I also tested it with serial monitor and I get the same thing (a short spurt of data, then nothing).

Is it physically connected right? (only 4 wires from the arduino to the xbee)
Is the data going across too fast or something?

I tried adding a 'delay(40)' at the end of my main loop in case data was going across too fast and it still crapped out (though I want to say it took longer to crap out, but I didn't time it or anything).

kriista


PaulS

Quote
I tried adding a 'delay(40)' at the end of my main loop in case data was going across too fast and it still crapped out (though I want to say it took longer to crap out, but I didn't time it or anything).

40 milliseconds may not be enough for the receiver to process all the data received. Try a (much) larger delay (maybe 500 to start with). If that works, slowly lower it until you find a value that works.

kriista

So it's that I'm sending too much information?

500ms would be unusably slow (I know that's just an example value), but 40ms is more latency that I'd want as well.

I'm rewriting the code (though your help in another thread) to send binary bytes, instead of the text-based serial.print code posted here, so that would produce much less information per spurt which would hopefully help things overall. (6 sensors, 4bytes per sensor, so 24bytes of data per loop).

Would lowering the baud rate help too? Or is it a matter of generating less information per loop overall?


PaulS

Quote
Would lowering the baud rate help too?

It would hurt. Sending data slower is the opposite of what you want to do.

Quote
Or is it a matter of generating less information per loop overall?

It's a matter of not sending data faster than the receiver can handle it. Once the receiver quits acknowledging packets, the sender quits sending. Packets that are not added to the serial buffer are not acknowledged. So, the rate that data can be sent can be no faster than the receiver can read (and process) it,

kriista

So the things I can do to improve this are:

Send less data overall (binary bytes)
Add delay to the loop

That's it?

48X24X48X

If you want to get the best results, use the CTS pin. Send only when the XBee buffer is not full. :)

kriista

Isn't the receiver the problem? (So I'm sending too much data, wether or not the sending arduino's buffer is full)

PaulS

Quote
Isn't the receiver the problem? (So I'm sending too much data, wether or not the sending arduino's buffer is full)

Yes, the receiver is the problem. Its receive buffer is overflowing, not the Arduino's buffer. Outgoing data is not (yet) buffered on the Arduino.

kriista

You kind of confused me there with the last part.

Relatedly I tried putting together the code for sending binary bytes using serial.write and am getting a compile error I've not seen before.

This code:

Code: [Select]
Serial.write(0x11, BYTE);
Serial.write(highByte(AccX));
Serial.write(lowByte(AccX));
Serial.write(0x99, BYTE);


Is giving this error:
invalid conversion from 'int' to 'const uint8_t*'

In searching the forum the solution I've seen says to use Serial.print instead of Serial.write, which is a step backwards in terms of sending less data.

SurferTim

#10
Oct 09, 2011, 07:45 pm Last Edit: Oct 09, 2011, 08:03 pm by SurferTim Reason: 1
I don't know about the BYTE parameter, but if you are trying to send individual bytes, this works for me.
I encoded the letters 'H' into the highByte, and 'I' in the lowByte, the 0x21 is an exclamation point, the last two are the CR-LF.
The array I filled in setup(). It is sent two ways. One as an array (needed typecasting) and count, the other as a zero terminated string.

Code: [Select]
char outBuf[6];
int AccX = 0x4849;

void setup()
{
  Serial.begin(9600);
  outBuf[0] = 0x48;
  outBuf[1] = 0x49;
  outBuf[2] = 0x21;
  outBuf[3] = 0x0D;
  outBuf[4] = 0x0A;
  outBuf[5] = 0;
}


void loop()
{
  Serial.write("Single\r\n");
  Serial.write(highByte(AccX));
  Serial.write(lowByte(AccX));
  Serial.write(0x21);
  Serial.write(0x0D);
  Serial.write(0x0A);
  delay(1000);
  Serial.write("Count\r\n");
  Serial.write((uint8_t*)outBuf,5);
  delay(1000);
  Serial.write("String\r\n");
  Serial.write(outBuf);
  delay(1000); 
}



kriista

Ok, so I've changed it to this:

Code: [Select]
Serial.write(0x11);
Serial.write(highByte(AccX));
Serial.write(lowByte(AccX));
Serial.write(0x99);


And I don't get any compile errors. I've not tested to see if I'm getting data yet. I need to figure out the parsing side of things as I've not done binary parsing in my host program (Max/MSP) before, so I need to figure that out.

I don't follow most of that code with the string bits in it. I'm specifically trying to send as little information as possible, to hopefully alleviate this buffer overrun problem, and to improve/reduce latency in general.

I'm using the first byte to tag which device I'm using (I have two arduino's, each with 9 sensor outs, so 0x11 = device 1, sensor 1), then the actual sensor data (in this case Accelerometer X axis), then a footer tag (for parsing purposes). So 4 bytes total per sensor (x 9 per arduino, so 36bytes in data total).

Isn't "Count\r\n" at least 9 bytes on it's own? (Unless I'm misunderstanding how "quotes" work when used with Serial.write

SurferTim

#12
Oct 09, 2011, 08:46 pm Last Edit: Oct 09, 2011, 09:03 pm by SurferTim Reason: 1
All this is not as important with Serial.print() and Serial.write() as it is in some other transport protocols.

With the ethernet shield (TCP or UDP), client.print(), client.println(), and client.write(uint8_t) will send each character in its own packet. Very wasteful.

Those last two array writes (Count and String) are the only way to send all that data in one packet.

Edit: The "Count\r\n" is being sent as a zero-terminated string, letting you know the next line is going to be the array and count method. It is the "HI!\r\n" in the array that is 5 characters. The sixth character in the array is the zero terminator.

"Count\r\n" as an array would be 7 characters. "Count\r\n" with a terminating zero would take an 8 character array.
\r = 0x0D ( one character)
\n = 0x0A (one character)

kriista

So if I send the data as a string, it stays together as one packet?

So I could send sensor/device tag & sensor data as a single packet, and if I had two XBees sending this way, each packet would arrive at the  receiver in one piece?

One thing that I know I was going to have a hard time was when I had two XBees going at the same time, each sending 9 sensors worth of data, with the streams getting crossed or collided.


SurferTim

Not with XBee. That is serial, not TCP or UDP. No packets involved with serial. It all goes in its own "packet", but with serial, there is only a start and stop bit as "packet overhead". With the other protocols, the packet overhead is high if you send just one byte.

Don't be confused with that now. Just be aware of the different ways you can "write" to different devices.



Go Up