My first Arduino based bot :)

Here is my first Arduino based bot - I still have a large to do list with it, but wanted to share it now as it just completed its first run since building it.

Here is a short youtube vid I did today. :slight_smile:

About the bot:

Chassis
I hand made the chassis out of a single piece of 11x14 lucite.

System
Controlled by the Arduino board.

Drive
Two modified futaba servos
I built the motor driver circuit using some 74HC245N chips

Wheels
Foamy airplane tires modified to work with futaba servo splines
front caster - cheap, but want to replace

Eyes
Ping sensor
Standard (unmodified) servo

Logic
During forward drive, the bot is continually scanning. If it detects something within approximately 1 foot:
Stop (brakes)
Scan 3 positions
left
right
center
Determine closest object
turn away from closest object
resume forward movement
if object center is closest, or all sides are close to the same distance
backup
rescan objects

I have had quite a bit of fun building this so far! The bot as it sits in this vid literally has its electronics placed between the bottom and top levels and hanging out all over the place, nothing is anchored yet. Also, the wiring is a mess, and the bot is dirty - but it is just the first test run, definately not planning on leaving as it is! :wink:

;D

-B94Cast

Cool vid, is it possible to use the ping sensor to plot a straight line, rather than zagging from point to point?

I guess it might need to plot the distance of 360 points, and then draw a straight line to the furtherest point. Then once it reached a short distance from that point, do the calculation all over again.

Im not a bot person so I don't know if its doo'able. It would be cool to see a bot doing a course at high speed, like R2D toa on steroids lol

Thanks! I was excited to see it on its first trip around :smiley:

I would think that it is quite possible, but also more than likely out of scope of my current programming abilities - especially considered the smaller space that is available. :slight_smile: I am sure there are gurus out there that could give me ideas off of how to work that logic out in an efficient way. Right now, in the three locations I scan after object detection, I do what feels like a fairly clumsy compare on values to determine which direction is best to go.

R2D on steroids - lol - :wink: I think that was my test bot I built with the arduino on a RC10 that I have... it didnt succeed going around things quite as well as running into them at 30mph! ;D

I have the electronics somewhat tidily installed now, and have updated the routines quite a bit. I still have more to do with the electronics, adding LED's and some other stuff (new drive system incoming! :smiley: ) but at least the bots parts are not dragging all over anymore. :wink:

Thanks tons to "mem" for a considerable bit of help today on a comparison value issue I was crunching up against! With what I learned from that today, I will be updating the software over the next week to do multi-directional scans (instead of just three that I do now - left, right, and center). This should help quite a bit to make the bot movements more natural.

Since the first post above, I have added scanning while in movement, created alert and actively scanning sounds (that was fun!) and speaker to play them, and have been working on building some motor mounts for the new drive units I will be using next.

Some pictures

And the new motors - I got these with switches, which I will implement in the next week for a basic location reckoning system, and to detect if the bot is stuck on/against something :slight_smile:

and my home made steel motormounts - im not a skilled metalworker for sure - but still took a good amount of time to make... not pretty, but they do the job :wink:

Looks great! Any chance of an updated video?

Thank you! :slight_smile:
And yes, I will try and get a new video done up today.

code please?

I installed the new drive system, wanting to use that in the next video I posted, but I was not satisfied with it. here are some pics of that:

While the new drive system worked fine, as you can see it extended the wheels out considerably far out. This made the navigation much harder, as I solely (at least currently) rely upon the ultrasound "eyes" at the top of the bot. So for now, its back to the original drive system... :-/

I updated my drive circuit a bit, and added some lighting along with some of the other updates I listed above for this pic, and following vid.

and the new vid :smiley:

and robotkid249, I am constantly updating my code, so dont want to post it just yet :slight_smile:

Thanks!

Would you mind posting the code? It seems sooo good! Please.

Looks very cool....

I like it. I am thinking about doing something alot like this. Keep it up!

Thanks :slight_smile:
And for those asking for code - I just dont want to post it just yet. The code is pretty ugly atm, and I want to get it more in shape (well as much as I can, im no expert) a bit more before I post it. I am also still changing/adding to it almost daily - so it has quite a bit of // remarked out code and the like.
Thanks for the interest - not blowing anyone off, just wanting to wait a bit :wink:

Hi,

I'm new here, and I've just seen your video. Love it...

Now if only it could drag the hoover along... ;D

Keep up the good work.

Thanks tankslappa :slight_smile:
And welcome! I am pretty new here myself, just got started with Arduino myself about 2 weeks ago. Its a great community here, and I have learned alot and had fun every step of the way so far! :smiley:

Looks pretty cool man. I would really suggest that you post your code, I felt the same way at one time about mine, however after posting it in its raw and unfinished state I received a lot of useful tips and in the end my rover became better than it was before. Either way you look at it you will probably receive criticisms about the code whether you post it before 'finishing' it or after. Besides, will it ever be completely finished? :wink:

LOL! Good point that! :wink:
Ok, will try and get it posted here in the next few - I am trying to get a basic 6x6 map working at the moment. I was reading about the wavefront algorithm, and am working on a derivative of that.
:slight_smile:

Ok,
So here is my code so far - rat nests and all :slight_smile:
I have bugs I am working out in this version but I dont think that I will ever be done with the code, and people have asked for it - so here it is.
Feel free to poke/prod/suggest/maim/give beer/whatever :wink:

part 1

#include <Servo.h>
Servo servo1;
#define spkr 9 // speaker + pin9 - digital
#define ultraSoundSignal 7 // Ultrasound signal pin - digital
#define ledPin 13 // LED connected to digital pin 13
#define motor1a 5 // motor1 pin5 - digital
#define motor1b 4 // motor1 pin4 - digital
#define motor2a 2 // motor2 pin2 - digital
#define motor2b 3 // motor2 pin3 - digital
#define eyeleds 8
//int count = 50;
int count = 0;
int count1 = 0;
//int count2 = 0;
int count3 = 50;
int count4 = 0;
boolean dir = true;
int servoval = 95;
int moveservo;
int val = 0;
int ultrasoundValue = 0;
int timecount = 0; // Echo counter
int obded = 0;
int usv1 = 0;

void setup()
{
servo1.attach(14); //analog pin 0 - eyes/sonar device
pinMode (ledPin, OUTPUT); // Sets the digital pin as output
pinMode (1, OUTPUT);
pinMode (motor1a, OUTPUT);
pinMode (motor2a, OUTPUT);
pinMode (motor1b, OUTPUT);
pinMode (motor2b, OUTPUT);
pinMode (spkr, OUTPUT);
pinMode (eyeleds, OUTPUT);
}

void loop()
{
timecount = 0;
val = 0;
digitalWrite(eyeleds, HIGH); //turn on eyeleds while in main loop
usv1 = getrange();
if (usv1 <=14) {
motorstop();
makesounds();
lookaround(0);
count4 = 0;
} //lookaround if somethings close
if (usv1 > 8) {
driveit(500, 9);
} //go exploring
count4++;
if (count4 >=10) {
count4 = 0;
lookaround(1);
} //no motorstop called to make realtime course changes?
}

void driveit (int cval, int dir) {
switch (dir) {

case 1: //left motor forward

digitalWrite(motor1a, HIGH);
digitalWrite(motor1b, LOW);
delay (cval);
motorstop();
break;

case 2: //left motor backward

digitalWrite(motor1a, LOW);
digitalWrite(motor1b, HIGH);
delay (cval);
motorstop();
break;

case 3: //right motor forward

digitalWrite(motor2a, HIGH);
digitalWrite(motor2b, LOW);
delay (cval);
motorstop();
break;

case 4: //right motor backward

digitalWrite(motor2a, LOW);
digitalWrite(motor2b, HIGH);
delay (cval);
motorstop();
break;

case 5: //both left and right forward - forward

digitalWrite(motor1a, HIGH);
digitalWrite(motor1b, LOW);

digitalWrite(motor2a, HIGH);
digitalWrite(motor2b, LOW);
delay (cval);
motorstop();
break;

case 6: //both left and right backward - back

digitalWrite(motor1a, LOW);
digitalWrite(motor1b, HIGH);
digitalWrite(motor2a, LOW);
digitalWrite(motor2b, HIGH);
delay (cval);
motorstop();
break;

case 7: //left forward right backward - rotate right

digitalWrite(motor1a, HIGH);
digitalWrite(motor1b, LOW);
digitalWrite(motor2a, LOW);
digitalWrite(motor2b, HIGH);
delay (cval);
motorstop();
break;

case 8: //left backward right forward - rotate left

digitalWrite(motor1a, LOW);
digitalWrite(motor1b, HIGH);
digitalWrite(motor2a, HIGH);
digitalWrite(motor2b, LOW);
delay (cval);
motorstop();
break;

case 9: //set forward with no time, wait for sonar to brake

digitalWrite(motor1a, HIGH);
digitalWrite(motor1b, LOW);
digitalWrite(motor2a, HIGH);
digitalWrite(motor2b, LOW);

default:

break;
}
}

void motorstop () { //reset all outputs as well as put the motors in "brake" mode :slight_smile: Which technically invalidates
//all of the "low" state declarations in the driveit()routines
digitalWrite(motor1a, LOW);
digitalWrite(motor1b, LOW);
digitalWrite(motor2a, LOW);
digitalWrite(motor2b, LOW);
}

part 2

int getrange()
{
timecount = 0;
val = 0;
pinMode(ultraSoundSignal, OUTPUT); // Switch signalpin to output

/* Send low-high-low pulse to activate the trigger pulse of the sensor


*/

digitalWrite(ultraSoundSignal, LOW); // Send low pulse
delayMicroseconds(2); // Wait for 2 microseconds
digitalWrite(ultraSoundSignal, HIGH); // Send high pulse
delayMicroseconds(5); // Wait for 5 microseconds
digitalWrite(ultraSoundSignal, LOW); // Holdoff

/* Listening for echo pulse


*/

pinMode(ultraSoundSignal, INPUT); // Switch signalpin to input
val = digitalRead(ultraSoundSignal); // Append signal value to val
while(val == LOW) { // Loop until pin reads a high value
val = digitalRead(ultraSoundSignal);
}

while(val == HIGH) { // Loop until pin reads a high value
val = digitalRead(ultraSoundSignal);
timecount = timecount +1; // Count echo pulse time
}
ultrasoundValue = timecount; // Append echo pulse time to ultrasoundValue
ultrasoundValue = (ultrasoundValue / 30); //rough conversion to inches
if(timecount > 0){
digitalWrite(ledPin, HIGH);
}
delay(100);
return ultrasoundValue;
}

void lookaround(int inmotion) {
int dist_left = 0;
int dist_right = 0;
int dist_center = 0;
while (count < 1900) {
servo1.write(25); //move eyes servo left
Servo::refresh();
count++;
//look left
}
//measure distance here, store in dist_left var

dist_left = getrange();

if (dist_left <=14) {
if (inmotion = 1){
driveit(500, 8); //rotate left 1
}
else motorstop();
makesounds();
}
count = 0;

if (inmotion =1) { //look center during sweep if inmotion
while (count < 1900) {
servo1.write(90); //move eyes servo center
Servo::refresh();
count++;
//look center
}
//measure distance here, store in dist_center var

dist_center = getrange();

if (dist_center <=14) {
if (inmotion = 1){
driveit(500, 6); //go back
}
else motorstop();
makesounds();
}
count = 0;
}

while (count < 1900) {
servo1.write(135); //move eyes servo right
Servo::refresh();
count++;
//look right
}
//measure distance here, store in dist_right var

dist_right = getrange();

if (dist_right <=14) {
if (inmotion = 1){
driveit(500, 7); //rotate right 1
}
else motorstop();
makesounds();
}

count = 0;
while (count < 1900) {
servo1.write(90);
Servo::refresh();
count++;
//look center
}
//measure distance here, store in dist_center var

dist_center = getrange();

if (dist_center <=14) {
if (inmotion = 1){
driveit(500, 6); //go back
}
else motorstop();
makesounds();
}

//analyze ranges
if (dist_left < dist_right) {
if (dist_left < dist_center) {
driveit(500, 8); //rotate left 1/8
}
}
if (dist_right < dist_left) {
if (dist_right < dist_center) {
driveit(500, 7); //rotate right 1/8
}
}
if (dist_center < dist_right) {
if (dist_center < dist_left) {
if (dist_left < dist_right) {
driveit(500, 8); //rotate left 1/2
}
else driveit (1000,7); //rotate right 1/2
}

count = 0;
}

void makesounds(){
count1 = 0;
count3 = 50;
for (count1 = 1; count1 <=45; count1++) {
if (count3 <=7) {
dir = false;
}
if (dir) count3 = count3 - 77;
else {
count3 = count3 + 77;
if (count3 >= 777) dir = true;
count1++;
}

digitalWrite(spkr,HIGH);
delayMicroseconds(count3);

digitalWrite(spkr,LOW);
delayMicroseconds(count3);

digitalWrite(spkr,HIGH);
delayMicroseconds(7777);

digitalWrite(spkr,LOW);
delayMicroseconds(count3);

digitalWrite(spkr,HIGH);
delayMicroseconds(77);

digitalWrite(spkr,LOW);
delayMicroseconds(count3);
}
}

[/quote]