So I have made another robot. It is a cheap small simple robot, most of the parts were bought on Ebay. Ebay has become my primary source for robot parts. So much stuff these days is made in China. And Ebay is a great place to buy it.
For the chassis I used a plastic box I had lying around.
I bought 2 of the cheapest geared motors with wheels on Ebay. You can easily find them on Ebay when you search for “robot motor”. These are DC motors with small gears to reduce the speed. The motors come without wires, so I soldered some wires to the terminals. These motors draw very little current so you don’t need to use thick wire.
I then stuck the motors to the chassis with some double sided tape.
I bought a small castor wheel on Ebay and used the same method to attach it to the chassis. By using a castor wheel the robot can almost turn around it’s own radius, which has its benefits.
To control the motors I chose to make my own motor controller based on the L293D h-bridge and a couple of transistors and resistors. There are different ways to control a L293D chip from a micro controller. By using 2 transistors I only need 4 pins on the Arduino to control the 2 motors. Each motor is controlled by 2 pins, one is a pwm pin to control the speed of the motor. The other pin controls the direction of the motor by turning it low or high. I soldered all the parts on some perfboard. The L293D chip can be found cheaply on Ebay.
I drew the following schematic in Eagle:
To detect obstacles I used an ultrasonic SR04 sensor. These sensors only cost a couple of dollars on Ebay. This sensor is well supported by Arduino, several people have written libraries for the SR04 sensor. I wanted to be able to sweep the sensor so I mounted it on a small SG90 servo. Want to guess where I bought it from? Ebay of course 🙂 I did use a part that didn’t come from Ebay. I recently bought some things from Rocket brand studios and ordered a couple of sensor brackets. These brackets are laser cut from acrylic. They are made to mount a SR04 sensor on a small servo. I then attached the servo and sensor to the chassis with some more double sided tape.
For the micro controller I used an ATmega328P-PU with Arduino bootloader. I used one of my own PCB’s, my Bajduino 3A. The board has a 3A 5V regulator and lots of male pins so I could easily hook up the sensor and servo and L293D board to the micro controller pins. I used a 2S Lipo battery to power the robot. A 2S Lipo gives about 8.4V when fully charged, this is a bit to much for the small dc motors. So I used the 5V from my Bajduino 3A to power the motors. My Bajduino 3A can give 3 amps, more then enough for the motors. This is not recommended though as motors can give voltage spikes and possibly damage your micro controller. But with these small motors it works well.
I soldered some leds with current limiting resistors to a piece of perfboard and stuck it on the back of the sensor bracket. This is a handy way to see what is going on in the micro controller. For every direction, forward/backward/left/right a led lights up. I hooked everything up with some Dupont cable.
This is the result:
Obstacle avoiding robot
I spent quite a bit of time writing code for this little robot. Most obstacle avoiding Arduino sketches I have seen use lots of delays in the code. When the robot detects an obstacle in its path it stops and lets the servo look left and right to determine which way it should go. Between every step there is a delay in the code. I wanted to write a sketch without any delays so it would be faster and smoother. The code uses lots of timers based on the millis function. The servo sweeps all the time and the values of the SR04 ultrasonic sensor are constantly taken. So the moment the robot detects an obstacle it immediately knows which way it should turn. It took me many hours to get right. But it seems to work pretty well.
Here is a video:
This is the code I used:
/* http://www.bajdi.com (your number one source for buggy Arduino sketches) Simple obstacle avoiding robot made from parts mostly sourced from Ebay Micro controller = ATmega328P-PU with Arduino bootloader (3.5$ @ Eb.. noooo Tayda Electronics) Using a L293D (bought from my favourite Ebay seller Polida) to drive 2 yellow "Ebay motors with yellow wheels" Detecting obstacles with an SR04 ultrasonic sensor (uber cheap on Ebay) SR04 sensor mounted on SG90 servo (you can get these servo very cheap on ... oh yes you guessed it: EBay) */ #include <NewPing.h> //library for the SR04 ultrasonic sensor #include <Servo.h> //servo library, SR04 is mounted on this servo Servo myservo; #define TRIGGER_PIN A1 //using analog pins as digital for SR04 sensor #define ECHO_PIN A0 //because I just happened to plug them in here #define MAX_DISTANCE 200 //the sensor can't measure much further then this distance NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); #define runEvery(t) for (static typeof(t) _lasttime;(typeof(t))((typeof(t))millis() - _lasttime) > (t);_lasttime += (t)) const int EN1 = 6; //enable motor 1 = pin 1 of L293D const int direction1 = 7; //direcion motor 1 = pin 2 of L293D const int EN2 = 5; //enable motor 2 = pin 9 of L293D const int direction2 = 4; //direction motor 2 = pin 15 of L293D // leds are very handy for testing const int redLed = 10; // this led will lit up when the robot drives forward const int greenLed = 11; // this led will lit up when the robot drives backward const int yellowLed = 12; // this led will lit up when the robot turns left const int whiteLed = 13; // this led will lit up when the robot turns right int uS; //value of SR04 ultrasonic sensor int distance; //distance in cm of ultrasonic sensor int pos = 90; //start position of servo = 90 int servoDirection = 0; // sweeping left or right int robotDirection = 0; //0 = forward, 1 = backward, 2 = left, 3 = right int lastRobotDirection; //last direction of the robot int distanceCenter; int distanceLeft; int distanceRight; int servoDelay = 20; //with this parameter you can change the sweep speed of the servo const int speedLeft = 205; //there seems to be a bit of a difference between these cheap motors :( const int speedRight = 255; //this motor needs a bit more voltage to keep up with the other long previousMillis = 0; const int interval = 650; //interval to switch between the robotDirection, this value will determine //how long the robot will turn left/right when it detects an obstacle void setup() { pinMode(EN1, OUTPUT); pinMode(direction1, OUTPUT); pinMode(EN2, OUTPUT); pinMode(direction2, OUTPUT); analogWrite(EN1, 0); analogWrite(EN2, 0); pinMode(redLed, OUTPUT); pinMode(greenLed, OUTPUT); pinMode(yellowLed, OUTPUT); pinMode(whiteLed, OUTPUT); Serial.begin(9600); //to use the serial monitor myservo.attach(8); //servo on pin 8 myservo.write(pos); //center servo delay(1500); // delay so we have some time to put the robot on the floor } void loop() { sweepServo(); //function to sweep the servo getDistance(); //function to get the distance from the ultrasonic sensor if (pos >= 15 && pos <= 45) { distanceRight = distance; //servo is to the right so measured distance = distanceRight } if (pos >= 135 && pos <= 165) { distanceLeft = distance; //servo is to the left so measured distance = distanceLeft } if (pos > 70 && pos < 110) { distanceCenter = distance; //servo is centred so measured distance = distanceCenter } if (distanceCenter >= 25) // coast is clear, full power forward { robotDirection = 0; //move forward } else //obstacle detected, turn left or right? { if (distanceLeft > distanceRight) { robotDirection = 2; //turn left } if (distanceLeft < distanceRight) { robotDirection = 3; //turn right } if (distanceLeft <= 5 && distanceCenter <= 5 || distanceRight <= 5 && distanceCenter <= 5) { robotDirection = 1; // we are stuck, lets try and backup } } unsigned long currentMillis = millis(); //set a timer if(robotDirection == 0 && robotDirection == lastRobotDirection) { forward(); lastRobotDirection = robotDirection; } if(robotDirection == 0 && robotDirection != lastRobotDirection && currentMillis - previousMillis > interval ) { forward(); lastRobotDirection = robotDirection; previousMillis = currentMillis; } if(robotDirection == 1 && robotDirection == lastRobotDirection) { backward(); lastRobotDirection = robotDirection; } if(robotDirection == 1 && robotDirection != lastRobotDirection && currentMillis - previousMillis > interval ) { backward(); lastRobotDirection = robotDirection; previousMillis = currentMillis; } if(robotDirection == 2 && robotDirection == lastRobotDirection) { left(); lastRobotDirection = robotDirection; } if(robotDirection == 2 && robotDirection != lastRobotDirection && currentMillis - previousMillis > interval ) { left(); lastRobotDirection = robotDirection; previousMillis = currentMillis; } if(robotDirection == 3 && robotDirection == lastRobotDirection) { right(); lastRobotDirection = robotDirection; } if(robotDirection == 3 && robotDirection != lastRobotDirection && currentMillis - previousMillis > interval ) { right(); lastRobotDirection = robotDirection; previousMillis = currentMillis; } } void forward() { digitalWrite(direction1, HIGH); digitalWrite(direction2, HIGH); analogWrite(EN1, speedLeft); analogWrite(EN2, speedRight); digitalWrite(redLed, HIGH); digitalWrite(greenLed, LOW); digitalWrite(yellowLed, LOW); digitalWrite(whiteLed, LOW); } void stop() { digitalWrite(direction1, LOW); digitalWrite(direction2, LOW); analogWrite(EN1, 0); analogWrite(EN2, 0); digitalWrite(redLed, LOW); digitalWrite(greenLed, LOW); digitalWrite(yellowLed, LOW); digitalWrite(whiteLed, LOW); } void backward() { digitalWrite(direction1, LOW); digitalWrite(direction2, LOW); analogWrite(EN1, speedLeft+35); analogWrite(EN2, speedRight-15); digitalWrite(redLed, LOW); digitalWrite(greenLed, HIGH); digitalWrite(yellowLed, LOW); digitalWrite(whiteLed, LOW); } void left() { digitalWrite(direction1, LOW); digitalWrite(direction2, HIGH); analogWrite(EN1, speedLeft+35); analogWrite(EN2, speedRight); digitalWrite(redLed, LOW); digitalWrite(greenLed, LOW); digitalWrite(yellowLed, HIGH); digitalWrite(whiteLed, LOW); } void right() { digitalWrite(direction1, HIGH); digitalWrite(direction2, LOW); analogWrite(EN1, speedLeft); analogWrite(EN2, speedRight-30); digitalWrite(redLed, LOW); digitalWrite(greenLed, LOW); digitalWrite(yellowLed, LOW); digitalWrite(whiteLed, HIGH); } void getDistance() { runEvery(40) //loop for ultrasonic measurement { uS = sonar.ping(); distance = uS / US_ROUNDTRIP_CM; if (uS == NO_ECHO) // if the sensor did not get a ping { distance = MAX_DISTANCE; //so the distance must be bigger then the max vaulue of the sensor } Serial.print("Ping: "); //to check distance on the serial monitor Serial.print(distance); Serial.println("cm"); } } void sweepServo() { runEvery(servoDelay) //this loop determines the servo position { if(pos < 165 && servoDirection == 0) // 165 = servo to the left { pos = pos + 5; // +1 was to slow } if(pos > 15 && servoDirection == 1) // 15 = servo to the right { pos = pos - 5; } } if (pos == 165 ) { servoDirection = 1; //changes the direction } if (pos == 15 ) { servoDirection = 0; //changes the direction } myservo.write(pos); //move that servo! }
Comments on my code are very welcome, I’m always willing to learn 🙂
I was hoping you could tell me the resistor values on the L293 schematic? i would really appreciate it! big fan of your site! Thanks!
Oops forgot those 🙂 R1 and R2 are 1K and R3 and R4 10K.
one more question. I was just wondering what the input voltage was needed to power the motors. Also do i need to make my own 5v supply for the driver, or do i use the power off the arduino? so basically, do i need a power supply for the motor, the IC, and the arduino. thats 3 power supplies. Also i really want your bajduino!!!!!! how much man!!! you should put them up for sale on your site with directions on how to use them to make your robots. I think you would make a few bucks on it. anyways. Hope to hear from you soon. Names Kyle. THanks
Well I first tried running the motors of a 2S Lipo (8.4V fully charged) but the motors didn’t like that. So I powered them of the Bajduino (5V). That worked a lot better. My Bajduino has a 3A regulator so it’s powerful enough. A standard Arduino has a tiny voltage regulator and would just overheat.
You can feed the 5V logic of the L293D from the Arduino, that’s no problem. But for the motors you need some more power. An easy solution is to run your Arduino from a seperate battery (9V) and feed power to the L293D from rechargeable AA batteries (5-6V or so). You must have a common ground between the Arduino and the L293D, else it won’t work.
awesome thanks for the help. I finished the bot last night. Working pretty good. Now i need to figure out a new project. AHHHH
I followed your instructions and the hardware is working fine, but the wheels keep rotating in opposite directions that is the robot keeps spinning. is there a problem in my wiring or the code?
Try switching the wires of the motor that spins in the wrong direction…
I copy pasted the sketch, but it does not compile, shows errors.
Can you please send a detailed schematic too.
Many many thanks.
BOSE
Detailed schematic of what? I posted the schematic of the motor controller. You only need to connect the motor controller and ultrasonic sensor. The pins are defined in the beginning of the sketch. Sketch should compile fine in the Arduino IDE, you must of course have the newping library installed.
can u please tell me the price of srO4 SENSOR at which u buyed?
I bought 10 SR04 sensors on Ebay for 12€: http://www.bajdi.com/?attachment_id=857
[…] little Ebay bot is powered by 2 cheap DC geared motors. These yellow geared DC motors are very popular. Lots of […]
I noticed you aren’t using pin 7 and 10 on the l239D at all. I was under the impression that these were used for controlling the speed. And that the enable pins (1, 9) indicate whether a motor is being used on that side of the chip, and 5V should be fed into those pins if there are motors there. Am i not understanding something?
Thanks
Pin 7 and 10 are used. The circuit with the transistor will either switch pin 2 or pin 7 high for motor 1. Depending on the output of the micro controller pin. That way you only need one pin on the micro controller to control the direction of the motor. And 1 pin to control the speed of the motor (by pwm’ing the enable pin).
two questions
firstly what is the use of that transistor you are using
secondly could you please include a link to a sketch that uses delays because i want to compare these two and i cant seem to find one
thanks alot
nice project BTW
By using the transistor I only need one output of the micro controller per motor to set the direction, else you would need 2. I don’t have a sketch that uses delays…
in verifying your code i got the error>>”NewPing does not name a type”
Have you installed the NewPing library? And installed it in the right place?
now i install it and problem solved. But what are the purposes for using transistor and resistors??if i avoided it what will occur??
Sorry i didn’t read your previous comment. You already describe their purposes>>:p
Still confusing with the operation of transistor>>would u plz explain more about transistor??
What is the meaning of this line of code
“#define runEvery(t) for (static typeof(t) _lasttime;(typeof(t))((typeof(t))millis() – _lasttime) > (t);_lasttime += (t))
“???
Take a look at this: http://forum.arduino.cc/index.php/topic,124974.0.html
i made this with arduino uno. i saw your video. But the problem is, your and my robot is going in right(slightly)not is straight. Should i edit/add code to solve this???
Take a look at this: http://www.bajdi.com/adding-encoders-to-those-cheap-yellow-motors/
But the speed of both motor are same in my project. so what value should i write here>>>
const int speedLeft = 200; //speed of left motor
const int speedRight = 200; //speed of right motor
Abdullah please tell me the circuit connection of sensors and ic293 with aruino uno kit.
im trying out your code and im having compiling errors with line 220
NO_ECHO was not declared in this scope.
im using Arduino ide 1.0.5 with atmega8 board.
any advice?
I think the newping library doesn’t work with the ATmega8…
ok thanks for the reply.another question, what is the purpose of these lines:
uS = sonar.ping();
distance = uS / US_ROUNDTRIP_CM;
if (uS == NO_ECHO) // if the sensor did not get a ping
{
distance = MAX_DISTANCE; //so the distance must be bigger then the max vaulue of the sensor
}
Serial.print(“Ping: “); //to check distance on the serial monitor
Serial.print(distance);
Serial.println(“cm”);
Have you read the newping library documentation? http://playground.arduino.cc/Code/NewPing
I found your code to be the closest thing to work with the 4pin SR04 and still be understandable.
I have borrowed your code and added some modularizations for the motorshield I am using plus its libraries. I have the sweeping SR04 working and reporting distances and hope to have the body rolling tomorrow with everything working.
#Chrissybot3000
Hye, good tutorial! Is the coding available to be used at arduino uno?
The above code will work with any Arduino that has an ATmega328 micro controller.
Owh I see, I’ve already compile the programming. But my motor doesn’t move. I’m using 6V battery for motor’s power. Is there anything wrong here?
Sorry I don’t have a crystal ball.
Sir i am so interested to build this project. Can I have the wiring diagram of arduino to sensor and to motor driver. A million thanks sir
Read my above comment …
Hey can u show backside connection diagram of arduino board
I’m not using an Arduino board.
[…] Περισσότερες πληροφορίες:Obstacle avoiding robot […]
Great job here. I see that others have been able to make this code work, I am facing some issues.
The robot starts moving forward for a few seconds on power up and then stops. The motors only respond when an obstacle is detected after this. I have checked all my connections. Any guesses why this might be happening?
i can’t understand about servo where it is connected in motor driver. so please can you help me
Uh, servo’s don’t use motor drivers …
Great tutorial.I built it.But the problem is that the sensor does not sense ,the motors move only forward but the servo works accorgingly.Any idea why.Thanks for your help.
Sorry I don’t have a crystal ball.
then where is servo connected.
Look up some tutorials on how to connect a servo to an Arduino. There are 100’s on the internet.
My robot is working now.The problem was the HC-SR04 ultrasonic.I ordered 10 of them and all do not work.Thanks for your time. Great tutorial.
[…] Simple Obstacle Avoiding Robot Arduino: The obstacle avoiding robot can be designed by using Arduino and distance sensors. By using this project, we design a robot which senses the obstacles in its way and it avoids automatically. […]
[…] Simple Obstacle Avoiding Robot Arduino: The obstacle avoiding robot can be designed by using Arduino and distance sensors. By using this project, we design a robot which senses the obstacles in its way and it avoids automatically. […]
[…] Simple Obstacle Avoiding Robot Arduino: The obstacle avoiding robot can be designed by using Arduino and distance sensors. By using this project, we design a robot which senses the obstacles in its way and it avoids automatically. […]
[…] Simple Obstacle Avoiding Robot Arduino: The obstacle avoiding robot can be designed by using Arduino and distance sensors. By using this project, we design a robot which senses the obstacles in its way and it avoids automatically. […]