Journal for the creation of the Prodigialis Robot – Day 2

The wiring continues

Today, I fixed the flipped and connected the power and ground wires to the positive and negatives columns on the breadboard. Then I wired the positive and negative wires to the servos over to the positive and negative columns. In the picture I removed a lot of wiring, so you can see the wiring I just talked about more clearly.

IMG_0687

So, now that the Servos were wired up, the robot should have worked, right? Nope, took me another 3 minutes or so to realize that I had connected the controller wire to the power wire on the servo header. So, I moved the controller wire over to the correct spot. I could now move on to the  programming, which I promptly did.

Here’s the diagram of the final wiring:

AWARE-Day1-final_bb

The Programming:

I had to download and install the Arduino IDE, though that wasn’t too hard because I was using Ubuntu. (Yes, I am going to be pushing it. It’s the best Operating System. Period, exclamation point.) I simply entered the terminal and ran

sudo apt-get install arduino

It downloaded and installed without a hitch, so I fired it up and it set up all the stuff I needed. I logged out and back in again, to make sure it was set up right, and it worked. Thus the programming begins.

The Arduino language is basically C/C++ compiled into instructions the Arduino can understand, so I am learning a new language, one I’ve been wanting to, while making this cool robot! Win, win.

So, the first program I ever wrote was your generic “Hello World!” program. This is the code for it:

void setup()
{
	Serial.begin(9600);
}

void loop()
{
	Serial.println(“Hello World!”);
}

Simple enough. void setup() is what runs first in an Arduino program, and is where most of the program is, obviously, set up. Serial.begin(9600); simply sets the baud rate on the Serial console to 9600. Read this wikipedia article for the technical side of it, and the Arduino page for the programming explanation. It just repeatedly prints the string “Hello World!” to the Serial console. I uploaded it to the Arduino and it ran. My first Arduino and first C/C++ program! Awesomesauce!

I then programmed simple movement into the robot, using this code:

#include 

//create the Servo objects
Servo leftMotor;
Servo rightMotor;

void setup()
{
	leftMotor.attach(13);
	rightMotor.attach(12);
}

void loop()
{
	leftMotor.write(180);
	rightMotor.write(180);
}

The code creates a couple of Servo objects after importing the Servo library and then attaches the objects to the pins on the Arduino. Then, it writes the value 180 to both of the motors. This made the robot go in a circle.

Wait a minute…they’re the same value, why is the robot going in a circle?

Because, the servos are actually flipped. If you think about, it makes sense.

Servos are designed as duplicates, so when they are put on opposite sides, they are reversed. Thus, writing the same value would cause the servos to turn opposite directions. Change the value of one of the Motor.write() statements to 0 and the robot should either go forwards, or backwards, depending on which servo you change.

Now, on to the Supersonic sensor. A supersonic sensor, simply put, sends out a super-high-pitched (supersonic) “ping”. It goes out until it hits an object and then returns to the sensor. The sensor then gives the data regarding the “ping” back to the Arduino. One of the Foxytronics tutorials tells about the math involved in calculating the distance.

So, I had to code the sensor:

const int serialPeriod = 250;	// only print to the console every  ¼ second
unsigned long timeSerialDelay = 0;

const int loopPeriod = 20;		// a period of 20ms = a frequency of 50Hz
unsigned long timeLoopDelay = 0;

// specify the trig and echo pins used for the ultrasonic sensors
// keep these the same, otherwise your robot will think it has 0 cm in front of it
// thus it tries to turn away, putting it in an endless circle.
const int ultrasonic2TrigPin = 8;	
const int ultrasonic2EchoPin = 9;

int ultrasonic2Distance;
int ultrasonic2Duration;

void setup()
{
	Serial.begin(9600);

	// ultrasonic sensor pin configurations
	pinMode(ultrasonic2TrigPin, OUTPUT);
	pinMode(ultrasonic2EchoPin, INPUT);
}

void loop()
{
	debugOutput()	// prints debugging messages to the serial console

	if(millis() - timeLoopDelay >= loopPeriod)
	{
		readUltrasonicSensors();	//read and store the measured distance
		timeLoopDelay = millis();
	}
}

void readUltrasonicSensors()
{
	// ultrasonic 2
	digitalWrite(ultrasonic2TrigPin, HIGH);
	delayMicroseconds(10);		// Must keep pin high for at least 10us
	digitalWrite(ultrasonic2TrigPin, LOW);

	ultrasonic2Duration = pulseIn(ultrasonic2EchoPin, HIGH);
	ultrasonic2Distance = (ultrasonic2Duration/2)/29;
}

void debugOutput()
{
	if ((millis() - timeSerialDelay) > serialPeriod)
	{
		Serial.print(“ultrasonic2Distance: “);
		Serial.print(ultrasonic2Distance);
		Serial.print(“cm: “);
		Serial.println();

		timeSerialDelay = millis()
	}
}

This code just sends pings out and returns the distance, giving distance value. It doesn’t make the robot move according to what it “sees.” That comes later.

Programming the movement according to the results from the Supersonic sensor

Now that the supersonic code had been completed, I could move on to creating the final version, the version to end all versions.

Okay, back to the programming. I’m not going to type all of the code above again, so when it’s there, but not being added for this section, you will see these: …

Here’s the final code. If you have any questions pop them down in the comment section.

#include 

// create servo objects
Servo leftMotor;
Servo rightMotor;

		// define the states
		#define DRIVE_FORWARD	0
		#define TURN_LEFT		1
		int state = DRIVE_FORWARD	// 0 = drive forward (DEFAULT), 1 = turn left

…

void setup()
{
	…
	leftMotor.attach(12);
	rightMotor.attach(13);
}

…

void stateMachine()
{
if(state == DRIVE_FORWARD)	// no obstacles detected
{
 if(ultrasonic2Distance > 6 || ultrasonic2Distance < 0) // if there's nothing in front of us (note: ultrasonicDistance will be negative for some ultrasonics if there's nothing in range)
        {
            // drive forward
            rightMotor.write(180);
            leftMotor.write(0);
        }
        else // there's an object in front of us
        {
            state = TURN_LEFT;
        }
    }
    else if(state == TURN_LEFT) // obstacle detected -- turn left
    {
        unsigned long timeToTurnLeft = 1100; // it takes around 1.1 seconds to turn 90 degrees
        
        unsigned long turnStartTime = millis(); // save the time that we started turning

        while((millis()-turnStartTime) < timeToTurnLeft) // stay in this loop until timeToTurnLeft (1.1 seconds) has elapsed
        {
            // turn left
            rightMotor.write(180);
            leftMotor.write(180);
        }
        
        state = DRIVE_FORWARD;
    }
} 

Finally! The code was done. I uploaded it to my Arduino and Voila! I had a robot that drove around and turned away when it saw something in its path. This completed what I did in day 2, which I see as the best day. Here’s a video of the robot working, by Nathan House on Foxytronics.

Advertisements
Tagged ,

Tell us what you thought!

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: