Rover 5 can now explore a confined space – various code changes

Getting the exciting bit out there first here is a video of my Rover 5 driving itself around an enclosed space. It definitely isn’t perfect at all yet but I’m pretty happy that I got things to this state with a few basic code changes.

 

So, to get to this state I had 3 main code changes.

First I needed to have a function to Rotate the rover. Rather than create a new function I decided to modify Go() somewhat. Now we can pass Go two parameters, one for the left motors speed and one for the right motors speed. As going “forwards” for each side’s motors is a different direction (I hope that makes sense!) the code is a bit more complex than it would be otherwise.

void Go(int speed, int speed2) // pretty sure this is right_speed, left_speed but need to check
{
if(speed<0) //if we want this side to go backwards then do the following.
{
digitalWrite(M1,LOW);
digitalWrite(M2,LOW);
speed=speed*-1; //get the speed back to a positive value which can be used to drive a PWM output to send a speed to the motors.
}
else //otherwise, forward it is for this side.
{
digitalWrite(M1,HIGH);
digitalWrite(M2,HIGH);
}
if(speed2<0) //if we want this side to go backwards then do the following.
{
digitalWrite(M3,HIGH);
digitalWrite(M4,HIGH);
speed2=speed2*-1; //get the speed back to a positive value which can be used to drive a PWM output to send a speed to the motors.
}
else //otherwise, forward it is for this side.
{
digitalWrite(M3,LOW);
digitalWrite(M4,LOW);
}

analogWrite(E1,speed); //PWM Speed Control (right motors)
analogWrite(E2,speed); //PWM Speed Control
analogWrite(E3,speed2); //PWM Speed Control (left motors)
analogWrite(E4,speed2); //PWM Speed Control
}

So, we can now go Go(255,255) to go forwards at full speed, or Go(255,-255) to rotate left at full speed.

The next part I wanted to do is to give me a way to put the Rover 5 in to debug mode where it does nothing but output sensor data and does not drive it’s tracks at all. It’s pretty annoying when making changes to code to have the motors whirling away all the time. Basically, all we do here is to input a “d” over the serial to go in to debug mode, and input a “n” to go back to normal or operational mode.

The following code goes in my main loop function and handles reading in from serial.

//We'll reset readString back to nothing in case it was set last time this loop was run
readString="";

if (Serial.available() > 0)
{
// read the incoming byte:
char character = Serial.read();
readString += character; //makes the string readString

if(readString=="d") //if user wants to put us in debug mode
{
debug=1;
Serial.println("Debug Mode On");
Stop(); //it is key to run this to set all motor speeds to zero!
delay(500); //not actually required - just a self imposed delay.
}
else if(readString=="n") //if user wants to put us in operational mode
{
debug=0;
Serial.println("Debug Mode Off");
//delay(500);
}
}

Finally, I need to adapt the code to turn left when sensing objects in front rather than just stopping. But at the same time I didn’t like the behaviour to be instantly turning left or instantly going forward again. So I added some basic states that get set (go, or turn) and then detection of changes of states. When state has been changed the Rover 5 is stopped and object detection paused for a moment.

This also went in my main loop()

if(debug==0)
{
if(dist>35) //if IR Dist sensor reports object not close in front then go forward
{
currentState="go";
if(currentState!=previousState) //if we have just changed state to "go" then stop and wait for 300 msec
{
Stop();
delay(300);
}
Go(255,255);
previousState=currentState;
}
else //if IR Dist sensor reports object close in front then turn
{
currentState="turn";
if(currentState!=previousState) //if we have just seen an object then stop the rover and wait for 1 sec
{
Stop();
delay(1000);
}
Go(220,-220);
previousState=currentState;
}
}
delay(100); //delay 100 at end of loop. Mainly used right now to keep output over serial to a human readable amount.

All in all things seemed to work pretty good for now.

Next up I think I’ll try and get the ultra-sonic sensor hooked up and reading from it. However, I’m now worried that I mounted this too high on the chassis to be useful.

IMG_0452

Share on Facebook

First proper test – all worked nicely

So, a couple of days ago my jumper leads arrived from Mindkits. I managed to quickly hook up both motor drivers (4 motors in total) and do a basic test.

IMG_0465

Then yesterday I managed to write some basic code. I wanted to keep things really simple so I have a function called Go() and another called Stop(). I’ll leave it as an exercise for the reader to deem what they do.

Finally, I have a simple function to read from the only distance sensor I have attached so far – the one on the front.

I had to do quite a bit of tweaking of how fast to set the motors for it to work on carpet. In the end I just went with full speed as anything less can make it fail to start moving.

Here is the video of its first test.

Here is my current code. Pretty simple stuff!

//
// Right tracks of Rover 5.
// E2/M2 are the front motor
// E1/M1 are the rear motor
//

int E1 = 2; //PWM
int M1 = 14;
int E2 = 3; //PWM
int M2 = 15;   

//
// Left tracks of Rover 5.
// E4/M4 are the front motor
// E3/M3 are the rear motor
//

int E3 = 4; //PWM
int M3 = 16;
int E4 = 5; //PWM
int M4 = 17;   

// Front Distance Sensor
int Dist1 = 6;

void setup() 
{ 
   pinMode(M1,OUTPUT);   
   pinMode(M2,OUTPUT);
   pinMode(M3,OUTPUT);   
   pinMode(M4,OUTPUT);   

   pinMode(Dist1,OUTPUT);
   Serial.begin(9600);
} 

void loop() 
{ 
  Serial.println(getDist());
  int dist=getDist();
  if(dist>30) 
  {
    Go(255);
  }
  else
  {
    Stop();
  }
  delay(250);
}

int getDist()
{
  int i=analogRead(Dist1);
  int val=(6762/(i-9))-4;
  return val;
}

void Go(int speed)
{
  digitalWrite(M1,HIGH);
  digitalWrite(M2,HIGH);
  digitalWrite(M3,LOW);
  digitalWrite(M4,LOW);  
  analogWrite(E1,speed);   //PWM Speed Control
  analogWrite(E2,speed);   //PWM Speed Control
  analogWrite(E3,speed);   //PWM Speed Control
  analogWrite(E4,speed);   //PWM Speed Control    
}

void Stop()
{
  analogWrite(E1,0);   //PWM Speed Control
  analogWrite(E2,0);   //PWM Speed Control
  analogWrite(E3,0);   //PWM Speed Control
  analogWrite(E4,0);   //PWM Speed Control   
}
Share on Facebook

We have power

It seems trivial, but the below photo is the first time I’ve powered all 3 boards of the Rover 5 from the battery. Note 3 LEDs shining!

IMG_0460

 

Re-doing power is definitely a job for some time in the future. For now I have a simple on off switch connected to the + input. Then the Arduino and two motor drivers hooked up in parallel off of the switch and the GND input.

I’m wondering if I need a fuse anywhere? I’m pretty sure the chassis motors have a fuse on their power leads but don’t know if I need one on the input from the battery right now.

Share on Facebook

Distance sensor for Rover5

If we take a look at the pins on the arduino we see it goes GND, VCC, SENSOR.

IMG_0453

And if we look at the pinout from the distance sensor on the end of the lead we see SIGNAL, GND, VCC or VCC, GND, SIGNAL. Either way it isn’t going to work.

IMG_0454

So, as a crude fix I just swapped the red and the black cables around half way down the cable and then used electrical tape to label the plug pins correctly.

IMG_0457

Then I ran some basic test code on the Arduino and read in the values from the sensor. It seems that numbers under 10 are very close objects, 10 – 20 near by, and anything over 100 seems to mean nothing much around. Will need to do some more tuning later on this I expect.

Screen Shot 2013-05-18 at 8.27.49 PM

Here’s my current test code:

#include <SoftwareSerial.h>
int i;
int val;
int redpin=6;
void setup()
{
pinMode(redpin,OUTPUT);
Serial.begin(9600);
}
void loop()
{
int i=analogRead(redpin);
int val=(6762/(i-9))-4;
Serial.println(val);
delay(1000);
}
Share on Facebook

Arduino Rover 5 stage 2

In my previous post I taked about what I had bought and my basic test to prove how the motors and motor drivers work.

I now needed to get the components mounted on the chassis somehow and come up with a good method to connect them together. I also decided that I wanted an on/off switch to save having to disconnect the battery to power everything down.

My boss found me a electrical mounting board that he uses when building wireless radio sites on the top of hills which is mounted in a large cabinet.

First I glued (using the trusty glue gun) some plastic spaces to the board in the correct positions for the arduino and motor controllers. I also added a real simple power-in block, switch, and power-out block. The aim is to wire up the arduino, and the two motor controllers in to the power-out block in parallel.

IMG_0439

Below is my first go at mounting the board on the chassis itself. Note, one screw hole didn’t line up for the chassis but oh well!

IMG_0445

Next I added some basic surrounds to hold the battery in place, wired the battery in to my basic switch and also added some various mounts for all of the proximity sensors that I’ve purchased.

IMG_0448

Finally, after wiring in the power for the motor controllers and adding a few sensors this is currently what my robot looks like below.

IMG_0452

 

Now I’m waiting on some jumper leads designed for arduino stuff to arrive from Mindkits. Hopefully those arrive on Tuesday!

Share on Facebook

I decided to build a robot!

I wanted to do something new with Arduino and I figured building some form of robot seemed to be simple enough but give a lot of possibility to make it as complicated as I like.

There were quite a few kits out there to choose from and I went with a Dagu Rover 5 mainly as it seemed to have no majorly negative reviews and it was in stock at a local NZ stockist – Mindkits.

Dago Rover 5

IMG_0425IMG_0426

Above: Unpacking the kit from Mindkits. I ended up with 4 distance sensors, 1 chassis with 4 motors, an ArduinoMEGA 2560, an MEGA Sensor shield, and 2 motor drivers. I also got an ultrasonic sensor and mounting bracket with it.

My first task was to work out how the motor worked. It seemed simpler to use the normal Arduino headers that I was used to before exploring all of the Mega Expansion shield headers. I hooked these up to a breadboard, hooked up a motor driver, added in a LiPo battery from JayCar and made some basic test code to make one track (two motors) go forward and back. Photo below.

IMG_0436

Below is some example code with some basic changes made. It makes 2 motors (one track) go forward for 3 secs, backwards for 3 secs and then do nothing for 8 secs. Repeat..

 

// # Editor : Lauren from DFRobot
// # Date : 17.02.2012

// # Product name: L298N motor driver module DF-MD v1.3
// # Product SKU : DRI0002
// # Version : 1.0

// # Description:
// # The sketch for using the motor driver L298N
// # Run with the PWM mode

// # Connection:
// # M1 pin -> Digital pin 4
// # E1 pin -> Digital pin 5
// # M2 pin -> Digital pin 7
// # E2 pin -> Digital pin 6
// # Motor Power Supply -> Centor blue screw connector(5.08mm 3p connector)
// # Motor A -> Screw terminal close to E1 driver pin
// # Motor B -> Screw terminal close to E2 driver pin
// #
// # Note: You should connect the GND pin from the DF-MD v1.3 to your MCU controller. They should share the GND pins.
// #

int E1 = 6;
int M1 = 7;
int E2 = 5;
int M2 = 4;

void setup()
{
pinMode(M1, OUTPUT);
pinMode(M2, OUTPUT);
}

void loop()
{
digitalWrite(M1,HIGH);
digitalWrite(M2,HIGH);
analogWrite(E1, 170); //PWM Speed Control
analogWrite(E2, 170); //PWM Speed Control
delay(3000);
digitalWrite(M1,LOW);
digitalWrite(M2,LOW);
analogWrite(E1, 170); //PWM Speed Control
analogWrite(E2, 170); //PWM Speed Control
delay(3000);
digitalWrite(M1,HIGH);
digitalWrite(M2,HIGH);
analogWrite(E1, 0); //PWM Speed Control
analogWrite(E2, 0); //PWM Speed Control
delay(8000);
}

This all worked nicely so the next step (in my next post) is to start working how I will mount all of the circuit boards and sensors on the chassis itself.

Share on Facebook

Growing Tomatoes from seeds

I decided back in September 2012 to grow some tomatoes from scratch.

So I planted some seeds in trays and put them in the hot water cylinder cupboard. At the same time I started building a cold frame to protect them from the elements when they were ready to go outside.

Lid:

IMG_0089

Frame:

IMG_0090

After about 10 days in the cupboard the seedlings had geminated and I moved them to the window sill in the lounge.

IMG_0091

About late November at a guess, had been outside in the cold frame for a while and I was starting to leave the lid off a bit and harden them up.

IMG_0153

Had to water the plants pretty much every day all throughout summer. But its been so sunny that the plants went really well and have given us heaps of tomatoes so far.

And then end results.

IMG_0279

IMG_0280

And a picture of the cold frame once it was fully built (minus lid)

IMG_0281

Share on Facebook