Go Down

Topic: Controlling 2 servos by 2 potentiometers via xbee (Read 3009 times) previous topic - next topic

deathrow

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:

Code: [Select]


#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:

Code: [Select]


#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


PaulS

Code: [Select]
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?

deathrow

Quote

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.

Quote

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.

Quote

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

allen121

#3
Mar 07, 2013, 12:49 pm Last Edit: Mar 07, 2013, 12:55 pm by allen121 Reason: 1
hi i was going through this post and i am having the same problem, i am using a different set of codes given below

Code: [Select]
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);




Code: [Select]
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

AWOL

Code: [Select]
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.
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

PaulS

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

That's hardly surprising.

Code: [Select]
  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.

Code: [Select]
  int data =Serial.read()-'0';
On the receiver, data will be 0, 1, 2, ... , 8 or 9.

Code: [Select]
  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.

Code: [Select]
  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.

deathrow

It finally works!

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

Thanks for the help!

allen121

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


Code: [Select]
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);
 
}


Code: [Select]

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();
 
 
 
}

AWOL

#8
Mar 08, 2013, 10:54 am Last Edit: Mar 08, 2013, 10:57 am by AWOL Reason: 1
Code: [Select]
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.
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

allen121

#9
Mar 08, 2013, 12:08 pm Last Edit: Mar 08, 2013, 12:13 pm by allen121 Reason: 1
Code: [Select]
while(Serial.available()>0);
 Serial.read();


i am using this to flush out any unwanted data

i guess the above code replaces

Code: [Select]

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

Code: [Select]
while(Serial.available()>0);
 Serial.read();


so what changes should i make

thanks

AWOL

Quote
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.
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

allen121

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

Code: [Select]

Serial.flush();


i can achieve what i am looking for  ?

AWOL

#12
Mar 08, 2013, 12:18 pm Last Edit: Mar 08, 2013, 12:20 pm by AWOL Reason: 1
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.
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

PaulS

Quote
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.

allen121

#14
Mar 09, 2013, 03:44 pm Last Edit: Mar 09, 2013, 03:48 pm by allen121 Reason: 1
Quote
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.



Quote
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





Go Up