Introduction: DFRobotShop Rover W/Xbee and Joystick

About: I make projects, they have names. Some are obscure and some straightforward. Form or Function; I go either way. Battery powered or edible, I love making things.

Rover Obstacle Course from Aleksei Sebastiani on Vimeo.  Thanks to Red Vines and Phillip K Dick.


Goal: To get my DFRobotShop Rover to talk over xbee and be controlled via an Analog Joystick.

Parts:

The Rover  from DFRobotShop $90 (My prize from this Instructable!)
Joystick Shield from Sparkfun $13
ProtoShield from AdaFruit $13
Xbee and Adapter MakerShed $35 (you'll need 2 of these)
Halfsize Breadboard Adafruit $5
Arduino Uno from Adafruit $30
FTDI interface  IteadStudio $9 (FTDI cable, or de-chipped arduino also work)

Tools:

Solder iron
Jumper wires
USB cables of all sorts
Aleve, Lots of Aleve

Links:

http://www.ladyada.net/make/xbee/index.html (AdaFruit Tutorial)
http://www.digi.com/support/kbase/kbaseresultdetl.jsp?kb=125 (XTCU Software)
http://www.sparkfun.com/tutorials/171#setup (Joystick Turorial)
http://www.robotshop.com/content/PDF/dfrobotshop-rover-user-guide.pdf (Rover Manual)




Step 1: Wiring

The Rover:

Assemble Rover as per Robotshop instructions. Same with the Joystick and Xbee shields. Place protoshield on the rover and Xbee adapter on top. Start connecting wires.
Xbee RX⇒TX on the Rover
Xbee TX⇒RX on the Rover
5volts to 5Volts and Gnd to Gnd

Joystick Shield:

Arduino TX⇒RX Xbee
Arduino RX⇒TX Xbee
5volt to 5volt and Ground to Ground

And that's it.

Step 2: The Code for Arduino Uno(Joystick)

//Code from Sparkfun with a few tweeks to get it working with Rover.  Rather than serial printing 
//words, I switched it to print the letters that the rover sketch understands. 


const byte PIN_ANALOG_X = 0;
const byte PIN_ANALOG_Y = 1;

const int X_THRESHOLD_LOW = 450;   //I have the contrains real big so there's less chance for 
const int X_THRESHOLD_HIGH = 550;  //analog misinterpretation. 

const int Y_THRESHOLD_LOW = 450;
const int Y_THRESHOLD_HIGH = 550;

int x_position;
int y_position;

int x_direction;
int y_direction;

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

void loop () {
x_direction = 0;
y_direction = 0;

x_position = analogRead(PIN_ANALOG_X);
y_position = analogRead(PIN_ANALOG_Y);


if (x_position > X_THRESHOLD_HIGH) {
x_direction = 1;
} else if (x_position < X_THRESHOLD_LOW) {
x_direction = -1;
}

if (y_position > Y_THRESHOLD_HIGH) {
y_direction = 1;
} else if (y_position < Y_THRESHOLD_LOW) {
y_direction = -1;
}


if (x_direction == -1) {
if (y_direction == -1) {
Serial.println("left-down");
} else if (y_direction == 0) {
Serial.println("a");                               //the A is whats making it go left
} else {
// y_direction == 1
Serial.println("left-up");
}
} else if (x_direction == 0) {
if (y_direction == -1) {
Serial.println("s");                          // S is for reverse
} else if (y_direction == 0) {
Serial.println("f");                          // F is for Stop--it sends this until something else is sent
} else {
// y_direction == 1
Serial.println("w");                       // W is forward
}
} else {
// x_direction == 1
if (y_direction == -1) {
Serial.println("right-down");
} else if (y_direction == 0) {
Serial.println("d");                         // D is right
} else {
// y_direction == 1
Serial.println("right-up");
}
}}

Step 3: Code for the Rover

//Code courtesy DFRobotShop  Rover_Serial 

int E1 = 6; //M1 Speed Control
int E2 = 5; //M2 Speed Control
int M1 = 8; //M1 Direction Control
int M2 = 7; //M2 Direction Control

int LED = 13;

void setup(void)
{
 int i;
 for(i=5;i<=8;i++)
 pinMode(i, OUTPUT);
 pinMode(13, OUTPUT);
 Serial.begin(9600);
}
void loop(void)
{
 while (Serial.available() < 0) {} // Wait until a character is received
 char val = Serial.read();
 int leftspeed = 255; //255 is maximum speed
 int rightspeed = 255;
 switch(val) // Perform an action depending on the command
 {
  case 'w'://Move Forward
  forward (leftspeed,rightspeed);
  break;
  case 's'://Move Backwards
  reverse (leftspeed,rightspeed);
  break;
  case 'a'://Turn Left
  left (leftspeed,rightspeed);
  break;
  case 'd'://Turn Right
  right (leftspeed,rightspeed);
  break;

  case 'l'://LED
  blink_LED();
  break;

  case 'f'://Stop
  stop();
  break;

  default:
  break;
 }
}

void stop (void) //Stop
{
 digitalWrite(E1,LOW);
 digitalWrite(E2,LOW);
}
void forward (char a,char b)
{
 analogWrite (E1,a);
 digitalWrite(M1,LOW);
 analogWrite (E2,b);
 digitalWrite(M2,LOW);
}
void reverse (char a,char b)
{
 analogWrite (E1,a);
 digitalWrite(M1,HIGH);
 analogWrite (E2,b);
 digitalWrite(M2,HIGH);
}
void left (char a,char b)
{
 analogWrite (E1,a);
 digitalWrite(M1,HIGH);
 analogWrite (E2,b);
 digitalWrite(M2,LOW);
}
void right (char a,char b)
{
 analogWrite (E1,a);
 digitalWrite(M1,LOW);
 analogWrite (E2,b);
 digitalWrite(M2,HIGH);
}

void blink_LED ()
{
 digitalWrite(LED, HIGH);
 delay(200);
 digitalWrite(LED, LOW);
 delay(100);
 digitalWrite(LED, HIGH);
 delay(200);
 digitalWrite(LED, LOW);
}

Step 4: Review, Failings & Fun

              Firstly, I like to thank the Instructables community and DFRobotShop for providing the rover.   It's a nice platform that I look forward to doing much more with.   I feel like this has gotten me past my noob level and onto a novice grade.  For a while I uploaded and tried all sorts of different codes, AFSoftSerial library, a dozen other things.  The rover wasn't working as I thought it should.  It was behaving as if it wasn't getting nearly enough power to drive the motors.  I tried adding more power.  With batteries in it, I plugged it into a wallwart.  After about 20 minutes of crazy behavior the batteries began to POP, all 4 exploded inside the rover.  Not good.   The next day I was sure everything was setup properly but still no movement, or the rover would move an inch and quit.   After wiring up a separate 5volt supply I realized the built-in LED's were pulling enough power to keep the motors from running at full force.  I pulled out the jumpers and everything works ok now.  Even with the best batteries I could find, it still drains enough power that after about 2 minutes of use, it needs to be cycled Off and On. I don't know why this is or how to combat it(Any Suggestions?).   The Xbee intergration was really the easiest part of this whole project.  A few wires and using XCTU made it very smooth.  In the end, it paid to stick with it and not be deterred by exploding batteries, losing trax of the wheels and tons of shoddy code uploads.    Now some Failure & Fun video.







4th Epilog Challenge

Participated in the
4th Epilog Challenge