Tuesday, November 17, 2015

Rover 5 using Xbee and Arduino Mega 2560

Hello everyone, In this post you are going to learn how to work with Dagu Rover 5.I am a big enthusiast for the sharing of knowledge and get lot of information from the internet,so here is me sharing my  collective knowledge to all of you.

I have shown you the image of Dagu rover 5 arduino uno mega 2560 Xbee by which you can get some sort of idea of it.
The various items needed for this project are
Dagu Rover 5  in which I have the 4 motors/ 4 encoder model
rover 5 motor driver Board
arduino uno mega 2560
Xbees ,here 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 wire
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 center for the wires from the motors and encoders to come through. After that, cut some to plastic bit with a pointed knife. then pull the wires through, this will allow for the plate to be mounted flat.

Step 2: Wiring Part A

First of all,you have to attach the motor and encoder wires to the rover 5 motor driver Board. I have shown the image above of how i wired it but it doesn't show how I attach the motor and encoder wires. To wire these, draw them back to the motor and then plug them into the right port. For the encoder wires you have to 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


Above shown image shows you how I wire the rover 5 motor driver Board to the arduino uno mega 2560.
Now, I am showing you some arduino codes 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

Here, I have included the cur(current) pins and I have used a breadboard for a common ground, this may be wrong but it works best for me.

Step 4: Platform to hold batteries


After wiring the lower platform, there is no room for batteries. Then I created one for mine out of paper mache and wire.That is not very good, possible alternatives 3d print or shop bought box that fits.Then we have to attach the batteries via velcro.


Step 5: Coding basic

Now, I am presenting you the basic code for all four motor to spin for 5 seconds, and here,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
Now, I am presenting a easy code for the left encoder.After working for many hours, I       found a linear encoder code that works best for our project.This code will spin the left      motors until the encoder(count) reaches 500.It also print it to the serial monitor.It is same for the other side just have to change the pins and names.
// 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
We will need Xbees to solder some pins into it. First of all,take Xbees of your choice and program them to take to each other on the same channel using XBee Explorer Dongle v2 and XCTU.Choose the serial port for the Xbee on the Arduino 2 or 3 and after that you have to run these easy receiving code.This code will turn led 13 on the board on when it  receives processing in the 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 another step.Firstly,import processing.serial. plug you other xbee to the XBee Explorer Dongle v2 and into your computer,here I found a USB extensionlead.Then,you  have to button it now should turn on led 13 on the board.I have written this code in pick    the port to which you are attach too and Clicking and holding the mouse 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

Now,I am presenting you the final code for the arduino uno mega2560.Here,I have          created the subcommands so that it will be easy for all of you to understand.
//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
Now,I am presenting you the processing code which is used to run the Xbee.I have used arrow keys for the direction and ctrl key for stop.I have included the data in channel to receive the encoders.Sometimes,it crashes when it only receives 1 Encoder Code is written in step 2.
 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: How It works.
Below I have uploaded a video of the rover rolling over some obstacles.I just hope my blog will be helpful to you.











1 comment:

  1. The 13 Casino in Santa Barbara, CA - Mapyro
    Find the cheapest 목포 출장안마 and quickest ways to get from 속초 출장마사지 The 13 Casino in Santa Barbara, 시흥 출장샵 CA to The 아산 출장마사지 13 Casino in Santa Barbara, CA. 경주 출장마사지

    ReplyDelete