Go Down

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

kriista

Yup just tested. I was calling the function and getting the '65' in Max/MSP but, just like before, it stops after a little bit.

kriista

So finally got back around to testing again.

I changed everything to 57600 (Xbee baud rate and Arduino baud rate) and it seemed to work without a problem. I wonder why the higher baud rate doesn't work.

It also ran off batteries for 43min, which is longer than the performances in which it's going to be used (20-25min long, often shorter)

I measured the latency between readings coming in and it looks like 10-40ms between the 'round trip' part of the call/response. I was getting 0ms between the actual sensor numbers coming in (which seems weird as I'm polling every 10ms, but I guess they come in a burst), but the time between one set of numbers coming in and the next varied between 10-40. Most were in the 20/30 range.

kriista

#47
Aug 15, 2012, 04:39 am Last Edit: Aug 15, 2012, 04:43 am by kriista Reason: 1
Sorry to raise this thread from the dead but an update and a new version of this problem.

To kind of summarize the thread up to this point I'm using a 9DOF sensor setup with a built-in Arduino. I'm sending that over XBee (series1) to another XBee connected to an XBee USB explorer. I was doing it at 115200 but it would stop working after a couple of seconds. I did two things, one was incorporate a serial call-reponse setup, and bring the baud rate down to 57600.

I didn't touch this project for many months (since about the last post) but recently dusted it off, wired it up, housed it, and began tweaking things. I got it working consistently, streaming all (9) sensors over XBee/serial at 57600 using a call-reponse setup with Max/MSP.

The thing is, every now and again (it honestly seems random) it drops out. It will run fine for over an hour then stop working, or sometimes it just keeps dying after a few minutes a pop.
I'm wondering if this call-response type setup is more prone to death or buffer overflow (ie if my computer doesn't send a 'hello' within X amount of time, that it overruns the receiving serial buffer).

It does seem to happen more often (though that could be psychosomatic) when the computer is bogged down. I'm using this with a Max/MSP patch that is doing quite intensive audio processing in real-time. I'm polling the serialport every 10ms, but that 10ms isn't always 10ms as the scheduler for that kind of thing isn't perfect in Max.

Another problem is that the Arduino code I'm running only sends out a "hello" byte on the startup loop, so if it dies, I literally have to restart the unit, which is a bummer.

Here is the code I'm currently running:

Code: [Select]
// i2c Arduino Library
#include <Wire.h>

// 0011110b, i2c 7bit address of HMC5883
#define address 0x1E

// Define sensor variables
int AccX;
int AccY;
int AccZ;
int GyroX;
int GyroY;
int GyroZ;
int SW1 = 9;
int SW2 = 10;

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

// Incoming serial byte
int inByte = 0;

void setup() {
 // Start serial port at 57600 bps:
 Serial.begin(57600);
 
 // Set incoming switch mode
 pinMode(SW1,INPUT);
 pinMode(SW2,INPUT);
 
 // Start i2c communication
 Wire.begin();
 
 // Put the HMC5883 IC into the correct operating mode
 Wire.beginTransmission(address); //open communication with HMC5883
 Wire.write(0x02); //select mode register
 Wire.write(0x00); //continuous measurement mode
 Wire.endTransmission();
 
 // Send a byte to establish contact until receiver responds
 establishContact();  
}

void loop() {
 // Define variables for magnetometer
 int MagX,MagY,MagZ;

 // Tell the HMC5883 where to begin reading data
 Wire.beginTransmission(address);
 Wire.write(0x03); //select register 3, X MSB register
 Wire.endTransmission();
 
 // If we get a valid byte, read analog ins:
 if (Serial.available() > 0) {
   inByte = Serial.read();
   
   AccX = analogRead(aX);
   AccY = analogRead(aY);
   AccZ = analogRead(aZ);
   GyroX = analogRead(gX);
   GyroY = analogRead(gY);
   GyroZ = analogRead(gZ);
   
 // Read data from each axis of magnetometer, 2 registers per axis
 Wire.requestFrom(address, 6);
 if(6<=Wire.available()){
   MagX = Wire.read()<<8; // X msb
   MagX |= Wire.read(); // X lsb
   MagZ = Wire.read()<<8; // Z msb
   MagZ |= Wire.read(); // Z lsb
   MagY = Wire.read()<<8; // Y msb
   MagY |= Wire.read(); // Y lsb
 }
 
 // Send sensor data out
 
 // Accelerometer X  
 Serial.write(highByte(AccX));
 Serial.write(lowByte(AccX));
 
 // Accelerometer Y
 Serial.write(highByte(AccY));
 Serial.write(lowByte(AccY));
 
 // Accelerometer Z
 Serial.write(highByte(AccZ));
 Serial.write(lowByte(AccZ));
 
 // Gyroscope X
 Serial.write(highByte(GyroX));
 Serial.write(lowByte(GyroX));
 
 // Gyroscope Y
 Serial.write(highByte(GyroY));
 Serial.write(lowByte(GyroY));
 
 // Gyroscope Z
 Serial.write(highByte(GyroZ));
 Serial.write(lowByte(GyroZ));
 
 // Magnetometer X
 Serial.write(highByte(MagX));
 Serial.write(lowByte(MagX));
 
 // Magnetometer Y
 Serial.write(highByte(MagY));
 Serial.write(lowByte(MagY));
 
 // Magnetometer Z
 Serial.write(highByte(MagZ));
 Serial.write(lowByte(MagZ));
 
 // Switch 1
 Serial.write(digitalRead(SW1));
 
 // Switch 2
 Serial.write(digitalRead(SW2));
 }
}

void establishContact() {
 while (Serial.available() <= 0) {
   Serial.write('A');   // send a capital A
   delay(300);
 }
}

48X24X48X

Hi,

Let me see whether I get your idea right:

Upon power up, Arduino tries to get establish a connection to a PC through point-to-point XBee connection.
Once established (a handshake?), the PC will send a "hello" command at an interval to the Arduino.
The Arduino will response by sending the sensor data?

In order to make sure that this thing work perfectly, I would advise use a simpler Terminal program on the PC that takes care of the TX & RX of the "hello" command. In my case, I would use the program Docklight (not affiliated with them). You can set it to response to a certain character ('A' in your case) and also transmit a string/character at a regular interval. All the incoming and outgoing characters is shown (logged if you have the paid version). By doing this over long period of time, you probably will be able to tell whether the Max/MSP is the issue.

kriista

More like the Arduino sends data, once Max receives it it sends a request for more, and then it sends more. So if the computer doesn't receive the sensor data, it won't send a request for more, and sending a request for more when its crashed doesn't seem to satisfy the Arduino (which is what makes me think the serialbuffer is freaking out).

(I'm on a mac with no windows partition/emulation).

kriista

Ok did a bit of searching, since I've been under the presumption that most of my problems have been with a serial buffer, on the receive side of things. It's why I went to a slower baud rate, it's why I went to serial call-response.

I found this thread on how to improve xbee transfer speed:
https://groups.google.com/forum/#!topic/xbee-api/HQgvRz-Y-3o%5B1-25%5D

Which states the following:
"One of the things you can do is to change the settings on your XBEE
explorer (I guess you use them).

The XBEE explorer FTDI chip will have a serial buffer time of 16 ms
standard but it can be brought back to 2 ms. But you can also change the
buffer size. FTDI chip on the explorer is FT232RL (R chip). I don't know
if this is the same for windows machines but on MAC the instructions
should be here (make sure you are the root user when trying to change
things): "

It then points to this document:
http://www.ftdichip.com/Support/Documents/TechnicalNotes/TN_105%20Adding%20Support%20for%20New%20FTDI%20Devices%20to%20Mac%20Driver.pdf


So. Is that an option and more specifically, a possible to solution to my problems? Can I just change the serial buffer time down to 2ms and it will be less prone to jamming up when going at higher baud rates? (115200)
Is this something that's possible when using an Arduino on the receive side of an XBee connection (ie if I use an Arduino Mega to connect to the computer, instead of an XBee USB Explorer)?

kriista

Ok I opened up the .plist to try to edit the latency timer, but there's dozens (if not over a hundred) devices in the .plist file.

How do you find out the device name/key for a USB explorer?
And since this is in the .plist file on the computer, I'd need to change the .plist file on each computer I use this setup with? (It doesn't stick to the ftdi chip on the USB explorer?).

kriista

Did more testing today. I ran my parsing at 150ms (up from 10ms) and it still drops out. There's no way I'm overrunning a buffer sending 20bytes every 150ms...particularly using call-response.

I also noticed, unless I'm just imagining it, that I get more dropouts when I'm not plugged into the charger. If I'm using it purely wirelessly it seems to drop out after a minute (even at 150ms), but if I have it plugged into a USB charger (no data, literally a USB charger) then it seems to last longer (up to 15minutes+). I'm using this as my charger/booster (https://www.sparkfun.com/products/10300) and only have the ArduIMU and an XBee connected to the charger/booster.
The power doesn't go (the arduIMU isn't dying/resetting), so I don't know what's happening.

Unless the XBees are flaking out for some reason...

48X24X48X

Did you ever use the CTS line on the XBee? On the sensor node side.
I notice in the past that I drop packets whenever I just dump data to the XBee without really checking whether is is ready to accept or not.
Somewhere buried in the datasheet, they also mentioned about the buffer size and when they will pull the CTS line high indicating they can't accept anymore at this moment. You might want to check that out just in case.

kriista

I haven't messed with that at all really. I did make a different thread (http://arduino.cc/forum/index.php?topic=118731.0) a bit ago about changing some of the FTDI driver/buffer settings, but now having tested it super slowly, I'm thinking the problem isn't there.

I didn't see CTS in the XBee configuration (in X-CTU), but I only had a quick look (dead tired and about to go to sleep).
I did see "Packetization Timeout" which is set to 3 on both units.

What settings are you suggesting I change, and to what?


I found this:

~CTS is Clear To Send. An output from the device receiving data from another device. When asserted (low) it is telling the other device it is Clear to send data.

~RTS is Request To Send. An input to the device sending the serial data meaning the other device is ready to receive data when asserted (low). The receiving device Request data.

So is CTS/RTS the equivalent of XBee call/response?

kriista

Wait, these are hardware pins you're talking about.

Are you saying take data from/to them? Ground them?

48X24X48X

These are the pins on the XBee. The CTS will be high whenever his buffer is full and cannot take more.
I think with the rate you are transmitting, it will be better to know whether XBee is ready to take in more data.

kriista

Right, you're saying to measure it to see what's up.

So it should never go high? Or rather, if I see it go high, there's a problem?

What would be the solution to that problem, if it's the 'transmitter' xbee that's overflowing?

48X24X48X

The CTS pin will go up and down depending on whether it is ready to take in more data.
Take a look at page 13 of the datasheet.
If the XBee is not ready (CTS high), all the data that you send from the Arduino on the serial to the XBee will be ignored/dropped. You are running at quite high serial baud rate right?

In your data packet, do you have a packet number? Like a free running number that increases over time (and overflow)? This can be used to indicate whether all packet are received at your receiver end (PC side).

kriista

I'm only running at 57600 (it was originally 115200 but it would dropout after a couple seconds).

The thing is, with the call/response the transmitter is only sending data when it receives a packet back (and vice versa for the computer), so nothing should overflow that way (I would think).

I'm guessing the 'response' part of the message is getting dropped periodically, so going back to just streaming data might be more reliable, but that's how I was getting dropouts at the start anyways.

I'm not packing a packet number in, so unless the xbee is, there isn't one. I've tried to keep the messages as small/tight as possible, so I'm sending all my sensor values as bytes. I'm sending a 20-byte message per 'go', though I'm sure the xbee sticks some stuff on top of that for what it does.

Go Up