The Dodging Robot

IMG_3562

In this Project I plan on remotely controlling a two-wheeled car I built via bluetooth.In this project I wanted to make a small two wheeled robot that drives around dodging evrything infront of it.
I mounted two SHARP IR Distance sensors to the front so that the robot can decide which way to turn if an object triggers either sensor.

I used an 18 pin dsPIC30F3012 for this as I wanted to fit the dsPIC and driver chip SN754410NE onto one small breadboard, also the dsPIC30F3012 had all the io I needed.

I used state’s for each circumstance the robot can be in, in each state there are conditions that if occur the program will change to a different state.

The states of the code go as follows:

StateMachineTable

The output voltage of the infrared sensor was then measured at different distances so that I could decide at what distance I wanted it to turn.
The results were as follows:

Capture

Plotted on a graph it looked like this:

Capture1

Here is a wiring diaram of the circuit:

rect4922

Here is my code:


// dsPIC30F3012
// The dodgy Robot
// Written by Aron Horan
// The plan of this project is to make a two wheeled robot with two IR sensors
// mounted to the front. The robot will simply drive around dodging objects.
// If the two sensors have a low reading the robot will drive straight,
// if the left sensror goes high and right is low the robot turns right and vise versa,
// if either sensor goes very high the robot will reverse for a second and turn around

#include <xc.h>
#include <stdio.h>

// Configuration settings
_FOSC(CSW_FSCM_OFF & FRC_PLL16); // Fosc=16x7.5MHz, Fcy=30MHz
_FWDT(WDT_OFF);                  // Watchdog timer off
_FBORPOR(MCLR_DIS);              // Disable reset pin

// Function prototypes
unsigned int read_analog_channel(int);

int main()
{
	const turn_right = 0, turn_left = 1, forward = 2, turn_around = 3;
	int state = forward;
	int left_eye;
	int right_eye;
	int sw = 0;
	
	// Configure UART
	U1BRG = 48;            // 38400 baud @ 30 MIPS
	U1MODEbits.UARTEN = 1; // Enable UART
	

	// Make RB0-3 outputs
	TRISB = 0b1111111111110000;

	// Configure analog inputs
	ADPCFG = 0b1111111100111111;// Only AN6 and AN7 are analog inputs
	ADCON1 = 0;                 // Manually clear SAMP to end sampling, start conversion
	ADCON2 = 0;                 // Voltage reference from AVDD and AVSS
	ADCON3 = 19;            	// Manual Sample, ADCS=9 -> Tad = 10*Tcy = 333ns
	ADCON1bits.ADON = 1;        // Turn ADC ON

	
	while(1)
	{
		left_eye = read_analog_channel(6); 	// read infrared detector
		right_eye = read_analog_channel(7); // read infrared detector
	
	   
       if (state == forward)
       {
            LATB = 0b1010; // motors: left forward, right forward
            if (left_eye > 900 && right_eye < 900) state = turn_right;
            if (left_eye < 900 && right_eye > 900) state = turn_left;
            if (left_eye > 2200 || right_eye > 2200) state = turn_around;
       }
       
       else if (state == turn_right)
       {
              LATB = 0b1000; // motors: left stop, right forward
              if (left_eye < 900 && right_eye < 900) state = forward;
              if (left_eye > 2200 || right_eye > 2200) state = turn_around;
       }
       
       else if (state == turn_left)
       {
            LATB = 0b0010; // motors: left forward, right stop
            if (left_eye < 900 && right_eye < 900) state = forward;
            if (left_eye > 2200 || right_eye > 2200) state = turn_around;
       }
       else if (state == turn_around)
       {
            LATB = 0b0101; // motors: left reverse, right reverse
            __delay32(40000000);
            LATB = 0b0110; // motors: left reverse, right reverse
            __delay32(30000000);
            state = forward;
       }
       	    __delay32(300000);
	}
	return 0;
}

// This function reads a single sample from the specified
// analog input. It should take less than 2.5us if the chip
// is running at about 30 MIPS.
unsigned int read_analog_channel(int channel)
{
	ADCHS = channel;          	// Select the requested channel
	ADCON1bits.SAMP = 1;      	// start sampling
	__delay32(30);            	// 1us delay @ 30 MIPS
	ADCON1bits.SAMP = 0;      	// start Converting
	while (!ADCON1bits.DONE);	// Should take 12 * Tad = 1.2us
	return ADCBUF0;
}

Here are some pictures of the finished piece:

IMG_3402

IMG_3403

IMG_3404

IMG_3406

IMG_3407

I will have a video of it in action very shortly, im just low on batteries at the moment and can only run it while plugged in, which wouldn’t make a good video…

Had a bit of a disaster with this little poor fellow. Afer driving from Greystones to Dublin on my bike I Arrived into college to find my bag zip open… Dodgbot was gone…

So without further wait I bring to you…..

DODGBOT V2.0IMG_3554IMG_3556

IMG_3558

IMG_3560

IMG_3562

IMG_3554

I ended up having to buy a set of AA NI-MH rechargable batteries as it kept resetting when the motors switched into reverse due to the curent surge and voltdrop.

Still even with these new 1700mAH batteries it was still resetting, so I ended up using a heap of capacitors (2160uF) is was done the trick.

So finally here is a video of it in action: