DFRobotShop Rover W/Xbee and Joystick
by Grissini in Circuits > Arduino
27258 Views, 62 Favorites, 0 Comments
DFRobotShop Rover W/Xbee and Joystick
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)
Wiring
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.
The Code for Arduino Uno(Joystick)
//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");
}
}}
Code for the Rover
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);
}
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.