Pages: [1]   Go Down
Author Topic: Xbee random freezing  (Read 2149 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Newbie
*
Karma: 0
Posts: 5
I like c++
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi,
So, I just got my hands on a pair of Xbee Radios awhile back, and they worked fine for regular use until now...
I'm working on a robot project right now (sadly, it can't be autonomous  smiley-cry ) and I'm using the Xbees for the remote.
The communications code is rather simple, 5 bytes total (command, motor number, direction, velocity (raw value), EOT byte).
Now, this all works great (code runs, tests out) until I put the Xbees in. Everything works fine for awhile, but some random amount of time later the remote stops working. No message in LED on the robot (my code flashes it for a good message), No RSSI Indication on the Xbee explorer (sparkfun). However, the DIN light on the remote's Xbee explorer is flashing (oddly, the TX/RX LEDs on the same unit don't), so I'm drifting away from the code being the problem..
For some background:
I'm using Hardware serial at both ends (the remote also uses NewSoftSerial for a LCD, if that matters) at 115200 baud. I've tried lower baud rates to the same results.
Each Xbee is Identical, Series 1 PRO, and I'm not in a very noisy RF environment AFAIK, the error counters are low on the units as well (I think only 3 ACK Failures, probably from when I range tested them at school). Direct communication between them works alright (as in USB Explorer <=> Xbee <=> Xbee <=> FTDI Basic)

What would cause the units to "freeze" up like this?

Thanks,
Matt M., KD8OOS
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 601
Posts: 48543
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Even though the XBees are pretty reliable, it is still possible to bytes to get lost. If you are not properly syncing on the end of a packet (the start would be better), you can get out of sync. Whether or not you are properly syncing, though, is a mystery since you didn't post your code.
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 5
I like c++
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

What do you mean by syncing up? I thought that would be taken care of by the xbee as long as it's operating in transparent mode?

Quite frankly, I can get by if I'm losing data every once and awhile (I can make up for it), but I can't fix this without reconnecting power to the board, which can't happen once this is put in use.

Here's the Transmitter Function (this is the only time in the program that something is printed to the serial port):
Code:
int testSliderMove(int current, int last, int lower, int upper, int slider) // look to see if a slider has moved at all (right=1 or left=0)
{
  //if it moved at all, we must do *something*
  if ((current > last + potSesitivity) || (current < last - potSesitivity))
  {
    //check if it's centered first...
    int centerline = ((upper - lower)/2)+lower; //mark the centerline
    if (current >= centerline - sliderCenterWidth/2 && current <= centerline + sliderCenterWidth/2)
    {
      //dump to lcd
      writeLn("                    ", slider+2);
      writeLn("", slider+2);
      lcd.print(slider == 0?"LEFT":(slider == 1?"RIGHT":"CENTER"));
      lcd.print(" Val: *CENTER*");
      //tx out the serial line
      Serial.print(slider == 0?"LCD":"RCD");
    }//done with center check
    else // then the slider has obvously moved some distance outside center
    {
      //write to lcd
      writeLn("                    ", slider+2);
      writeLn("", slider+2);
      lcd.print(slider == 0?"LEFT":(slider == 1?"RIGHT":"CENTER"));
      lcd.print(" Val: ");
      lcd.print(current-lower-centerline);
      //tx out serial line (This is the Important part!)
      Serial.print(slider);
      Serial.print("S"); // "Left Set" Command
      Serial.print(current-lower-centerline>0?"F":"R");
      Serial.print(map(abs(current-lower-centerline), 0, centerline-lower, 0, 255), BYTE); // dump as Binary value (easier to decode on remote micro)
      Serial.print("D"); // "Command Done"
    }//done with position set
    return current; //return the current value, as it has moved
  }
  return last;//return the last value as is has not moved
}

And here is the Reciever Code (I'm using servos for now, eventually it will be two h-bridges)

Code:
void processSerialMessage()
{
  bool processGood = false;
  //read in ALL Serial Data until a D char (End of message)
  unsigned char byteArray[30];
  int counter = 0;
  long timeout = millis() + 500;
  bool continueProcess = true;
  while (true)
  {
    if (Serial.available())
    {
      byteArray[counter] = Serial.read();
      if (byteArray[counter] == 'D')
        break;
      counter ++;
    }
    if (millis() > timeout)
    {
      continueProcess = false;
      break;
    }
  }
  if (continueProcess)
  {
    /*Serial << "Got: ";
    for (int i = 0; i<counter; i++)
    {
      Serial << byteArray[i];
    }*/
    //check for each message type
    if (byteArray[counter -1] == 'K' && byteArray[counter - 2] == 'O') // the OK message
    {
      processGood = true;
    }
    else if (byteArray[counter-1] == 'T' && byteArray[counter - 2] == 'I' && byteArray[counter - 3] == 'N' && byteArray[counter - 4] == 'I')
    {
      Serial << "OKD";
      processGood = true;
    }
    else if (byteArray[counter-3] == 'S')
    {
      digitalWrite(statusLight, HIGH);
      int posMsg = byteArray[counter-1]; // set a byte var to the pos data
      // the following code is specific to the system drive method, it all depends on the drive system
      posMsg = map(pow(posMsg, 2), 0, 65025, 0, 90); // map the value to 0-90 (for servos)
      posMsg= abs(posMsg + (byteArray[counter-2] == 'F'?90:-90)); // add 90 if we want to go forward, subtract to go backaward
      processGood = true;
      if (byteArray[counter-4] == '0')
      {
        leftWheel.write(posMsg);
      }
      else if (byteArray[counter-4] == '1')
      {
        rightWheel.write(180 - posMsg);
      }
      else
      {
        processGood=false;
        sysOK = false;
      }
      //END system specific code
      digitalWrite(statusLight, LOW);
    }
    if (byteArray[counter-1] == 'C') // Center Message
    {
      processGood = true;
      switch (byteArray[counter-2])
      {
        case 'L':
        leftWheel.write(90);
        break;
        case 'R':
        rightWheel.write(90);
        break;
        default:
        processGood = false;
        break;
      }
    }
    else
    {
      processGood = false;
    }
   
    if (processGood == true)
    {
      lastActivityMillis = millis(); // set the last active millis if the system is OK and the incoming data was processed OK
      sysOK = true;
      qryWaiting = false;
    }
  }
}
(I'm still not that good at writing very clean code  smiley-sad , is there some crucial thing I missed here?)
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 601
Posts: 48543
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
  while (true)
  {
    if (Serial.available())
    {
      byteArray[counter] = Serial.read();
      if (byteArray[counter] == 'D')
        break;
      counter ++;
    }
    if (millis() > timeout)
    {
      continueProcess = false;
      break;
    }
  }
should be
Code:
  while (Serial.available() && millis() < timeout)
    {
      byteArray[counter] = Serial.read();
      if (byteArray[counter] == 'D')
        break;
      counter ++;
    }
  }
At this point, byteArray[counter] is either 'D', and the byteArray can be used, or it isn't, and we need to ignore what we have received so far, since it took to long to send the packet.

Code:
    /*Serial << "Got: ";
    for (int i = 0; i<counter; i++)
    {
      Serial << byteArray[i];
    }*/
Why is this commented out? Your code is not yet working correctly, or else the robot wouldn't be freezing up.

Code:
    if (byteArray[counter -1] == 'K' && byteArray[counter - 2] == 'O') // the OK message
This would make more sense as
Code:
    if (byteArray[counter - 2] == 'O' && byteArray[counter - 1] == 'K') // the OK message

Code:
    else if (byteArray[counter-1] == 'T' && byteArray[counter - 2] == 'I' && byteArray[counter - 3] == 'N' && byteArray[counter - 4] == 'I')
Suppose counter is 2. What do you suppose is in counter[-1] or counter[-2]? What do you suppose happens when you reference a location outside the bounds of your array?

Code:
pow(posMsg, 2)
This is a very expensive way to compute posMsg * posMsg.

What are leftWheel and rightWheel? Are they Servo instances? If so, what kind of "servos" are they? If they are continuous rotation servos, the write method won't work. You need to use the writeMicroseconds method, instead.
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 5
I like c++
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

While my code is somewhat unorthodox, inefficient, and questionable, it does work and I have tested it without the Xbee to complete success. I will take your suggestions into consideration, but I have my reasons for many of those issues.

My problem is that the Xbee is locking up, there is no indication of reception at all by the receiving unit. It isn't sporadic (e.g. dropped packets), it's complete failure. Resetting the uC doesn't help, so it isn't like the code is locking up. Plus, If I hook the receiving Xbee to X-CTU it responds OK (as in I can get the firmware info). It only happens to the sending unit, switching them out makes no difference.

I sincerely hope you understand my view here, and I greatly appreciate your help with this.

It sounds unlikely, but could I accidentally be sending some kind of command sequence to the modem without knowing it? Did I switch to some kind of command mode?
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 601
Posts: 48543
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
It sounds unlikely, but could I accidentally be sending some kind of command sequence to the modem without knowing it? Did I switch to some kind of command mode?
No. At least, I doubt it. The XBees replace a wire between the sender and receiver. They may, although it is unlikely, inject data into the serial stream being sent (to the sender). Your sending application really should be extended to show what serial data it receives. If it receives any, it might reveal what is happening.

In addition, you can echo what you receive on the receiver.

However, this statement is a concern.
Quote
My problem is that the Xbee is locking up, there is no indication of reception at all by the receiving unit. It isn't sporadic (e.g. dropped packets), it's complete failure. Resetting the uC doesn't help, so it isn't like the code is locking up.
The XBee is also reset when the uC is reset, so, even if it did enter some kind of command mode, resetting it should get it out of that mode.

There is no RSSI indicator on the XBee explorer. There are 3 lights - TX, RX, and associate. The associate light blinks differently (supposedly) when there is communication between two XBees, or not. The TX light flashes whenever the XBee is transmitting data. The RX light flashes whenever it is receiving data.

When the XBee seems to lock up, does the associate light pattern change? Does the TX light stop flashing?

How is the XBee connected to the Arduino? Using a shield? Which one? Most of them have the same three lights. Do the associate and RX lights change behavior when the XBee "locks up"?

How DO you get the XBee receiving again?
Logged

North Yorkshire, UK
Offline Offline
Faraday Member
**
Karma: 104
Posts: 5531
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The sparkfun XBee explorer boards are not too great for XBees more powerful than the series 1 modules.

See the comments on the sparkfun page for example.

This may be what is causing the issue, especially if you have the older boards with the low power regulators on them.
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 5
I like c++
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I'm connecting to the Xbee without a shield. I'm using this: http://www.sparkfun.com/products/9132 on both ends then connecting the DIN and DOUT Pins to TX and RX of the arduino, respectively. one adapter board is newer than the other, The date on the newer board (bottom copper layer) is 8-7-09, so it's probably the older VReg (the lettering on the IC is LG33). So, as mowcius suggested, that could be the issue.
Would it be possible to use a lower transmit power mode on the Xbee? (I think there's an AT command for that...)
I have not used the reset pin of the Xbee (there is one broken out), should I pull it high (3.3v?) or low?

Both boards have 4 LEDs:
-PWR (always on, even when there is no Xbee)
-DIN which flashes on incoming data to the modem even when it's "locked up"
-DOUT
-"RSSI"; which is only on when receiving from the other Xbee (it goes out shortly after the data stops, it has never blinked for me).

The only way I can get the sending unit working again is to remove power from the Xbee, however I haven't tried doing anything to the reset pin yet, I'll try and do that later tonight.

I'm beginning to think that the problem with the Voltage regulator being too small might be my issue here...
Logged

North Yorkshire, UK
Offline Offline
Faraday Member
**
Karma: 104
Posts: 5531
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Reset pin should be taken low.

If you can connect to a computer then you can use X-CTU to configure the transmit power - there is an AT command for it but I can't say I know what it is.
Logged

North Yorkshire, UK
Offline Offline
Faraday Member
**
Karma: 104
Posts: 5531
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I've actually had some major issues with my own XBees now - XBee Pro ZB modules on home made single sided breakout boards. :s
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 5
I like c++
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Reset pin should be taken low.

If you can connect to a computer then you can use X-CTU to configure the transmit power - there is an AT command for it but I can't say I know what it is.

From the data sheet, it looks like the reset pin is Asserted Low, so it didn't work for me when the RST pin was pulled low.
However, resetting the Xbee while it was "locked up" did make it work again.

I tried updating the firmware too (in X-CTU), which didn't make any noticeable changes. FWIW, the version on both modems in 10E6.

Maybe my application is just sending too much data at one time... Would it be beneficial to send the control data at a fixed refresh rate instead? (Rather than whenever it changes, which is prone to jitter and dropped packets)
Logged

North Yorkshire, UK
Offline Offline
Faraday Member
**
Karma: 104
Posts: 5531
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I have experienced the same issue now. Looking into it.

My XBee is also sending random characters down the serial port on startup.

I appear to be getting loads and loads of dropped packets...
Logged

Pages: [1]   Go Up
Jump to: