Introduction: Dagu Rover 5 - Arduino Mega 2560 - Xbee
Hi. This is my 1st robot platform and 1st Instructable post. I am a big believer of the sharing of knowledge and have learned a lot for the internet, so here is me adding to the collective knowledge. Sorry for the lack of early photos
Items needed for project
dagu rover 5 - I have the 4 motors/ 4 encoder model
rover 5 motor driver Board
arduino mega 2560
Xbees - I use XBee Series 1
XBee Explorer Dongle v2
XBee Explorer Regulated - plus pins and soldering stuff
Batteries - 6AA and 5v usb bank.
male to female jumper wires
Pololu RP5/Rover 5 Expansion Plate RRC07B (Wide) Transparent Clear
Step 1: Cut a Hole for the Motor Wire to Come Through
To attach the Pololu RP5/Rover 5 Expansion Plate to rover you have to cut out a hole in the middle for the wires from the motors and encoders to come through. I cut some to plastic bit with a sharp knife. then pull the wires through, this will allow for the plate to be mounted flat
Step 2: Wiring Part A
First attach the motor and encoder wires to the rover 5 motor driver Board. I have included a image of how i wired it but it doesn't show how I attach the motor and encoder wires. To wire these trace them back to the motor and then plug them into the right port. For the encoder wires i have plug them into bottom row of the pins label "INT ENC1 ENC2" . From left to right it is Red - Yellow - White - Black.
Step 3: Wiring Part B
Wire the rover 5 motor driver Board to the arduino mega 2560 should be easier if a little messy. The image I have included shows how I did it. Here is some arduino code of where to wires go.
#define encoderA 2 #define encoderB 3 // Only use one interrupt in this example #define encoderC 19 #define encoderD 18 // Only use one interrupt in this example volatile int Lcount; volatile int Rcount; int Lcountsaved; int Rcountsaved;
int speedch1 = 9; // left front int speedch2 = 10; // left back int speedch3 = 11; // right front int speedch4 = 12; // right back // direction pins int dirch1 = 44; // left front int dirch2 = 45; // left back int dirch3 = 42; // right front int dirch4 = 43; // right back
int curch1 = A1; // left front int curch2 = A2; // left back int curch3 = A3; // right front int curch4 = A4; // right back
I have include the cur (current) pins but i never got them to work. I have use a breadboard for a common ground, this is probably wrong but it works. I will discuss Xbee in a separate step
Step 4: Platform to Hold Batteries
After wiring the lower platform, there is no room for batteries. So i created one for mine out of paper mache and wire. it is not very good, possible alternatives 3d print or shop bought box that fits. I attached the batteries via velcro.
Step 5: Coding Basic
This has been my first project so the code is rough. Here is a basic code for all four motor to spin for 5 seconds, there are no encoder or xbee in this code.
//ROBOT CAR CODE 001
int speedch1 = 9; int speedch2 = 10; int speedch3 = 11; int speedch4 = 12;
int dirch1 = 44; int dirch2 = 45; int dirch3 = 42; int dirch4 = 43;
int curch1 = A1; int curch2 = A2; int curch3 = A3; int curch4 = A4;
void setup() { // initialize the digital pin as an output. pinMode(dirch1,OUTPUT); pinMode(dirch2,OUTPUT); pinMode(dirch3,OUTPUT); pinMode(dirch4,OUTPUT);
pinMode(speedch1,OUTPUT); pinMode(speedch2,OUTPUT); pinMode(speedch3,OUTPUT); pinMode(speedch4,OUTPUT);
}
// the loop routine runs over and over again forever: void loop() { delay(2000); digitalWrite(dirch1,LOW); // direction motor spins digitalWrite(dirch2,HIGH); // 1 and 2 are on the same side but fight against each other. digitalWrite(dirch3,LOW); digitalWrite(dirch4,HIGH); analogWrite(speedch1,200); // speed PWM 0 - 255 analogWrite(speedch2,200); analogWrite(speedch3,200); analogWrite(speedch4,200); delay(5000);//how long the motors run analogWrite(speedch1,0); // stop analogWrite(speedch2,0); analogWrite(speedch3,0); analogWrite(speedch4,0); }
Step 6: Encoders Code
Here is a simple code for the left encoder. I spend many hours confused over this. but found a linear encoder code that works. The code spins the left motors until the encoder (count) reaches 500. it also print it to the serial monitor. It the same for the other side just have to change the pins and names, but i will include a final code with everything at the end.
// Interrupt information // pins may be different on uno<br>// 0 on pin 2 // 1 on pin 3
#define encoderA 2 #define encoderB 3 // Only use one interrupt in this example volatile int count;
int speedch1 = 9; // left front int speedch2 = 10; // left back int speedch3 = 11; // right front int speedch4 = 12; // right back // direction pins int dirch1 = 44; // left front int dirch2 = 45; // left back int dirch3 = 42; // right front int dirch4 = 43; // right back
int curch1 = A1; // left front int curch2 = A2; // left back int curch3 = A3; // right front int curch4 = A4; // right back int TIME; //time the command is for int SPEED;// 0 - 255 motor speed
void setup() { Serial.begin(9600); count=0; pinMode(dirch1,OUTPUT); pinMode(dirch2,OUTPUT); pinMode(dirch3,OUTPUT); pinMode(dirch4,OUTPUT);
pinMode(speedch1,OUTPUT); pinMode(speedch2,OUTPUT); pinMode(speedch3,OUTPUT); pinMode(speedch4,OUTPUT); pinMode(encoderA, INPUT); pinMode(encoderB, INPUT); attachInterrupt(0, handleEncoder, CHANGE);
}
void loop() { delay(1000); (SPEED = 200); forward(); if (count > 10) Serial.println(count); }
void handleEncoder() { if(digitalRead(encoderA) == digitalRead(encoderB)) { count++; } else { count--; }
} void forward() { digitalWrite(dirch1,LOW); digitalWrite(dirch2,HIGH); analogWrite(speedch1,SPEED); analogWrite(speedch2,SPEED); if (count > 500){ analogWrite(speedch1,0); analogWrite(speedch2,0); } }
Step 7: Xbee
The Xbees are the only place you will need to solder some pins. First get your xbees of choice and program them to take to each other on the same channel using XBee Explorer Dongle v2 and XCTU. unfortunately I managed to do this by what seems like blind luck. So i don't how much help I will be there. Here is what I know about the coding for sending for Processing to Xbee to Arduino mega 2560. choose the serial port for the xbee on the Arduino 2 or 3 and run this simple receiving code. The code turns led 13 on the board on when it receives (49) processing in next step.
int incomingByte = 0; // for incoming serial data< int led = 13;
void setup() { Serial2.begin(9600); // change to the serial port /2/3 pinMode(led, OUTPUT); }
void loop() {
// send data only when you receive data: if (Serial2.available() > 0) { // read the incoming byte: incomingByte = Serial2.read();
if(incomingByte == 49) digitalWrite(led, HIGH); else if(incomingByte == 50) digitalWrite(led,LOW); } }
Step 8: Processing
This is the other half. First import processing.serial. plug you other xbee to the XBee Explorer Dongle v2 and into your computer, I had found a usb extension lead useful. Pick which port you are attach too.Clicking and holding the mouse button it now should turn on led 13 on the board. This code was wrote in v2.1.1
import processing.serial.*; Serial myPort; // Create object from Serial class
void setup(){ size(640, 360); println(Serial.list());// This will list serial ports String portName = Serial.list()[5];// port number myPort = new Serial(this, portName, 9600); }
void draw(){ if (mousePressed) { myPort.write(49); } else { myPort.write(50); } }
Step 9: Final Code
Here is the Final code for the arduino mega 2560. I have created sub commands to make it easier.
//ROBOT CAR CODE 004 // commands // forward() // backward() // rotate_left() // rotate_right()
//notes // FULL 360 rotate // (TIME = 12000); //delay time // (SPEED = 200); //speed 0-255 // rotate_right(); int incomingByte = 0; // for incoming serial data //speed pins 0 - 255
#define encoderA 2 #define encoderB 3 // Only use one interrupt in this example #define encoderC 19 #define encoderD 18 // Only use one interrupt in this example volatile int Lcount; volatile int Rcount; int Lcountsaved; int Rcountsaved;
int speedch1 = 9; // left front int speedch2 = 10; // left back int speedch3 = 11; // right front int speedch4 = 12; // right back // direction pins int dirch1 = 44; // left front int dirch2 = 45; // left back int dirch3 = 42; // right front int dirch4 = 43; // right back
int curch1 = A1; // left front int curch2 = A2; // left back int curch3 = A3; // right front int curch4 = A4; // right back int TIME; //time the command is for int SPEED;// 0 - 255 motor speed
int count; int check1; //see if subcomand has run int check2; //see if subcomand has run int check3; //see if subcomand has run int check4; //see if subcomand has run int check5; //see if subcomand has run
void setup() { Lcount=0; Rcount=0;
// initialize the digital pin as an output. pinMode(dirch1,OUTPUT); pinMode(dirch2,OUTPUT); pinMode(dirch3,OUTPUT); pinMode(dirch4,OUTPUT);
pinMode(speedch1,OUTPUT); pinMode(speedch2,OUTPUT); pinMode(speedch3,OUTPUT); pinMode(speedch4,OUTPUT);
pinMode(encoderA, INPUT); pinMode(encoderB, INPUT); attachInterrupt(0, LhandleEncoder, CHANGE); pinMode(encoderC, INPUT); pinMode(encoderD, INPUT); attachInterrupt(5, RhandleEncoder, CHANGE);
Serial2.begin(9600); Serial.begin(9600);
analogWrite(speedch1,0);// stop all analogWrite(speedch2,0);// stop all analogWrite(speedch3,0);// stop all analogWrite(speedch4,0);// stop all
count = 0; (SPEED = 200);
}
// the loop routine runs over and over again forever: void loop() {
if (Serial2.available() > 0) { // read the incoming byte: incomingByte = Serial2.read(); } if(incomingByte == 10 && check1 == 0) forward(); else if(incomingByte == 11 && check2 == 0) rotate_right(); else if(incomingByte == 12 && check3 == 0) backward(); else if(incomingByte == 13 && check4 == 0) rotate_left(); else if(incomingByte == 14 && check5 == 0) pause();
// if(incomingByte == 16){ // if (Lcount != Lcountsaved && Rcount != Rcountsaved) Serial2.print(Lcount,DEC);//send encoder data Serial2.print(","); Serial2.print(Rcount,DEC); Serial2.print(","); Serial2.println(); incomingByte = 1; // Lcountsaved = Lcount; //Rcountsaved = Rcount; // } } void LhandleEncoder() { if(digitalRead(encoderA) == digitalRead(encoderB)) { Lcount++; } else { Lcount--; } }
void RhandleEncoder() { if(digitalRead(encoderC) == digitalRead(encoderD)) { Rcount++; } else { Rcount--; } }
void forward() { check2 = 0; check3 = 0; check4 = 0; check5 = 0; analogWrite(speedch1,0); analogWrite(speedch2,0); analogWrite(speedch3,0); analogWrite(speedch4,0); delay(100); digitalWrite(dirch1,LOW); digitalWrite(dirch2,HIGH); digitalWrite(dirch3,LOW); digitalWrite(dirch4,HIGH); analogWrite(speedch1,SPEED); analogWrite(speedch2,SPEED); analogWrite(speedch3,SPEED); analogWrite(speedch4,SPEED); check1 = 1;
}
void backward() { check1 = 0; check2 = 0; check4 = 0; check5 = 0; analogWrite(speedch1,0); analogWrite(speedch2,0); analogWrite(speedch3,0); analogWrite(speedch4,0); delay(100); digitalWrite(dirch1,HIGH); digitalWrite(dirch2,LOW); digitalWrite(dirch3,HIGH); digitalWrite(dirch4,LOW); analogWrite(speedch1,SPEED); analogWrite(speedch2,SPEED); analogWrite(speedch3,SPEED); analogWrite(speedch4,SPEED);
check3 = 1;
}
void rotate_right() { check1 = 0; check3 = 0; check4 = 0; check5 = 0; analogWrite(speedch1,0); analogWrite(speedch2,0); analogWrite(speedch3,0); analogWrite(speedch4,0); delay(100); //wait to stop digitalWrite(dirch1,LOW); digitalWrite(dirch2,HIGH); digitalWrite(dirch3,HIGH); digitalWrite(dirch4,LOW); analogWrite(speedch1,SPEED); analogWrite(speedch2,SPEED); analogWrite(speedch3,SPEED); analogWrite(speedch4,SPEED); check2 = 1;
}
void rotate_left() { check1 = 0; check2 = 0; check3 = 0; check5 = 0; analogWrite(speedch1,0); analogWrite(speedch2,0); analogWrite(speedch3,0); analogWrite(speedch4,0); delay(100); digitalWrite(dirch1,HIGH); digitalWrite(dirch2,LOW); digitalWrite(dirch3,LOW); digitalWrite(dirch4,HIGH); analogWrite(speedch1,SPEED); analogWrite(speedch2,SPEED); analogWrite(speedch3,SPEED); analogWrite(speedch4,SPEED); check4 = 1;
}
void pause() { check1 = 0; check2 = 0; check3 = 0; check4 = 0; analogWrite(speedch1,0); analogWrite(speedch2,0); analogWrite(speedch3,0); analogWrite(speedch4,0); check5 = 1; }
Step 10: Final Processing Code
Here is the Processing code used to run the xbee. I have striped it back to the basics. arrow key for direction and ctrl for stop. I have included the data in channel to receive the encoders. it some times crashes when it only receives 1 encoder, i don't know why. Code written in 2.1.1
import processing.serial.*; Serial myPort; // Create object from Serial class int lf = 10; // Linefeed in ASCII int source1; int source2; String myString = null;
void setup(){ size(640, 360); println(Serial.list()); String portName = Serial.list()[5]; // pick the port connected myPort = new Serial(this, portName, 9600); myPort.clear();
myString = myPort.readStringUntil(lf); myString = null; source1 = 0; source2 = 0;
} void draw(){ background(255,255,255); textSize(32); text(source1,20,60); text(source2,20,120); fill(0,0,0); while (myPort.available() > 0) { myString = myPort.readStringUntil(lf); if (myString != null) { println(myString);
String[] q = splitTokens(myString, ",");//split at "," println(q.length + " values found"); // Prints 2 values found" source1 = int(q[0]); source2 = int(q[1]); } } } void keyPressed() { if (key == CODED) { if (keyCode == UP) { myPort.write(10);//Forward } else if (keyCode == DOWN) { myPort.write(12);//Backward } else if(keyCode == LEFT){ myPort.write(13);//LEFT } else if(keyCode == RIGHT){ myPort.write(11);//Right }else if(keyCode == CONTROL){ myPort.write(14); //Pause } } }
Step 11: Proof It Works
Here is a short video of the rover rolling over some obstacles. Hope this has been helpful to you. I will try to answer any question about my robot. I plan to enter some Instructable competitions and would love the help of your vote.

Participated in the
Tech Contest

Participated in the
Microcontroller Contest
5 Comments
7 years ago
Thank you so much for the wiring diagrams. I have searched for these, especially the connections between the Arduino and the controller board. I've asked Dagu, Pololu and Sparkfun (all produced versions of the board) but NO ONE would give me a picture like this!!! Thanks again. If you have any updates to this project (in regards to the controller board, Mega and Rover), I'd love to see them.
8 years ago
How do I alter the coding if I want to use WASD keys or arrow keys to send commands?
Thank you!!!
9 years ago
Smart idea! Thanks for shearig :)
9 years ago on Introduction
Thanks for sharing what you learned! Looks like it was fun and that you created something pretty cool!
Reply 9 years ago on Introduction
@MsSweetSatisfaction Thanks for taking the time to comment, love your Nightvale's Glow Cloud idea.