Controlling 2 servos by 2 potentiometers via xbee

I'm trying to practice a bit more with XBees, and I wanted to try to use 2 potentiometers connected to one arduino to control 2 servo motors connected to another arduino via xbee. I'm using XBee series 1.

I saw the EasyTransfer library and thought that maybe this is the best way to go for a beginner like me.

For the sender part:

#include <EasyTransfer.h>
EasyTransfer ET;

int potpin1 = 0;
int potpin2 = 1;

struct SEND_DATA_STRUCTURE{
  int servo1val;
  int servo2val;
};

SEND_DATA_STRUCTURE txdata;

void setup(){
  Serial.begin(115200);
  ET.begin(details(txdata), &Serial);
  pinMode(potpin1, INPUT);
  pinMode(potpin2, INPUT);
 
}

void loop(){
  txdata.servo1val = analogRead(potpin1);
  txdata.servo2val = analogRead(potpin2);
 
  ET.sendData();
  
}

For the receiving side:

#include <Servo.h>

#include <EasyTransfer.h>
EasyTransfer ET;

Servo myservo1;
Servo myservo2;


struct RECEIVE_DATA_STRUCTURE{
  int servo1val;
  int servo2val;
};

RECEIVE_DATA_STRUCTURE txdata;

void setup(){
  Serial.begin(115200);
 
  ET.begin(details(txdata), &Serial);
  myservo1.attach(9);
  myservo2.attach(10);
}

void loop(){
  if(ET.receiveData()){
   
    myservo1.write(map(txdata.servo1val, 0, 1023, 0, 179));
    myservo2.write(map(txdata.servo2val, 0, 1023, 0, 179));
    
  }
}

I tried the code but nothing happens :S

Can you guys please tell me what I'm doing wrong? Thanks in advance

int potpin1 = 0;
int potpin2 = 1;

void setup()
{
  pinMode(potpin1, INPUT);
  pinMode(potpin2, INPUT);

The pinMode() function doesn't even know that the Arduino has analog pins, since those pins are input only. You just diddled with the Serial pins. Not a good idea, at all.

It would be a lot simpler to do the mapping BEFORE sending, so you are sending half as much data.

How are the XBees configured? How are they connected to the Arduinos?

The pinMode() function doesn't even know that the Arduino has analog pins, since those pins are input only. You just diddled with the Serial pins. Not a good idea, at all.

Yes, I will definitely change that.

It would be a lot simpler to do the mapping BEFORE sending, so you are sending half as much data.

That is also another modification that I wanted to try implementing.

How are the XBees configured? How are they connected to the Arduinos?

The XBees were configured by X-CTU and I've tested them before and they work fine.
I'm using the Sparkfun XBee shield to connect them to the Arduinos

hi i was going through this post and i am having the same problem, i am using a different set of codes given below

sender code 

[int potpin =0;
void setup()
{
  Serial.begin(9600);
}

void loop()
{
  int val = map(analogRead(potpin), 0, 1023, 0, 9);
  Serial.print(val);
  delay(50);
receiver code

 
[#include <Servo.h>

Servo hand;

void setup()
{ Serial.begin(9600);
hand.attach(9);
}
void loop()
  {
  while (Serial.available()==0);
  int data =Serial.read()-'0';
  int pos = map(data , 0, 1023, 0, 180);
  pos = constrain(pos, 0 ,180);
  
  hand.write(pos);
  while(Serial.available()>0);
  Serial.read();
  }

after uploading both these codes i am not able to move my servo

i used Putty to program my xbees
any suggestions, can anybody please explain what i am doing wrong

int data =Serial.read()-'0';
  int pos = map(data , 0, 1023, 0, 180);
  pos = constrain(pos, 0 ,180);

Your map range is wrong for an input range of only 0..9.

Please use code tags when posting code.

after uploading both these codes i am not able to move my servo

That's hardly surprising.

  int val = map(analogRead(potpin), 0, 1023, 0, 9);
  Serial.print(val);

The sender is sending '0', '1', ... , or '9', depending on what setting the potentiometer is in.

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

On the receiver, data will be 0, 1, 2, ... , 8 or 9.

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

A value in the range 0 to 9 is mapper as though it was in a range 100 times as large. Even the largest value in the actual range will map to 0.

  hand.write(pos);
  while(Serial.available()>0);
  Serial.read();

The only position you ever write to the servo is 0.

Then, if there is another character to read, you enter an endless loop. Fortunately, there isn't. But, you read one any way.

Try again. This time, pay attention.

It finally works!

I did the modifications, and also re-programmed my XBees.

Thanks for the help!

thanks for the valuable input i was able to make it work; but i have a new problem and i don't know how to solve it

special thanks to PaulS

i am trying to control three different servos using three different pots

so i wrote the code assigning three different pots and servos, but i am unable to setup the individual links between the pots and the servo
when i upload the following codes, and when one pot is turned all three servos turn, which is not what i am looking for

could somebody explain how i can set up a wireless link between, for eg. analog pin 0 and PWM pin 9 etc

thanks a lot

sender end

int potPin_0 = 0;
int potPin_1 = 1;
int potPin_2 = 2;

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

void loop()
{
  int val_0 = map(analogRead(potPin_0), 0, 1023, 0, 9);
  Serial.print(val_0);
  delay(50);
  
  int val_1 = map(analogRead(potPin_1), 0, 1023, 0, 9);
  Serial.print(val_1);
  delay(50);
  
  int val_2 = map(analogRead(potPin_2), 0, 1023, 0, 9);
  Serial.print(val_2);
  delay(50);
  
}
receiver end

#include <Servo.h>

//Define Pins
int servoPin_0 = 8;
int servoPin_1 = 9;
int servoPin_2 = 10;

//Create Servo Object
Servo orangeServo;
Servo wristServo;
Servo gripperServo;

void setup()
{
 //Start Serial
 Serial.begin(9600);
  
  //Attaches the Servo to our object
  orangeServo.attach(servoPin_0);
  wristServo.attach(servoPin_1);
  gripperServo.attach(servoPin_2);
  
  delay(500);
}

void loop()
{  

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

  int pos_0 = map(data_0, 0, 9, 0, 180);
  pos_0 = constrain(pos_0, 0, 180);

  //Turn the servo
  Serial.print(pos_0);
  orangeServo.write(pos_0);
  while(Serial.available()>0);
  Serial.read(); 
  
  
  while( Serial.available() == 0);
  int data_1 = Serial.read() -'0';

  int pos_1 = map(data_1, 0, 9, 0, 180);
  pos_1 = constrain(pos_1, 0, 180);

  //Turn the servo
  Serial.print(pos_1);
  wristServo.write(pos_1);
  while(Serial.available()>0);
  Serial.read(); 
  
  
  while( Serial.available() == 0);
  int data_2 = Serial.read() -'0';

  int pos_2 = map(data_2, 0, 9, 0, 180);
  pos_2 = constrain(pos_2, 0, 180);

  //Turn the servo
  Serial.print(pos_2);
  gripperServo.write(pos_2);
  while(Serial.available()>0);
  Serial.read(); 
  
  
  
}
 while(Serial.available()>0);
  Serial.read();

As pointed-out above, you're waiting for a character to become available, reading it, but throwing away the value.
Why?

Even when you've fixed this problem, you've got a problem of synchronisation - you can't tell which decimal digit is destined for which servo, and if you miss a character, you'll control the wrong servo.
You could implement a simple encoding mechanism, if you're wedded to the single ASCII character, so '0'..'9' are destined for servo 0, 'A'..'J' for servo 1 and 'a'..'j' for servo 2.

while(Serial.available()>0);
  Serial.read();

i am using this to flush out any unwanted data

i guess the above code replaces

Serial.flush();

in arduino 1.0

also my aim is to move the servo in nine steps from 0 - 180

if i am reading multiple characters i guess i will not be able to use

while(Serial.available()>0);
  Serial.read();

so what changes should i make

thanks

i am using this to flush out any unwanted data

How do you know it is unwanted?

In 1.0, flush affects the output queue, not the input.

so do you mean to say if i don't use

Serial.flush();

i can achieve what i am looking for ?

I don't know - I don't know what it is you're looking for (but whatever it is, it'll be in the last place you look, so look there first)

I don't really understand why you're limiting yourself to just 10 positions per servo.

As pointed-out above, you're waiting for a character to become available, reading it, but throwing away the value.
Why?

Actually, that is not waiting for data to become available. It enters an infinite loop IF there IS data available (that semicolon on the end is the body of the statement). Really not advised.

Of course, neither is reading and discarding one of the valuable bytes sent.

OP: Now that you can send and receive, it's time to learn how to send and receive strings, so you can send a value like 1023, or to send and receive bytes, as binary data, so you can map the pot value to a position and Serial.write() that byte.

I don't know what it is you're looking for

-9
i want to control two servos using two different pots... at the moment when i use the code all servos turn when i turn on pot which is not what i want.

for eg. i want the pot at A0 to only control one servo attached to pin9 etc.

I don't really understand why you're limiting yourself to just 10 positions per servo.

this is because i want the servo to move in only 9 steps. i am using it to control a robotic arm

could somebody please help, at the moment, i am able to move ALL servos with just one pot

what i want to do is to control one servo using only one pot and the other servo using another pot .

how do i set this link?

thanks in advance

Have you fixed any of the issues that have been pointed out? If so, post your current code. If not, well, you know what you need to do.

ya i fixed my first issue of not being able to communicate with the xbee. I was able to move the servo with the help of a pot, no issues with that.

but now i want to add another set of pot and servo for which i wrote the program, the same has been posted above,

my current problem is that when i move one pot all the servos move, although they have been assigned to different pots, i just want one pot to move one servo

in the program posted i am trying to do it but i am unable to do so, not sure why.

for your convenience i am posting the code here again

 Sender code
int potPin_0 = 0;
int potPin_1 = 1;
int potPin_2 = 2;

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

void loop()
{
  int val_0 = map(analogRead(potPin_0), 0, 1023, 0, 9);
  Serial.print(val_0);
  delay(50);
  
  int val_1 = map(analogRead(potPin_1), 0, 1023, 0, 9);
  Serial.print(val_1);
  delay(50);
  
  int val_2 = map(analogRead(potPin_2), 0, 1023, 0, 9);
  Serial.print(val_2);
  delay(50);
  
}
receiver end

#include <Servo.h>

//Define Pins
int servoPin_0 = 8;
int servoPin_1 = 9;
int servoPin_2 = 10;

//Create Servo Object
Servo orangeServo;
Servo wristServo;
Servo gripperServo;

void setup()
{
 //Start Serial
 Serial.begin(9600);
  
  //Attaches the Servo to our object
  orangeServo.attach(servoPin_0);
  wristServo.attach(servoPin_1);
  gripperServo.attach(servoPin_2);
  
  delay(500);
}

void loop()
{  

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

  int pos_0 = map(data_0, 0, 9, 0, 180);
  pos_0 = constrain(pos_0, 0, 180);

  //Turn the servo
  Serial.print(pos_0);
  orangeServo.write(pos_0);
  while(Serial.available()>0);
  Serial.read(); 
  
  
  while( Serial.available() == 0);
  int data_1 = Serial.read() -'0';

  int pos_1 = map(data_1, 0, 9, 0, 180);
  pos_1 = constrain(pos_1, 0, 180);

  //Turn the servo
  Serial.print(pos_1);
  wristServo.write(pos_1);
  while(Serial.available()>0);
  Serial.read(); 
  
  
  while( Serial.available() == 0);
  int data_2 = Serial.read() -'0';

  int pos_2 = map(data_2, 0, 9, 0, 180);
  pos_2 = constrain(pos_2, 0, 180);

  //Turn the servo
  Serial.print(pos_2);
  gripperServo.write(pos_2);
  while(Serial.available()>0);
  Serial.read(); 
  
  
  
}

Please bear with me i am new to arduino and xbee

while(Serial.available()>0);

I think that one was pointed out as potentially problematical. Luckily, you probably haven't got anything yet. On the other hand, the "read" is going to fail.
You've still got no way of distinguishing which value belongs to which channel, so if you miss a character, you're screwed.

Hard to wade thru all the churn, but below is some servo/pot test code for two servos and two pots that might be of interest.

//zoomkat dual pot/servo test 12-29-12

#include <Servo.h> 
Servo myservo1;
Servo myservo2;

int potpin1 = 0;  //my pot pin
int potpin2 = 1;

int newval1, oldval1;
int newval2, oldval2;

void setup() 
{
  Serial.begin(9600);  
  myservo1.attach(2);  
  myservo2.attach(3);
  Serial.println("testing dual pot servo");  
}

void loop() 
{ 
  newval1 = analogRead(potpin1);           
  newval1 = map(newval1, 0, 1023, 0, 179); 
  if (newval1 < (oldval1-2) || newval1 > (oldval1+2)){  
    myservo1.write(newval1);
    Serial.print("1- ");
    Serial.println(newval1);
    oldval1=newval1;
  }

  newval2 = analogRead(potpin2);
  newval2 = map(newval2, 0, 1023, 0, 179);
  if (newval2 < (oldval2-2) || newval2 > (oldval2+2)){  
    myservo2.write(newval2);
    Serial.print("2- ");    
    Serial.println(newval2);
    oldval2=newval2;
  }
  delay(50);
}

Okay i understand that but AWOL but then what is the way out, can you please tell me, as per my understanding if i take out
while(Serial.available()>0);

i will be able to read all the char that comes in, but in this case how can i set up the link between pot1 and servo1 and pot 2 and servo 2

zoomkat can i use the same code i have for the sender ?