Xbees doesn't work more than 15m apart

Hello!

My RC Plane project hit another obstacle. I have a setup like this,

XBee ZigBee S2 RF(wired antenna, they have promissed 120m outdoor range) modules connected to arduino via funduino XBee shields. They are setup as Point-to-point communication.

My Transmitter is a Mega2560 and Receiver is an Uno.

This is the code for Transmitter:

 /* TX
 * using elevons?
 * have 2 servos for 2 elevons, ignore aileron.
 */
 
#define aileron 2
#define elevon 3
#define esc 4

#define elevontrim 0
#define ailerontrim 1
#define esctrim 5

#define signalLED 13

int ailerontrimVal,elevontrimVal,aileronVal,elevonVal,esctrimVal,escVal;

void setup()
{
  Serial.begin(9600);//1152200 only 9600 works, check XBEE forum
  pinMode(signalLED,OUTPUT);
}

void loop()
{
  aileronVal = analogRead(aileron);
  aileronVal = map(aileronVal, 0, 1023, 0, 179);
  ailerontrimVal = analogRead(ailerontrim);
  ailerontrimVal = map(ailerontrimVal, 0, 1023, -25, 25);
  aileronVal = aileronVal+ ailerontrimVal;
  constrain(aileronVal, 0, 179);
  
  elevonVal = analogRead(elevon);
  elevonVal = map(elevonVal, 0, 1023, 0, 179);
  elevontrimVal = analogRead(elevontrim);
  elevontrimVal = map(elevontrimVal, 0, 1023, -25, 25);
  elevonVal = elevonVal+ elevontrimVal;
  constrain(elevonVal, 0, 179);

  escVal = analogRead(esc);
  escVal = map(escVal, 0, 1023, 0, 179);
  esctrimVal = analogRead(esctrim);
  esctrimVal = map(esctrimVal, 0, 1023, -25, 25);
  escVal = escVal+ esctrimVal;
  constrain(escVal, 0, 179);
  
  Serial.print("L");
  Serial.print(aileronVal);
  Serial.print("R");
  Serial.print(elevonVal);
  Serial.print("S");
  Serial.print(escVal);
  delay(10);
  
  /*if(Serial.available())
  {
    if(Serial.read() == 1)
      digitalWrite(signalLED,HIGH);
    else
      digitalWrite(signalLED,LOW);
  }*/
    
}

This is the code for Receiver:

/* RX
 * State machine
 * 2 servos, esc. extend if a rudder is needed, currently using a servo for esc as well
 */
 
 #include <Servo.h>
 
 #define laileron 11
 #define raileron 10
 #define throttle 9
 
 typedef enum{NONE,GOT_L,GOT_R,GOT_S} states;
 Servo left,right,esc;
 states state = NONE;
 unsigned int currentValue;
 unsigned long successfulMillis;
 
 void setup()
 {
   pinMode(13,OUTPUT);
   digitalWrite(13,LOW);
   Serial.begin(9600); //1152200 only 9600 works, check whats wrong
   state=NONE;
   left.attach(laileron);
   right.attach(raileron);
   esc.attach(throttle);
 }
 
 void processLeft(const unsigned int value)
 {
   left.write(value);
   //Serial.print(1);
   //delay(10);
 }
 
  void processRight(const unsigned int value)
 {
   right.write(value);
   //Serial.print(1);
   //delay(10);
 }
 
  void processEsc(const unsigned int value)
 {
   esc.write(value);
   //Serial.print(1);
   //delay(10);
 }
 
 void hanldlePreviousState()
 {
   switch(state)
   {
     case GOT_L:
       processLeft(currentValue);
       break;
     case GOT_R:
       processRight(currentValue);
       break;
     case GOT_S:
       processEsc(currentValue);
       break;
   }
   currentValue=0;
 }
 
 void processIncomingByte(const byte c)
 {
   if(isdigit(c))
   {
     currentValue *= 10;
     currentValue += c-'0';
   }
   else
   {
     hanldlePreviousState();
     
     switch(c)
     {
       case 'L': state=GOT_L;
         break;
       case 'R': state=GOT_R;
         break;
       case 'S': state=GOT_S;
         break;
       default: state=NONE;
     }
   }
 }
 
 void defaults()
 {
   left.write(90);
   right.write(90);
   esc.write(0);
   digitalWrite(13,HIGH);
   while(true);
 }
 
 /*void signalLossProtocol(int attempts)
 {
   if(Serial.available()<=0)
   {
     attempts++;
     delay(500);
     if(attempts<11)
       signalLossProtocol(attempts);
     else
     {
       defaults(); 
       while(1>0);//exit(0); forum advices not to do so. check if works
     }
   }
 }*/
 
 void signalLossProtocol()
 {   
   /*while(millis()-successfulMillis<5000)
   {
     if(Serial.available()>0)
       return;
   }*/
  defaults();
 }
 
 void loop()
 {
   if(Serial.available()>0) //>0 not needed?
     {
       digitalWrite(13,LOW);
       processIncomingByte(Serial.read());
       successfulMillis = millis();
     }
   //else
   if(millis()-successfulMillis>5000)
   {
     defaults();
     while(true);
   }
 }

Please ignore my comments!
I have connected all the servos to the 5v pin and respective PwM pins at the receiver end (outdoor test done with only one servo).
I have POTs at the transmitter end wich sends the analog signal to the receiver.

I tested my setup like this. My friend took the receiver end while i was turning the POTs at the transmitter end. They work great at a close range but when my friend took the receiver longer than 15m the Servos start to turn at their will. even after he came close the servos does not respond. I had to kill the power to the transmitter and restart it again to get that to work even at the close range.

I thinks this could still be a programming issue (since they work at close range).

Am I using my delays correctly?

And i found out that if I don’t have enough power to the XBees they could loose the range too. how would i check the power coming to XBEE?

I thinks this could still be a programming issue (since they work at close range).

How could it be? If the code works when the XBees are close together, it will work when they are far(ther) apart.

What is powering the copter? What is motivating the copter? I think you have noise/interference issues.

how would i check the power coming to XBEE?

With a multimeter.

I would test the XBees on their own to determine what is the actual communication range.

Are you using AT mode or API mode?

First thing to look for would be packet loss. For example, you could connect two XBees to two laptops and try to repeatedly send "QWERTY" or any other sequence at different distances. Try to find at which distance you start losing packets.

Another thing to look into is delay. I think that in API mode, the packet is retransmitted if no confirmation arrives. Still, retransmissions add a delay that may interfere with the right operation of your project.

What is the configuration of your XBees? Are you using unicast or broadcast messages? In our experience, unicast works faster and more reliably than broadcast.

Actual range can change with the presence of interferences. If XBee use the crowded of 2.4 GHz band, the existence of wifi, bluetooth and other technologies can reduce the reliability and range of the XBees.

I would test the XBees on their own to determine what is the actual communication range.

So using a XBee explorer at each XBee on different Laptops?

Are you using AT mode or API mode?

I am using AT mode

irst thing to look for would be packet loss. For example, you could connect two XBees to two laptops and try to repeatedly send “QWERTY” or any other sequence at different distances. Try to find at which distance you start losing packets.

I will do that and let you know.

Another thing to look into is delay. I think that in API mode, the packet is retransmitted if no confirmation arrives. Still, retransmissions add a delay that may interfere with the right operation of your project.

Since I am using AT mode i shouldn’t consider about this I guess. I originally have a 10ms delay at my transmitter end. otherwise the Servos start acting crazy after a little time regardless of the distance.

What is the configuration of your XBees? Are you using unicast or broadcast messages? In our experience, unicast works faster and more reliably than broadcast.

This is in Unicast mode since I have interchanged the DL DH with SL SH of the modules? Thats the way to do that right? I know this method as Point-to-point comm.

Actual range can change with the presence of interferences. If XBee use the crowded of 2.4 GHz band, the existence of wifi, bluetooth and other technologies can reduce the reliability and range of the XBees.

I guess we don’t have reception of any WiFi or BlueTooth, I have tried with y laptop. It is a rugger ground so clears as an open area right?

I will test the sequence and let you know when we start to loose the packets ok?

Thanks!

Well I just did the range test on X-CTU it all gives me bad signals, not even one is good. even though they are close!

bhashithe:
Well I just did the range test on X-CTU it all gives me bad signals, not even one is good. even though they are close!

I guess this explains why your project was not working.

We have a meetup today. If there is interest from the participants, we can try to repeat your tests with our equipment and our environment, to see if our observations match your results. But I can't promise anything.

It seems that the performance of the XBees might not be good enough for some radio-control projects.

So this couldn’t be a power issue? :open_mouth:

I don't know, honestly.

I read Faludi's book and I don't remember anything about power issues. The book always powered the XBee using the 3.3V output of the arduino. O I guess that should be ok.

I know that there are other models of XBee (XBee Pro) that use higher power and lower frequencies for longer communication distances.