Control Multiple Servos with Arduino Via Xbee

Hello, Im trying to write some code to control multiple servos (6) using 2 arduinos communicating via 2 Xbees.

I have started by trying to code for a single servo but I'm getting limited movement. The servo only moves from 0-126 deg. I have based my code off the Xbee LED control code on page 202 of the "Making things talk" book.

I would like help determining why the servo is not moving to the full 180deg.

As far as I can tell, the values of 126-180 do not get passed along correctly after the "return message;" command at the bottom of the code.

When I print the "sensorReading" value it goes all the way to 180 but not the "sensorvalue" values.

sorry for the messy coding.

I have the code the same for the send and receive with the exception of changing the xbee addressing.

//======================================
#include <Servo.h> 
 
Servo myservo;  // create servo object to control a servo 

//=====================================

#define sensorPin 0 // input sensor // analog pin used
#define txLed 2 // LED to indicate outgoing data
#define rxLed 3 // LED to indicate incoming data


#define analogLed 9 // LED that changes brightness with
                   // incoming value
#define threshold 2 // how much change you need to see on
                    // the sensor before sending
int lastSensorReading = 0; // previous state of the switch
int inByte= -1; // incoming byte from serial RX

char inString[6]; // string for incoming serial data
//char inString[100]; // string for incoming serial data

int stringPos = 0; // string index counter



void setup() {
// configure serial communications:
Serial.begin(9600);
// configure output pins:
pinMode(txLed, OUTPUT);
pinMode(rxLed, OUTPUT);
pinMode (analogLed, OUTPUT);


// set XBee's destination address:
setDestination();
// blink the TX LED to indicate the main program's about to start:
blink(3);
//==========================================
myservo.attach(8);  // attaches the servo on pin 9 to the servo object 
//==========================================


}



void setDestination() {
// put the radio in command mode:
Serial.print("+++");
// wait for the radio to respond with "OK\r"
char thisByte = 0;
while (thisByte != '\r') {
if (Serial.available() > 0) {
thisByte = Serial.read();
}
}


//1000 reciver
//1001 sender 

// set the destination address, using 16-bit addressing.
// if you're using two radios, one radio's destination
// should be the other radio's MY address, and vice versa:
Serial.print("ATDH0, DL1000\r");
// set my address using 16-bit addressing:
Serial.print("ATMY1001\r");
// set the PAN ID. If you're working in a place where many people
// are using XBees, you should set your own PAN ID distinct
// from other projects.
Serial.print("ATID1111\r");
// put the radio in data mode:
Serial.print("ATCN\r");
}



// Blink the tx LED:
void blink(int howManyTimes) {
for (int i=0; i< howManyTimes; i++) {
digitalWrite(txLed, HIGH);
delay(200);
digitalWrite(txLed, LOW);
delay(200);
}
}



void loop() {
// listen for incoming serial data:
if (Serial.available() > 0) {
// turn on the RX LED whenever you're reading data:
digitalWrite(rxLed, HIGH);
handleSerial();
}
else {
// turn off the receive LED when there's no incoming data:
digitalWrite(rxLed, LOW);
}
// listen to the potentiometer:
char sensorValue = readSensor();
// if there's something to send, send it:
if (sensorValue > 0) {
//light the tx LED to say you're sending:
digitalWrite(txLed, HIGH);
Serial.print(sensorValue, DEC );

//===================================================================
//Serial.print("sensorValue =");
//Serial.print(sensorValue, DEC );
//Serial.println();
//====================================================================
Serial.print("\r");
// turn off the tx LED:
digitalWrite(txLed, LOW);
}
}




void handleSerial() {
inByte = Serial.read();
// save only ASCII numeric characters (ASCII 0 - 9):
if ((inByte >= '0') && (inByte <= '9')){
inString[stringPos] = inByte;
stringPos++;
}

// if you get an ASCII carriage return:
if (inByte == '\r') {
// convert the string to a number:
int brightness = atoi(inString);

// set the analog output LED:
//analogWrite(analogLed, brightness);

//=============================
 myservo.write(brightness); 
 //Serial.print("brightness ="); 
 //Serial.print(brightness);
 //Serial.println();
//==============================
// put zeroes in the array
for (int c = 0; c < stringPos; c++) {
inString[c] = 0;
}
// reset the string pointer:
stringPos = 0;
}
}


char readSensor() {
char message = 0;
// read the sensor:
int sensorReading = analogRead(sensorPin);
// look for a change from the last reading

//==================================

// scale it to use it with the servo (value between 0 and 180)
sensorReading = map(sensorReading, 0, 1023, 0, 179); 

//=================================

// that's greater than the threshold:
if (abs(sensorReading - lastSensorReading) > threshold) {
  
//message = sensorReading/4;

//=================================
message = sensorReading;
//Serial.print("sensorReading =");
//Serial.print(sensorReading);
//Serial.println();
//=================================

lastSensorReading = sensorReading;

}
return message;
}

The message variable, being of char datatype, can only hold values between -128 and 127.

well shoot... :frowning:
Thank you for catching that Jack.

hmmm should I divide the value by 2 transmit it then multiply it by 2?

or is there a simpler way of doing it?
I have seen people use the EasyTransfer Library, but I couldn't get their example codes to work.

Any suggestions?

Lucky catch. Would it be as simple as using an int instead?

I looked through some more posts and found some useful code from "deathrow"

deathrow:
It finally works!

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

Thanks for the help!

I have been following this post and I used deathrow's posted code and made the modifications needed. I get 2 servos working off 2 pots.
Im using 2 Arduino Megas, 2 Xbee S1, 2 pots and 2 servos.

here is the code.

Sending code

#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);
  Serial.begin(9600);
  
  ET.begin(details(txdata), &Serial);
  //pinMode(potpin1, INPUT);
  //pinMode(potpin2, INPUT);
 
}

void loop(){
  
  /*
  txdata.servo1val = analogRead(potpin1);
  txdata.servo2val = analogRead(potpin2);
 */
 
  txdata.servo1val = analogRead(potpin1);
  txdata.servo2val = analogRead(potpin2);
  
  txdata.servo1val = map(txdata.servo1val, 0, 1023, 0, 179);
  txdata.servo2val = map(txdata.servo2val, 0, 1023, 0, 179);
  
 //========================================
 /*
  Serial.print("txdata.servo1val =");
  Serial.print(txdata.servo1val);
  Serial.print("     ");
  Serial.print("txdata.servo2val =");
  Serial.print(txdata.servo2val);
  
  Serial.println();
  */
  //======================================
 
 
  ET.sendData();
  

}

Receive code

#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);
  Serial.begin(9600);
 
  ET.begin(details(txdata), &Serial);
  myservo1.attach(9);
  myservo2.attach(10);
}

void loop(){
  if(ET.receiveData()){
   
    myservo1.write(txdata.servo1val);
    myservo2.write(txdata.servo2val);
    
  }
}

I like a lot of the features the original code posted that programmed the xbee and added status TX and FX LEDs. I like having LEDs or serial.prints to show me what is going on. I will be adding those features to this code later on.

Thank you all on this forum for all this help.