# How-to for Thomas

First, lets state our goal:
We want a robot to drive to dark areas while avoiding stuff on the way using various sensors.

As with everything, we break it down into smaller pieces. We test each one individually, record any numbers we get (ADC readings and the like) and then start putting them together. While doing each of these tests individually, it helps us figure out how we are eventually going to put them together.

If someone told me to accomplish the goal above, I would do it just like this:

• Test of LDR's by themselves. No mapping, raw data. Write these numbers down (dark, light, etc)
• Code the robot to turn on its center until both LDR readings are identical or within a threshold --then I would play with this code and a flashlight for a while
• Code the robot to do basically the same thing as above, but go forward this time. See if you can steer to the dark side, see if you can get it to turn proportionally in relation to the difference in readings of the 2 LDR's
• Forget about the LDR's completely and move on to the sonar sensor
• Test the sonar sensor all by itself
• Code the robot to drive forward until it sees an object at a given distance and have it stop
• Forget about the sonar sensor completely
• Code the robot to drive off of its sharp sensors (I assume these are R/L pointing outward) --these can be coded to "scoot" you off of a wall (when you are coming in shallow and your main sonar misses it) Code the robot to drive forward, check its side sensors and make a small correction (just a small correction) to "scoot" off the wall
• Add your sonar code to your sharp code (still without the LDR's) and have your robot do 2 things --scoot off of the wall, and stop when the main sonar sees something too close

At this point, you will need to stop and think about the actual operation of the bot. Right now, we just stop when we see something and have to reset the bot to make another run. Lets think about what we would want to do instead. We are driving forward, we see something,  --might be good to turn. Which way? Well, as it happens, we have 2 sharp sensors sticking out to the sides, lets ask them and see if either way is better (farther). Our code might look like this:

• Go forward, check all sensors
• If sonar is too close, turn. Base turn direction on readings from Sharps
• If both sharps and sonar are too close --Allstop, goto stuck in corner routine
• if none of the above is the case, drive forward

Ok, so now we have a robot that reads all 3 navigaion sensors and knows which sensor is more important than the others and drives accordingly. Let's go back to our LDR code.

• You still have a "read the LDR's" routine left over --great
• Add to this read the LDR's routine, some code that will figure the "turn request"  I.e. the LDR's want to turn left or want to turn right.
• Add this "check the LDR's" to your main loop --it can go right next to the code that reads all the other sensors

Now, here's the tricky part:

Add this turn request to the beginning of your navigation code. Now, the navigation routine continues (the stuff we talked about above, scooting off of walls, front sonar etc.) and if any of that happens, it comes after your turn request in the code. --It will "cancel out" the turn request, ignore it, and just do regular navigation. However, lets say the robot is out in the wide open. It runs through the navigation routine (starting with the turn request from the LDR's), but this time its obstacle avoidance is not the priority --there is nothing in front of the bot (or to the sides) and the robot will not correct its path. Thus, it will not "cancel out" your LDR turn request, it will "get through" and be done. Now, we just turned to the dark.

Wow, please tell me at least some of that helped...

## Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

I like the idea of prioritizing the sensors ,never thought of this one .

A Very explaining and inspiring guide.

very helpful i have an idea and would like to sell soon enough hope it will work. sold 4 of my bots so far..

#include <Servo.h> //include Servo library

const int irPin = A1;  //Sharp infrared sensor pin

const int dangerThresh = 276; //threshold for obstacles

const int ledPinstop = 3;       // the pin that the LED is attached to

const int ledPingo = 12;       // the pin that the LED is attached to

int rightDistance; //distance away from obstacles on the right

int centerDistance; //distance away from obstacles in the center

int leftDistance;  //distance away from obstacles on the left

int averaging;                // Stores average of distance

int val = 0;

int dist = 0;

//declare motors

Servo myservo;

Servo servoleft;     //Left wheel

Servo servoright;    //Right wheel

void setup()

{

pinMode(ledPingo, OUTPUT);

pinMode(ledPinstop, OUTPUT);

myservo.attach(9);          // head to pin D9

myservo.write(93);          // set IR sensor pan to center

servoleft.attach(10);       // Left servo to pin D10

servoright.attach(11);      // Right servo to pin D11

servoright.write(90);

servoleft.write(90);

}

void forward()

{

servoleft.write(0);

servoright.write(180); //move forward

}

void scan_area()

{

servoleft.write(90);

servoright.write(90);

delay(100);

myservo.write(125);

delay(300);

rightDistance = analogRead(irPin); //scan to the left

delay(100);

delay(300);

centerDistance = analogRead(irPin); //scan center

delay(100);

myservo.write(50);

delay(300);

leftDistance = analogRead(irPin); //scan to the right

delay(100);

delay(300);

centerDistance = analogRead(irPin); //scan center

delay(100);

}

int get_avg(int IRpin) //Gets 3 readings from the sensors and averages them to get rid of spikes

{

int total = 0;

for(int x = 0; x <=3; x++)

{

}

}

void loop()

{

int val = analogRead(irPin); //read IR sensor

if (val<dangerThresh) //if path is clear

{

digitalWrite(ledPingo, HIGH);

forward();

}

else //if path is blocked

{

digitalWrite(ledPingo, LOW);

digitalWrite(ledPinstop, HIGH);

scan_area();

compareDistance();

digitalWrite(ledPinstop, LOW);

}

}

void compareDistance()

{

if (leftDistance<rightDistance && leftDistance<centerDistance) //if left is less obstructed

{

servoleft.write(180);

servoright.write(180);  //turn right

delay(300);

}

else if (rightDistance<leftDistance && rightDistance<centerDistance) //if right is less obstructed

{

servoleft.write(0);

servoright.write(0); //turn left

delay(300);

}

else //if they are equally obstructed

{

servoleft.write(180);

servoright.write(0); //move back

delay(300);

servoleft.write(0);

servoright.write(0);    //turn left

delay(950);

scan_area();

compareDistance();

}

}