Let's Make Robots!

Code help, please

I have been trying to use Guibots xbee example of controlling 2 led's with 2 pots. I want to control a servo with a pot through xbee. using the servo.h sketch the below is what i have, but cant seem to get it to turn the servo. if i hook it up directly with no xbee involved, it works fine. so my problem is taking the example servo.h scketch and being able to break it into two sketches. send and a receive. i appreciate any help.

 looking at the below can you tell what i am doing wrong?

Here is the unaltered sketch from servo.h example. (servo library knob) this is just hooking up a servo and controlling it with a pot.

// Start example

 // Controlling a servo position using a potentiometer (variable resistor) 

// by Michal Rinott <http://people.interaction-ivrea.it/m.rinott

 

#include <Servo.h> 

 

Servo myservo;  // create servo object to control a servo 

 

int potpin = 0;  // analog pin used to connect the potentiometer

int val;    // variable to read the value from the analog pin 

 

void setup() 

  myservo.attach(9);  // attaches the servo on pin 9 to the servo object 

 

void loop() 

  val = analogRead(potpin);            // reads the value of the potentiometer (value between 0 and 1023) 

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

  myservo.write(val);                  // sets the servo position according to the scaled value 

  delay(15);                           // waits for the servo to get there 


//End Example 

 

below are the two sketch files i am trying to create for a send and receive. 

// Begin Sender

int potpin = 0;  // analog pin used to connect the potentiometer

int val;    // variable to read the value from the analog pin 

 

void setup()

{

// start serial port at 19200 bps

Serial.begin(19200);

}

 

void loop()

  val = analogRead(potpin);            // reads the value of the potentiometer (value between 0 and 1023) 

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

  delay(15);                           // waits for the servo to get there 

 

 

Serial.print(254, BYTE); //SYNC char

Serial.print(val, BYTE);

 

 

delay(150);

}

// End Sender

 

the next sketch is for the receiver.

 

// Begin RECIEVER

 

byte incomingByte, val;

 

#include <Servo.h> 

 

Servo myservo;  // create servo object to control a servo

 

void setup() {

 

// start serial port at 19200 bps

Serial.begin(19200);

Serial.println("Ready!");

 

 

myservo.attach(9);  // attaches the servo on pin 9 to the servo object 

 

}

 

void loop() {

if (Serial.available()) {   // are there any bytes available on the serial port ???

 

// assign bytes to the var ‘incomingByte’

incomingByte = Serial.read();

 

Serial.print(int(incomingByte));

 

 

 

if ((int(incomingByte) == 254)) {

val = Serial.read();

Serial.print("Sensor 1 = ");

Serial.print(int(val));

}

 

 

}

 

 myservo.write(val);                  // sets the servo position according to the scaled value 

 delay(15); 

 

}

// End Receiver 

 

 

 

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

I found this code on instructables by oomlout for the Serb robot. I am going to see if I can figure out how to take this and make two sketches. send and receive. 

/*****************************************************************

 * Arduino Controlled Servo Robot (SERB) - Wii Nunchuck Control  *

 * For more details visit: http://www.oomlout.com/serb           *

 *                                                               *  

 * Behaviour: Uses a Wii Nunchuck to control the movement of     *

 *            your SERB. Use the joystick to move the robot      *

 *            forward and backwards, left and right.             *

 *            Hold the Z button to use the acelerometers,        *

 *            tilt the nunchuck forward to go forward, backwards *

 *            to go in reverse and left and right, to go left    *

 *            and right.                                         * 

 *                                                               *

 * Wiring: --Arduino Controlled Servo Robot--                    *

 *             Right Servo Signal - pin 9                        *  

 *             Left Servo Signal - pin 10                        *

 *         --Wii Nunchuck--                                      * 

 *             + - white  - ground - negative                    *

 *             - - red    - 3.3+v  - 5 volts will work           *

 *             d - green  - data   - Analog 4                    *

 *             c - yellow - clock  - Analog 5                    *

 *                                                               *

 * License: This work is licenced under the Creative Commons     *

 *          Attribution-Share Alike 3.0 Unported License. To     *

 *          view a copy of this licence, visit                   *

 *          http://creativecommons.org/licenses/by-sa/3.0/       *

 *          or send a letter to Creative Commons, 171 Second     *

 *          Street, Suite 300, San Francisco, California 94105,  *

 *          USA.                                                 *  

 *                                                               *         

 ****************************************************************/

 

//START OF NUNCHUCK PREAMBLE -  

//For more in depth information please visit the original source 

//of this code http://www.windmeadow.com/node/42 

//----------------------------------------------------------------

#include <Wire.h>

#include <string.h>

 

#undef int

#include <stdio.h>

 

uint8_t outbuf[6]; // array to store arduino output

int cnt = 0;                    // counter used for nunchuck 

// comunication

int ledPin = 13;

 

int nunchuckValues[] = {

  0,0,0,0,0,0,0,0,0,0}; //An array to store 

                        //the nunchuck values

/*

 * The index of each value within the nunchuckValues[] array

 * ie. XSTICK value is stored at nunchuckValues[XSTICK] (0)

 */

#define XSTICK 0      //The joystick values     

#define YSTICK 1

#define XAXIS 2       //The three accelerometer values     

#define YAXIS 3        

#define ZAXIS 4 

#define ZBUTTON 5     //Front button values  (0 when pressed)  

#define CBUTTON 6  

#define XAXISDELTA 7  //Change in accelerometer data from last read;

#define YAXISDELTA 8   

#define ZAXISDELTA 9 

 

/*

 * Nunchuck G calculating Constants

 * Each accelerometer returns a value between 0 and 1024 (10 bits)

 * resting at about 512 in the middle. To make this more usable in

 * our code we can scale this value to number of Gs. This requires

 * a number of constants for details on what these constants mean

 * and how to callculate them for your nunchuck visit.

 * --  http://www.wiili.org/index.php/Motion_analysis --

 * The constants to follow are named identical to the explanation 

 * in that page. (some are unused in the code and could be deleted)

 *

 *     Zero Points

 *       <math>x_0 = (x_1 + x_2) / 2\,</math>

 *       <math>y_0 = (y_1 + y_3) / 2\,</math>

 *       <math>z_0 = (z_2 + z_3) / 2\,</math>

 *     One G points

 *       <math>x = \frac{x_{raw} - x_0}{x_3 - x_0}</math>

 *       <math>y = \frac{y_{raw} - y_0}{y_2 - y_0}</math>

 *       <math>z = \frac{z_{raw} - z_0}{z_1 - z_0}</math>

 */

#define X0 500 

#define X1 500

#define X2 500

#define X3 711

 

#define Y0 465

#define Y1 481

#define Y2 621

#define Y3 449

 

#define Z0 578

#define Z1 785

#define Z2 575

#define Z3 582

//END OF NUNCHUCK PREAMBLE

//----------------------------------------------------------------

 

//----------------------------------------------------------------

// START OF ARDUINO CONTROLLED SERVO ROBOT (SERB) PREAMBLE

#include <Servo.h>

 

#define LEFTSERVOPIN  10  //The pin the left Servo is connected to

#define RIGHTSERVOPIN  9  //The pin the right Servo is connected to

 

#define MAXSPEED 10  //due to the way continuous rotation servos 

                     //work maximum speed is reached at a much 

                     //lower value than 90 (this value will change 

                     //depending on your servos) (for Parallax servos)

                     //20 will give you full range 10 makes it very

                     //controllable but a little slow

 

Servo leftServo; 

Servo rightServo; 

 

int leftSpeed;        //sets the speed of the robot (left servos) 

                      //a percentage between -MAXSPEED and MAXSPEED

int rightSpeed;       //sets the speed of the robot (both servos) 

                      //a percentage between -MAXSPEED and MAXSPEED

int speed = 100;      //used for simple control (goForward etc.)

                      //a percentage between 0 and MAXSPEED

 

// END OF ARDUINO CONTROLLED SERVO ROBOT (SERB) PREAMBLE

//----------------------------------------------------------------

 

// THIS PROGRAMS PREAMBLE

//----------------------------------------------------------------

long lastPrint;        //a long variable to store the time the 

                       //wiimote state was last printed

#define PRINTINTERVAL 1000  //the number of milliseconds between 

                            //outputting the nunchuck state over the 

                            //usb port

#define DEADBAND 20         //A percentage away from center that is 

                            //interpretted as still being zero

                            //this accounts for joysticks or 

                            //accelerometers that aren't quite centered

// END OF THIS PROGRAMS PREAMBLE

//----------------------------------------------------------------

 

void setup(){

  beginSerial (9600);   //Starts the serial port 

  nunchuck_init ();     //send the nunchuck initilization handshake

  serbSetup();          //adds the servos and prepares all 

                        //SERB related variables

  lastPrint = millis(); //loads the current time as the last time

                        //nunchuck data was sent over the usb port

}

/*

 * The main loop 

 * Reads the nunchuck data, then if the Z Button is pressed calls a 

 * routine to move based on current accelerometer values otherwise

 * it will call a routine to use the current joystick values

 * finally if PRINTINTERVAL time has elapsed the current nunchuck

 * values are sent over the USB port.

 */

void loop(){

  readNunchuck();             //Reads the current state of the 

                              //nunchucks buttons and accelerometers

  if(!getNunValue(ZBUTTON)){  //If the Z Button is pressed

    moveWiiAcelerometer();    //moves the robot depending on the 

                              //nunchucks acceleration values 

  }

  else{                       //If the Z Button is not pressed

    moveWiiJoystick();        //moves the robot depending on the

                              //nunchucks joystick values

  }

  

  if((millis() - lastPrint) > PRINTINTERVAL){  //If a PRINTINTERVAL

                                               //milliseconds has 

                                               //passed since last 

                                               //printing nunchuck 

                                               //values print them

    printData();          //print nunchuck values

    Serial.println();     //add an enter

    lastPrint = millis(); //store current time as lastPrint

  }

}

 

/*

 * Moves the robot based on the accelerometer values. If tilted one

 * G forward the full speed forward, half a G forward then half

 * speed forward etc.

 */

void moveWiiAcelerometer(){

  moveDifferential(getYGs() * (float)100,getXGs()*(float)100); 

    //Scales the -1 to 1 G value from the accelerometers to -100 to

    //100 percent for the moveDifferential routine

    //Using the y axis for speed and x axis for direction

}

 

/*

 * Moves the robot based on the joystick values. If pushed fully forward

 * then full speed forward, half a forward then half

 * speed forward etc.

 */

void moveWiiJoystick(){

  moveDifferential(map(getNunValue(YSTICK),30,220,-100,100),map(getNunValue(XSTICK),30,220,-100,100));

    //Scales the Y axis stick from 30 to 220 to -100 to 100 for the

    //moveDifferential command 

    //Using the y axis for speed and x axis for direction

}

 

/*

 * takes in a speed value between 100 and -100 and a direction value

 * from -100 to 100.

 * example out comes. speed 100 direction 0 = full forward

 *                    speed 0 direction -100 = full speed left 

 *                    speed 0 direction 100 = full speed right

*/ 

void moveDifferential(int speed1, int direction1){

  speed1 = deadBandFilter(speed1);   //if speed is within DEADBAND percent

                                     // of zero then treat as zero

  direction1 = deadBandFilter(direction1); //if direction is within 

                                           //DEADBAND percent of

                                           //zero then treat as zero

  setSpeedLeft(speed1 + direction1);  //left speed is speed one plus

                                      //the direction value  

  setSpeedRight(speed1 - direction1); //right speed is speed minus the

                                      //direction value

}

 

/*

 * Adds a dead spot to control values. ie if a value is within DEADBAND

 * percent of zero the treat as zero, if above DEADBAND percent of zero

 * then scale the value to be between 0 and 100 when input value is 

 * DEADBAND to 100

 */

int deadBandFilter(int value){

  if(value > -DEADBAND && value < DEADBAND){ //if value is within 

    value = 0;                               //DEADBAND percent of zero

  }                                          //then make it zero

  else{

    if(value > 0){

      value = value - DEADBAND * 100 / (100-DEADBAND); //scale

    }

    else{

      value = value + DEADBAND * 100 / (100-DEADBAND); //scale

    }

  }

  return value; 

}

 

 

//START OF NUNCHUCK ROUTINES

//-------------------------------------------------------------------------------------------------------

 

/*

 * Returns the last read value for a particular input index

 * constants are at the head of this program

 * example call: getNunValue(YAXIS)

 */

int getNunValue(int valueIndex){

  return nunchuckValues[valueIndex];

}

 

/*

 * Calculates and returns the xAxis acceleration in Gs

 */

float getXGs(){

  return ((float)getNunValue(XAXIS) - X0) / (X3 - X0);

   //using math from --  http://www.wiili.org/index.php/Motion_analysis --

}

 

/*

 * Calculates and returns the yAxis acceleration in Gs

 */

float getYGs(){

  return ((float)getNunValue(YAXIS) - Y0) / (Y2 - Y0);

   //using math from --  http://www.wiili.org/index.php/Motion_analysis --

}

 

/*

 * Calculates and returns the zAxis acceleration in Gs

 */

float getZGs(){

  return ((float)getNunValue(YAXIS) - Z0) / (Z1 - Z0);  

   //using math from --  http://www.wiili.org/index.php/Motion_analysis --  

}

 

//START OF NUNCHUCK Reading CODE - For more in depth information 

//please visit the original source 

//of this code http://www.windmeadow.com/node/42 

//---------------------------------------------------------------

void readNunchuck(){

  Wire.requestFrom (0x52, 6); // request data from nunchuck

  while (Wire.available ()) {

    outbuf[cnt] = nunchuk_decode_byte (Wire.receive ()); // receive byte as an integer

    digitalWrite (ledPin, HIGH); // sets the LED on

    cnt++;

  }

  // If we recieved the 6 bytes, then go print them

  if (cnt >= 5) {

    nunchuckValues[XSTICK] = outbuf[0];

    nunchuckValues[YSTICK] = outbuf[1];

    int tempNun_xAxis = outbuf[2] * 2 * 2; 

    int tempNun_yAxis = outbuf[3] * 2 * 2;  

    int tempNun_zAxis = outbuf[4] * 2 * 2;

    nunchuckValues[ZBUTTON] = 0;

    nunchuckValues[CBUTTON] = 0;

    // byte outbuf[5] contains bits for z and c buttons

    // it also contains the least significant bits for the accelerometer data

    // so we have to check each bit of byte outbuf[5]

    if ((outbuf[5] >> 0) & 1) { 

      nunchuckValues[ZBUTTON] = 1; 

    } //checking if Z button is pressed (0=pressed 1=unpressed)

    if ((outbuf[5] >> 1) & 1) { 

      nunchuckValues[CBUTTON] = 1; 

    } //checking if C button is pressed (0=pressed 1=unpressed)

    if ((outbuf[5] >> 2) & 1) { 

      tempNun_xAxis += 2; 

    } //adding second least significant bit to x_axis

    if ((outbuf[5] >> 3) & 1) { 

      tempNun_xAxis += 1; 

    } //adding least significant bit to x_axis

    if ((outbuf[5] >> 4) & 1) { 

      tempNun_yAxis += 2; 

    } //adding second least significant bit to y_axis

    if ((outbuf[5] >> 5) & 1) { 

      tempNun_yAxis += 1; 

    } //adding least significant bit to x_axis

    if ((outbuf[5] >> 6) & 1) { 

      tempNun_zAxis += 2; 

    } //adding second least significant bit to z_axis

    if ((outbuf[5] >> 7) & 1) { 

      tempNun_zAxis += 1; 

    } ////adding least significant bit to x_axis

    nunchuckValues[XAXISDELTA] = tempNun_xAxis - nunchuckValues[XAXIS];

    nunchuckValues[XAXIS] = tempNun_xAxis;

    nunchuckValues[YAXISDELTA] = tempNun_yAxis - nunchuckValues[YAXIS];

    nunchuckValues[YAXIS] = tempNun_yAxis;

    nunchuckValues[ZAXISDELTA] = tempNun_zAxis - nunchuckValues[ZAXIS];

    nunchuckValues[ZAXIS] = tempNun_zAxis;

  }

  cnt = 0;

  send_zero (); // send the request for next bytes

}

 

void nunchuck_init (){

  Wire.begin (); // join i2c bus with address 0x52

  Wire.beginTransmission (0x52); // transmit to device 0x52

  Wire.send (0x40); // sends memory address

  Wire.send (0x00); // sends sent a zero.  

  Wire.endTransmission (); // stop transmitting

}

 

void send_zero () {

  Wire.beginTransmission (0x52); // transmit to device 0x52

  Wire.send (0x00); // sends one byte

  Wire.endTransmission (); // stop transmitting

}

 

// Encode data to format that most wiimote drivers except

// only needed if you use one of the regular wiimote drivers

char nunchuk_decode_byte (char x)  {

  x = (x ^ 0x17) + 0x17;

  return x;

}

 

//END OF NUNCHUCK CODE - For more in depth information please visit 

//the original source of this code http://www.windmeadow.com/node/42 

//---------------------------------------------------------------

 

//------------------------------------------------------------------------

//START OF ARDUINO CONTROLLED SERVO ROBOT (SERB) ROUTINES

 

/*

 * sets up your arduino to address your SERB using the included 

 * routines

 */

void serbSetup(){

  setSpeed(speed);

  pinMode(LEFTSERVOPIN, OUTPUT);     //sets the left servo signal pin 

  //to output

  pinMode(RIGHTSERVOPIN, OUTPUT);    //sets the right servo signal pin 

  //to output

  leftServo.attach(LEFTSERVOPIN);    //attaches left servo

  rightServo.attach(RIGHTSERVOPIN);  //attaches right servo

  goStop();

}

 

/*

 * sets the speed of the robot between 0-(stopped) and 100-(full speed)

 * NOTE: speed will not change the current speed you must change speed 

 * then call one of the go methods before changes occur.

 */

void setSpeed(int newSpeed){

  if(newSpeed >= 100) {

    newSpeed = 100;

  }     //if speed is greater than 100 

        //make it 100

  if(newSpeed <= 0) {

    newSpeed = 0;

  }         //if speed is less than 0 make 

            //it 0 

  speed = newSpeed * MAXSPEED / 100;        //scales the speed to be 

                                            //between 0 and MAXSPEED

}

 

/*

 * sets the speed of the robots rightServo between -100-(reversed) and 100-(forward)

 * NOTE: calls to this routine will take effect imediatly

 */

void setSpeedRight(int newSpeed){

  if(newSpeed >= 100) {

    newSpeed = 100;

  }     //if speed is greater than 100 

        //make it 100

  if(newSpeed <= -100) {

    newSpeed = -100;

  }   //if speed is less than -100 make 

      //it -100 

  rightSpeed = newSpeed * MAXSPEED / 100;   //scales the speed to be 

                                            //between -MAXSPEED and MAXSPEED

  rightServo.write(90 - rightSpeed);        //sends the new value to the servo

}

 

/*

 * sets the speed of the robots leftServo between -100-(reversed) and 100-(forward)

 * NOTE: calls to this routine will take effect immediatly

 */

void setSpeedLeft(int newSpeed){

  if(newSpeed >= 100) {newSpeed = 100;} //if speed is greater than 100 

                                        //make it 100

  if(newSpeed <= -100){newSpeed = -100;}//if speed is less than -100 

                                        //make it -100 

  leftSpeed = newSpeed * MAXSPEED / 100;//scales the speed to be 

                                        //between -MAXSPEED and MAXSPEED

  leftServo.write(90 + leftSpeed);      //sends the new value to the servo

}

 

/*

 * sends the robot forwards

 */

void goForward(){

  leftServo.write(90 + speed);

  rightServo.write(90 - speed);

}

 

/*

 * sends the robot backwards

 */

void goBackward(){

  leftServo.write(90 - speed);

  rightServo.write(90 + speed);

}

 

/*

 * sends the robot right

 */

void goRight(){

  leftServo.write(90 + speed);

  rightServo.write(90 + speed);

}

 

/*

 * sends the robot left

 */

void goLeft(){

  leftServo.write(90 - speed);

  rightServo.write(90 - speed);

}

 

/*

 * stops the robot

 */

void goStop(){

  leftServo.write(90);

  rightServo.write(90);

//END OF ARDUINO CONTROLLED SERVO ROBOT (SERB) ROUTINES

//---------------------------------------------------------------------------

 

//START  OF PRINT ROUTINES (can delete if not using)

//---------------------------------------------------------------

 

//Prints the Nunchucks last read data (must call NUN_readNunchuck();

//before calling

void printData(){

  Serial.print("XJoy= ");  Serial.print (getNunValue(XSTICK), DEC); Serial.print ("\t");

  Serial.print("YJoy= ");  Serial.print (getNunValue(YSTICK), DEC); Serial.print ("\t");

  Serial.print("XGs= ");   Serial.print (getXGs() * 1000, DEC);     Serial.print ("\t");

  Serial.print("YGs= ");   Serial.print (getYGs() * 1000, DEC);     Serial.print ("\t");

  Serial.print("ZGs= ");   Serial.print (getZGs() * 1000, DEC);     Serial.print ("\t");

  Serial.print("ZBut= ");  Serial.print (getNunValue(ZBUTTON), DEC);Serial.print ("\t");

  Serial.print("YBut= ");  Serial.print (getNunValue(CBUTTON), DEC);Serial.print ("\t");

}

//END OF PRINT ROUTINES

//-------------------------------------------------------------------- 

i am in class right now. when i get back later today i will take a screen shot.

dont know mate :(

 

Have you got a screenshot of it?

Im trying to help but i fear im hindering you by stabbing nto the dark.  

changed it to Value: and it shows up as Value: = 254, etc.

the sender monitor is showing garbled text though. 

Try: 

 Serial.print("Value:");

Serial.print(int(val)); 

 myservo.write(val);                  // sets the servo position according to the scaled value  

 

where the myservo line is to make sure that its getting that far and that the val isnt being lost in the loop somehow, at least then you will know its sending it to the servo in the right way.  

Yeah it prints out Sensor 1 = and shows the numbers. I have both arduinos plugged in to PC's.

  I am going to check out the principallabs.com website

for the reciever does it print out "Sensor 1 = " ?

to figure out serial comms wih arduino atm also but im not having any luck either. I believe in trying to achive the same, controling two servos over seriel comms. 

 

THis is using python to send the signals but he explains the part we need in his arduino code:

http://principialabs.com/arduino-python-4-axis-servo-control/ 

Yeah I can make the Xbees work. I followed Gui's tutorial for controlling two LEDS with Two Pots. Works wonderful.

http://arduinofun.com/blog/2009/03/21/arduino-wireless-xbee-test/ 

But I need to figure out how to control a servo. He uses DC servos, so his code I didn't understand and I am trying to see if i can edit something to work with the servos I use (with 3 wires). 

Have you tried plugging the receiver into the PC? Does it get as far as the Serial.print("Sensor 1 = "); ?