Xbee analog sending code

Hey i just want to make sure this is right and will work for the sending and receiving for xbees.

Here is the sending im pretty confident that this will work right:

int Finger1 = 1;
int Finger2 = 2;
int Finger3 = 3;
int Finger4 = 4;
int Finger5 = 5;

void setup()
{
   Serial.begin(9600);
}

void loop()
{
   byte servoValue1;
   byte servoValue2;
   byte servoValue3;
   byte servoValue4;
   byte servoValue5;
   
   int FingerV1 = analogRead(Finger1);
   int FingerV2 = analogRead(Finger2);
   int FingerV3 = analogRead(Finger3);
   int FingerV4 = analogRead(Finger4);
   int FingerV5 = analogRead(Finger5);
  
   byte servoVal1 = map(FingerV1, 0,1023,0,180);
   byte servoVal2 = map(FingerV2, 0,1023,0,180);
   byte servoVal3 = map(FingerV3, 0,1023,0,180);
   byte servoVal4 = map(FingerV4, 0,1023,0,180);
   byte servoVal5 = map(FingerV5, 0,1023,0,180);

   Serial.print(servoVal1);
   Serial.print(servoVal2);
   Serial.print(servoVal3);
   Serial.print(servoVal4);
   Serial.print(servoVal5);
   
   delay(100);
}

Now here is what i have so far for the receiving im just a little confused at the bottom (highlighted part):

#include <Servo.h>

Servo myservo1;  // create servo object to control a servo
Servo myservo2;
Servo myservo3;
Servo myservo4;
Servo myservo5;

void setup()
{
   Serial.begin(9600);
   myservo1.attach(2);  // attaches the servo on pin 9 to the servo object
   myservo2.attach(3);
   myservo3.attach(4);
   myservo4.attach(5);
   myservo5.attach(6);
}

[glow]void loop()
{
   if(Serial.available() > 0)
   {
    byte servoAng = Serial.read();

    // Send the servo to the position read... <-- you get to make this happen
    myservo.write(servoAng);
   }
} [/glow]

Right now, you are sending 5 bytes every time loop is called.

You need to make sure that the receiver waits for 5 bytes, and read all 5 of them. You also need to hope that none ever gets lost.

On the receiver, you don't have an object named myservo.

Other than that, the structure is right.

So would this be correct for receiving 5 bytes?

#include <Servo.h>

Servo myservo1;  // create servo object to control a servo
Servo myservo2;
Servo myservo3;
Servo myservo4;
Servo myservo5;

void setup()
{
   Serial.begin(9600);
   myservo1.attach(2);  // attaches the servo on pin 9 to the servo object
   myservo2.attach(3);
   myservo3.attach(4);
   myservo4.attach(5);
   myservo5.attach(6);
}

void loop()
{
   if(Serial.available() > 0)
   {
    byte servoAng1 = Serial.read();
    byte servoAng2 = Serial.read();
    byte servoAng3 = Serial.read();
    byte servoAng4 = Serial.read();
    byte servoAng5 = Serial.read();


    // Send the servo to the position read... <-- you get to make this happen
    myservo1.write(servoAng1);
    myservo2.write(servoAng2);
    myservo3.write(servoAng3);
    myservo4.write(servoAng4);
    myservo5.write(servoAng5);
   }
}
if(Serial.available() > [glow]0[/glow])
   {
    byte servoAng1 = Serial.read();
    byte servoAng2 = Serial.read();
    byte servoAng3 = Serial.read();
    byte servoAng4 = Serial.read();
    byte servoAng5 = Serial.read();

Close, but still no cigar. Now you are checking for 1 or more bytes to be read, and then reading all 5 of them. What will happen if only 2 bytes have arrived so far?

if(Serial.available() > 0)

{
   byte servoAng1 = Serial.read();
   byte servoAng2 = Serial.read();
   byte servoAng3 = Serial.read();
   byte servoAng4 = Serial.read();
   byte servoAng5 = Serial.read();







Close, but still no cigar. Now you are checking for 1 or more bytes to be read, and then reading all 5 of them. What will happen if only 2 bytes have arrived so far?

hmmm alright well would you go like this:

if(Serial.available() < 5)

hmmm alright well would you go like this:

if(Serial.available() < 5)

I wouldn’t. I’d use:

if(Serial.available() [glow]>=[/glow] 5)

Alright so that should do it? It should receive and controll the servos properly?

Alright so that should do it? It should receive and controll the servos properly?

Just try it!

I am using xBees and one of the things I am doing is remote control. I would suggest you wrap your message with some sort of prefix and termination sequence and in your main loop, check for characters available and buffer them until you have a packet then decode the packet. xBees are great, but they aren’t perfect. You need to account for the possibility of a lost byte here or there and not get out of sync. I toss packets that don’t make sense. I see a few of those as I have 5 active xBees in a “party line” configuration (with infrequent transmissions and a reasonable retry strategy, this works fairly well). Also, every time I set a servo value, I get the current millis() so that in the main loop I can check to see if it has been a long time since I got the last command. If these servos are motors that are moving a robot, you don’t want to disappear into the sunset if the transmitter crashes, lose power, goes out of range or whatever.

Hmmm well do you revenge doing that? And could you maby direct me in a way to do that

I don’t have code in front of me now; I will try to post some snippets later.

What I do is actually use text strings so that I can use a terminal interface on the PC to look at xBee traffic going back and forth to help me debug. So I actually use Serial.println to send my commands. I start with a chosen letter and then 4 numbers (2 are the “to” address and 2 are the “from”; I assign the addresses) and follow it with a sort command and parameter it might need like:
P0102JOY:180
to indicate that the joy stick is at 180 degrees on unit 1 and it wants unit 2 to react to it. The chosen letter is arbitrary, but I make sure there is the chosen letter followed by 4 numbers before I bother trying to sort out a packet.

This is from memory and may not be exactly right, but something like this for buffering in the loop:

int idx = 0;
char sBuf[256];

while( Serial.available() > 0)
{
byte inByte = Serial.read()
if (idx < 256)
sBuf[idx++] = inByte;
if( inByte == 13)
{
ExecCmd( sBuf); // you have to write this - it is the function to parse and execute commands
idx = 0;
}
}

As far as making sure motors don’t run indefinitely:

unsigned long lLastMotorCmd = 0;

void MotorWatchdog()
{
if( (millis() - lLastMotorCmd) > 500)
myservo.write(0);
}

void SetMotor( in iVal)
{
myservo.write( iVal);
lLastMotorCmd = millis();
}

Consider that as psuedo-code; I just wrote it in the browser.

But hopefully you get the idea. Buffer your input and the decode meaningful packets. Make a note of the time you turn a motor on and check to make sure it gets turned off if you don’t have another command to set the level again. There is an argument to be made that it is better practice to track whether or not the motor is currently on and at what level and not repeatedly turn it off or on to the same level. But it really buys you nothing and if there is a bug you better be faster than your robot…