P2P communication with Xbee series 2

Hello,

As a simple exercice, i'm trying to move a servo with a potentiometer wirelessly. I have a pair of Xbee series 2, and i have not been able to have them communicate with each other.

Following a tutorial found on the web, I set one of the Xbees in the Coordinator AT function, and the other in End device AT (with X-CTU). But when i power the Arduinos, it does not work. The code source is unlikely to be faulty, as i copypasted it from Blum's website.

Any help will be welcome.

I'd configure the one as Router AT, unless there was a specific need for an End Device (sleeping to save power, etc.) Set DH and DL on each XBee to be the other's address and I think that's all there should be to it.

Thanks for your answer.

It's still like before however: the servo occasionaly moves, randomly (more like jiggles), but doesn't respond to the potentiometer input. Just in case, here are the source codes (i made some minor changes on the original code).

Potentiometer:

//Define Pins
int potPin = 5;

void setup()
{
  //Create Serial Object (9600 Baud)
  Serial.begin(9600);
}

void loop()
{
  int val = map(analogRead(potPin), 0, 1023, 0, 180);
  Serial.println(val);
  delay(50);
  
}

Motor:

//Include Servo Library
#include <Servo.h>

//Define Pins
int servoPin = 9;

//Create Servo Object
Servo jeremysServo;

void setup()
{
 //Start Serial
 Serial.begin(9600);
  
  //Attaches the Servo to our object
  jeremysServo.attach(servoPin);
  
  delay(500);
}

void loop()
{  

  while( Serial.available() == 0);
  int data = Serial.read() -'5';

  int pos = map(data, 0, 1023, 0, 180);

  //Turn the servo
  Serial.println(pos);
  jeremysServo.write(pos);
  Serial.flush();  
    
}

A couple things. In the second sketch, are you sure that

  int data = Serial.read() -'5';

gives the intended value?

Also, the first sketch maps the analog input value to a number between 0 and 180 then sends it over the XBee. The second sketch then also maps it. A second mapping should not be necessary, yes?

One more thing.

  int data = Serial.read() -'5';

only reads a single byte of data. What if the first sketch sends a value like 42 (two bytes)? Or 120 (three bytes)?

Edit: And what does '5' have to do with anything?

I tried to implement the changes you suggested, but i'm afraid it still doesn't work (only jiggles) :

motor:

void loop()
{  

  while( Serial.available() == 0);
  int data = Serial.read();

  //Turn the servo
  Serial.println(data);
  jeremysServo.write(data);
  Serial.flush();  
  
}

What i don't understand with this code is why the "val" input from the potentiometer isn't used. I'm quite new with all this, as you surely noticed, so i don't know if it is normal.

Several things now that I looked at it again.

  1. The pot must be on an analog pin (A0-A5).
  2. A single byte is all we need to communicate an integer between 0 and 180.
  3. The motor code should not do Serial.print, as that sends data back to the potentiometer unit, and it's not expecting any input.

Try these. Move the pot to pin A0 first.

EDIT: int potPin = 5 is ok, assuming pot is connected to A5. I always forget that works. Confusing IMHO, I always use A0-A5 to be clear.

//potentiometer code

//Define Pins
int potPin = A5;    //pot must be on an analog pin

void setup()
{
  //Create Serial Object (9600 Baud)
  Serial.begin(9600);
}

void loop()
{
  delay(100);
  //since we want a number between 0 and 180, that fits
  //nicely into a byte variable (8-bit, unsigned).
  //so the message consists of a single character (byte).
  byte val = map(analogRead(potPin), 0, 1023, 0, 180);
  Serial.write(val);    //send it over the link in binary
}
//servo code

#include <Servo.h>

//Define Pins
int servoPin = 9;

//Create Servo Object
Servo jeremysServo;

void setup()
{
 //Start Serial
 Serial.begin(9600);
  
  //Attaches the Servo to our object
  jeremysServo.attach(servoPin);
  
  delay(500);
}

void loop()
{  

  while( Serial.available() == 0);
  byte pos = Serial.read();

  //Turn the servo
  jeremysServo.write(pos);
    
}

Confusing IMHO, I always use A0-A5 to be clear.

The A0 to A5 aliases were meant to be used when the analog pin is used as a digital pin. In my opinion, analogRead(A0) is MORE confusing. It makes it appear that the user doesn't really know what pin to use.

Not that that applies to you, but some others, I'm not so sure about.

PaulS:

Confusing IMHO, I always use A0-A5 to be clear.

The A0 to A5 aliases were meant to be used when the analog pin is used as a digital pin. In my opinion, analogRead(A0) is MORE confusing. It makes it appear that the user doesn't really know what pin to use.

Not that that applies to you, but some others, I'm not so sure about.

Different horses I guess. I probably use A0-A5 since those are the labels on the Uno board. My preference would be one pin, one name. But that's the nice thing about standards, there are so many to choose from.

//pick one, they're all the same:
analogRead(A2);
analogRead(16);
analogRead(2);

//pick one, they're all the same:

For a given board, yes. Not for all boards, which was why the analog-as-digital aliases were created.

Many thanks, it's working now. :slight_smile:

I have one more little question : there's always a delay of 1-2 seconds between the order and the execution by the servo. I reduced the delays in the code but it makes little difference. Is there a way to fix this ?

PaulS:

//pick one, they're all the same:

For a given board, yes. Not for all boards, which was why the analog-as-digital aliases were created.

Ah, right. Makes sense.

N_Tesla:
Many thanks, it's working now. :slight_smile:

I have one more little question : there's always a delay of 1-2 seconds between the order and the execution by the servo. I reduced the delays in the code but it makes little difference. Is there a way to fix this ?

Not sure. It should be so fast as to appear instantaneous. Does DH and DL for the XBee on the potentiometer end equal SH and SL for the XBee on the servo end?

Does DH and DL for the XBee on the potentiometer end equal SH and SL for the XBee on the servo end?

And are they non-zero on both ends? 0 is the broadcast address, and broadcast communications are lower priority than directed communications.

PaulS:

Does DH and DL for the XBee on the potentiometer end equal SH and SL for the XBee on the servo end?

And are they non-zero on both ends? 0 is the broadcast address, and broadcast communications are lower priority than directed communications.

Yes, and broadcast also causes more network overhead.

I had the parts handy, so I tossed it together, worked fine for me with the code I posted above. Even with the 100ms delay response seems immediate.

I had used the defaults settings, indeed. Now the destinations and serials are cross-matched, it works as expected, with no noticeable delay. :slight_smile:

Thank you very much for your help and your patience, guys.

I had used the defaults settings, indeed.

What were the default settings?

PaulS:

Does DH and DL for the XBee on the potentiometer end equal SH and SL for the XBee on the servo end?

And are they non-zero on both ends? 0 is the broadcast address, and broadcast communications are lower priority than directed communications.

Actually, for S2 XBees,

Special definitions for DH and DL include 0x000000000000FFFF (broadcast) and
0x0000000000000000 (coordinator).

So the end with the router can have DH=DL=0 and it should work fine, I actually do this a lot. However, since in this case the comm is one-way, it really doesn't matter (assuming the end with the pot has the coordinator). Put the coordinator on the end with the servo, and then both XBees could be left at the default setting of DH=DL=0.

Edit: Note simplest XBee S2 configuration for one-way transparent operation consists of simply loading coordinator firmware on one XBee and Router firmware on another, and then using the Router as the sending end. Assuming no other networks are in operation, this should be all that is required. If there are other XBee networks, then set the PAN ID for both units to some value different from the other network(s). I always like to set a unique PAN ID anyway, but the default value of zero should work fine as this causes the coordinator to select a random PAN ID and the router to join any PAN ID available.

N_Tesla:
I had used the defaults settings, indeed. Now the destinations and serials are cross-matched, it works as expected, with no noticeable delay. :slight_smile:

Thank you very much for your help and your patience, guys.

Sweet! Glad it works for you!