Go Down

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

kriista

Ok, I get you.

I thought you had just dropped a simple way for me to avoid a bunch of problems!

So over XBee using the headerbyte, 2byte sensor data, footerbyte is as small as I can get then? (while still having a header/footer for parsing purposes)

draythomp

There is one thing you can try to speed things up (usually a lot).  If you are currently using broadcast, switch to directly addressing the other XBee.  Depending on the XBee series you are using set each one to directly address the other and then try the experiment again.  When you're using broadcast (the default way they are shipped) the buffers may not go out quickly.  Using direct addresses they shoot right out.

At the receiving end, grab the bytes as soon as they appear to minimize buffering on the receive XBee.
Trying to keep my house under control http://www.desert-home.com/

kriista

I've got them set to direct addresses, though I've not yet tested sending both to a single receiver (I want to figure out the parsing first so I know what's happening on the computer side).

kriista

Finally had some time to sit down and test the new code (sending binary).

It still craps out after a couple of seconds (with no discernible difference from using serial.print).

I added in a delay(100) (which is waaay too much latency for the intended usage) and it died after 7seconds....

Any other ideas on how to fix this?

draythomp

Correct me if I'm wrong.  There's only two possibilities left.  1, The XBees just cant keep up  2, The receiving end can't suck the characters out fast enough to clear the buffer.

Judging from your description, you are hitting the XBee to send as fast as you can given the baud rate limitations and the other end has to get them all and pass them out the serial port.  This then locks up and you stop seeing characters coming out the Rx end serial port.  I mean, they don't come out in hunks, they just quit coming out, never to resume.

So, at the Rx end, dump the parsing and any other code and just use a serial terminal to watch the port as fast as it can.  Turn on the Tx arduino and the XBee.  In your code, give the XBee a couple of seconds to get connected ok and then hit it.  If the Rx end keeps up, the parsing code isn't fast enough to keep up with the input stream and you're filling the Rx buffer on the xbee or something along those lines.  If the terminal program sees the same results, then the XBees just can't handle it.

I'd try it, but I don't have any Series 1 XBees, I'm exclusively Series two and the data rates I use are a whole lot lower than what you want to do.
Trying to keep my house under control http://www.desert-home.com/

kriista

I'm guessing it's the second thing.

At the moment I'm not parsing data at all. Just printing values from the serial receive object in Max/MSP. After a few seconds it stops altogether. (the TX/RX lights go out on the Xbee RX shield).

This also happens in serial monitor. It's also super unresponsive when connected directly. Like if I'm not using the XBee and just have the sensor Arduino connected over USB, it's nearly impossible to change the baud rate, or move/close the serial monitor window.

In doing some searching on the forum I see serial.available() and serial.flush() come up a bunch. I'm wondering if I should use something like that?

One thing that did occur to me is that I'm hitting the serial read object in Max/MSP at 10ms. I don't know if that's connected to the RX arduino/xbee buffer, or just a matter of how often I check the buffer.

As in, if I increase that rate (say to 5ms or lower) will it empty out the serial buffer twice as fast, or just read from it twice as fast?

I've disconnected the XBee from the arduino in order to program the Arduino, so I can't test that last thing out just now. (Is it normal that you can't program the Arduino if an Xbee (which isn't powered up) is connected to the rx/tx pins).

draythomp

I've had nothing but trouble when I connect the XBee to pins 0 and 1.  I physically pull the XBee out when programming the arduino.  Most of the time I use NewSoftSerial and put the XBee on pins 2,3 so I don't have to deal with that.  I do have one Arduino that has the XBee hooked to pin 0,1, but that will be changing when I get around to it.  However, the data rates you want won't work with the software serial code, it's interrupt driven and isn't rated for that kind of speed.

However, the sluggish response you're seeing is not something I've experienced.  A terminal window talking through the usb to an XBee just snaps right along.  I wonder if you have something going on there that is weird.  You might try something else to read the rx serial output.  Got another arduino, a friend that has another arduino, another computer, something like that?

Trying to keep my house under control http://www.desert-home.com/

kriista

Ok, did some further testing.

With the sensor/xbee sending data (with no serial reading happening in software on the computer side), I see the RX light flash for a few seconds (longer than normal) then it stops, and after a couple more seconds the "RSS" LED goes out on the USB Explorer. (http://www.sparkfun.com/products/8687)

If I change the rate at which I read the serial object in Max/MSP increased (down to 1ms) it gets data for about 10+ seconds before crapping out.

(This is all with a delay(100) in the Arduino code though).

In serial monitor I get the same behavior.

kriista

Yeah it's annoying not being able to program while connected to rx/tx, particularly when not using a shield and hardwiring things, which prototyping....

kriista

I also tried removing the delay(100) and adding a delay(5) and Serial.flush() after that, but that only sends one bit of data then stops. I'm guessing that would require Serial.begin at the start of the loop too. Not sure if that's the way to go though, but I was thinking that might sending once passes worth of data, then empty the buffer, then doing it all over again, since I can't imagine that 20-30 bytes would overflow the buffer.

PaulS

Quote
but I was thinking that might sending once passes worth of data, then empty the buffer, then doing it all over again, since I can't imagine that 20-30 bytes would overflow the buffer.

I hooked up an Arduino and XBee, with simple code to echo what it received.
Code: [Select]
void setup()
{
  Serial.begin(9600);
}

void loop()
{
  while(Serial.available() > 0)
  {
    char aChar = Serial.read();
    Serial.print(aChar);
  }
}

I put another XBee on a USB explorer, and started X-CTU sending data. It is still blinking all the lights, and transmitting data, as fast as it can, no delays, 15 minutes later.

I don't think your problem is with the XBees. Configuration? Maybe. Wiring? Not sure. Power? Maybe.

draythomp

PaulS, his baud rate is 115400, is 9600 a valid comparison?
Trying to keep my house under control http://www.desert-home.com/

kriista

I don't think your problem is with the XBees. Configuration? Maybe. Wiring? Not sure. Power? Maybe.


Hmm.

Ok, receiver XBee (Connected to USB Explorer http://www.sparkfun.com/products/8687):

PAN ID - 2301
DL - 2823273
MY - 2301
Interface Data Rate - 115200


Sender XBee (1 of 2, both with identical settings):

PAN ID - 2301
DL - 2301
MY - 0 (unset)
Interface Data Rate - 115200


Wiring is XBee 3.3v/GND pins connected to the 3.3v/GND pins of the I2C header on the ArduIMU board (http://www.sparkfun.com/products/9956).
XBee DOUT is connected to RX (on the programming header of the ArduIMU, DIN is connected to TX (on the same header).
So only 4 wires between the XBee and the ArduIMU. All wired physically, as wires.

Power is coming via LiPo battery on the transmitter side, and USB on the receiver side.

The LiPo battery is an 110mAh (http://www.sparkfun.com/products/731)  running into a booster/charger board (http://www.sparkfun.com/products/9956). The 5v out of the booster is going to the 5v in of the ArduIMU (bypassing the 5v regulation on the ArduIMU, as that would expect 6v+)

For the sake of thoroughness here is the code used again:

Code: [Select]
#include <Wire.h> //I2C Arduino Library
#define address 0x1E //0011110b, I2C 7bit address of HMC5883

// define sensor inputs
#define aX A0
#define aY A1
#define aZ A2
#define gX A6
#define gY A7
#define gZ A3

// define button inputs
#define switch1 9
#define switch2 10

// define sensor variables
int AccX;
int AccY;
int AccZ;
int GyroX;
int GyroY;
int GyroZ;

// define button variables
int SW1;
int SW2;

void setup()
{
 Serial.begin(115200);
 pinMode(switch1,INPUT);
 pinMode(switch2,INPUT);
 Wire.begin();
 //Put the HMC5883 IC into the correct operating mode
 Wire.beginTransmission(address); //open communication with HMC5883
 Wire.send(0x02); //select mode register
 Wire.send(0x00); //continuous measurement mode
 Wire.endTransmission();
}

void loop()
{
 
 int x,y,z; //triple axis data for magnetometer

 //Tell the HMC5883 where to begin reading data
 Wire.beginTransmission(address);
 Wire.send(0x03); //select register 3, X MSB register
 Wire.endTransmission();
 
 //Read data from each axis of magnetometer, 2 registers per axis
 Wire.requestFrom(address, 6);
 if(6<=Wire.available()){
   x = Wire.receive()<<8; //X msb
   x |= Wire.receive(); //X lsb
   z = Wire.receive()<<8; //Z msb
   z |= Wire.receive(); //Z lsb
   y = Wire.receive()<<8; //Y msb
   y |= Wire.receive(); //Y lsb
 }
 
 // read analog sensors
 AccX = analogRead(aX);
 AccY = analogRead(aY);
 AccZ = analogRead(aZ);
 GyroX = analogRead(gX);
 GyroY = analogRead(gY);
 GyroZ = analogRead(gZ);
 
 // serial print tag, sensor value
 Serial.write(0x11);
 Serial.write(highByte(AccX));
 Serial.write(lowByte(AccX));
 Serial.write(0x99);
 Serial.write(0x12);
 Serial.write(highByte(AccY));
 Serial.write(lowByte(AccY));
 Serial.write(0x99);
 Serial.write(0x13);
 Serial.write(highByte(AccZ));
 Serial.write(lowByte(AccZ));
 Serial.write(0x99);
 Serial.write(0x14);
 Serial.write(highByte(GyroX));
 Serial.write(lowByte(GyroX));
 Serial.write(0x99);
 Serial.write(0x15);
 Serial.write(highByte(GyroY));
 Serial.write(lowByte(GyroY));
 Serial.write(0x99);
 Serial.write(0x16);
 Serial.write(highByte(GyroZ));
 Serial.write(lowByte(GyroZ));
 Serial.write(0x99);
 Serial.write(0x17);
 Serial.write(highByte(x));
 Serial.write(lowByte(x));
 Serial.write(0x99);
 Serial.write(0x18);
 Serial.write(highByte(y));
 Serial.write(lowByte(y));
 Serial.write(0x99);
 Serial.write(0x19);
 Serial.write(highByte(z));
 Serial.write(lowByte(z));
 Serial.write(0x99);
}

draythomp

#28
Oct 17, 2011, 04:18 am Last Edit: Oct 17, 2011, 04:29 am by draythomp Reason: 1
Alright, it's time to nail this thing down.  I think it is data rate and I just couldn't find that for the XBees (data overload from google).  

So, I propose a test that should take a lot less time than you've wasted so far.  Set the baudrates on both of them to 9600 and repeat PaulS's test.  I bet it works.  Then go to 57K, I bet it works for a while and then craps.  And so forth.

edit:  Spoke too soon, the datarate is 250Kbps for the low power 2.4GHz modules.  That should be enough, but I still think the test would be useful.

Yet another edit:  I just remembered the overhead.  These thing build everything into a packet and send acks and so forth back and forth.  You could well be exceeding the data rate.  Working from memory, the packet is a bunch bigger than the data for small messages what with the various addresses, checksums, sequence numbers and so forth.  They even do this in transparent mode, I mix my devices using one mode for this one and the other mode for that one.  So, the test makes even more sense.
Trying to keep my house under control http://www.desert-home.com/

kriista

From what I've read sending binary bytes has minimal overhead, so each sensor is 4bytes of data that I'm sending, + 2 bytes of data in order to send it, and that's it.

I did think about trying a lower baud rate, but it was mentioned earlier in this thread that that would make things worse (by backing up the buffer further), so I hadn't tried it yet, but I will definitely give it a go.

It seems like some kind of voodoo balancing act between baud rate, sending code, receiving code, delay(), etc...

Go Up