Problems controlling 2 servos wirelessly

Hi guys! I'm trying to build a remote control using xbee serie 1 and an arduino nano. Also, 2 joysticks are connected to the arduino nano. The arduino nano read the analog value of the 2 joysticks (just the X axe) and send the data through the Xbee. On the other side, an arduino uno receive the values and move the servos. The problem is that just one servo is moving. I'm receiving all the values because I can read them through the serial monitor, but just one servo is responding (the one named as "myservo1"). Xbee are working perfectly. Any suggestion is welcome.

-----------------Sender--------------------------
int Axe_X1 = A1;
int Axe_Y1 = A2;
int Axe_X2 = A3;

void setup()
{
Serial.begin(19200);

}

void loop()
{
int angle1 = map(analogRead(A1), 0, 1023, 0, 180);
int angle2 = map(analogRead(A3), 0, 1023, 0, 180);

Serial.write(',');
Serial.write(angle1);
Serial.write(angle2);

delay(25);
}

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

int Rarray[2];
int angle1;
int angle2;

int Val1;
int Val2;

int i;

int servoPin1 = 6;
int servoPin2 = 8;

void setup() {
Serial.begin(19200);
myservo1.attach(servoPin1) ;
myservo2.attach(servoPin2);

}

void loop() {

if(Serial.read() == ',')
{
while(Serial.available()>= 2){

for(i = 0; i < 3; i++)
{
Rarray = Serial.read();

  • }*

  • }*
    }

  • Val1 = map(Rarray[0], 0, 180, 0, 180);*

  • Val2 = map(Rarray[1], 0, 180, 0, 180);*

  • angle1 = constrain(Val1, 0, 180);*

  • angle2 = constrain(Val2, 0, 180);*

  • //Serial.println(angle2);*

  • myservo1.write(angle1);*

  • myservo2.write(angle2);*

  • delay(10);*

}

Your arrangement for reading the serial data is not robust.

Have a look at the examples in Serial Input Basics - simple reliable ways to receive data.

If you have control of the sending program use the technique in example 3 for greatest reliability.

...R

You send the data super fast so on the receiver side you receive the coma, then as long as there are more than 2 chars in the incoming buffer you read them into your array. You don't control timing on the serial so imagine this is what happens

,



10
20
,
20




30



,

Where empty lines mark nothing avail in the buffer as seen from the receiver

So you see the first comma, enter your while loop, there is nothing to read for a while and suddenly there are 4 data. Your loop loops twice and you exit the while with ',' in the first angle and 20 in the second.

See how this can be a pb?

After the comma you need to read exactly 2 values when they arrive and then take action and go back waiting for a comma. There is no need to send orders to the servos if you have not received anything or if they are the same as last time.

You could update the sender to only send the pair of values when the data has been changed there but I would not do that, as constantly receiving info from the sender can serve as a heartbeat that the communication is still good. If you ont receive the heartbeat for more than x milliseconds for example then you could decide to take a special action to protect the device with the motors (eg if this is a car or plane and you use the servos to steer, may be you want to car to stop moving or the plane to perform some kind of automated self protection actions, turn back and fly towards launch point if you have a GPS, or turn motor off and eject a parachute and run a warning sounds and light to not harm anyone,...)

As Robin2 points out, there are serious problems with sending binary data. Serial data is NOT guaranteed to be delivered, so you MUST deal with lost serial data. If you send, and insist on receiving, three bytes per packet, you are going to be hosed as soon as a byte gets corrupted.

The Serial.write() method is overloaded. You really need to pay attention to what the overloads are. Passing an int to a function that expects a byte can result in data loss. Which of the two bytes gets tossed, when you pass an int to a function that expects a byte? If you don't KNOW, don't pass an int to a function that expects a byte.

Thanks for the fast response. Can one of you guys write a piece of code of what I should do? Just a example. I know that in one of the reply one of you sent me a example but I'm working with simple numbers. Has to be something easier. Thanks.

Can one of you guys read a piece of code of what I should do?

Sure thing. You write it; we'll read it.

cf post #1
Have a look at the examples in Serial Input Basics - simple reliable ways to receive data.
You have code there