Hi everyone
i am trying to learn more about robotics, so i decide to make a simple robot 2 DC motor with H bridge controller and one Ultrasonic sensor if that work i will add for advance a servo motor to make it see all over around.
my problem is i don't found any code with dc motor all people used servo motor because its more easy to program it
actually i don't know from where i will start,
i search on a code and i found this
Code for Obstacle Avoidance Arduino Robot
#include <Servo.h>
//Declare Servos
Servo leftservo; //Left wheel servo
Servo rightservo; //Right wheel servo
Servo scanservo; //Ping Sensor Servo
const int turntime = 500; //Number of milliseconds to turn when turning
const int pingPin = 7; //Pin that the Ping sensor is attached to.
const int leftservopin = 9; //Pin number for left servo
const int rightservopin = 10; // Pin number for right servo
const int scanservopin = 6; // Pin number for scan servo
const int distancelimit = 10; //If something gets this many inched from
// the robot it stops and looks for where to go.
//Setup function. Runs once when Arduino is turned on or restarted
void setup()
{
leftservo.attach(leftservopin); //Attach left servo to its pin.
rightservo.attach(rightservopin); // Attch the right servo
scanservo.attach(scanservopin); // Attach the scan servo
delay(2000); // wait two seconds
}
void loop(){
go(); // if nothing is wrong the go forward using go() function below.
int distance = ping(); // us the ping() function to see if anything is ahead.
if (distance < distancelimit){
stopmotors(); // If something is ahead, stop the motors.
char turndirection = scan(); //Decide which direction to turn.
switch (turndirection){
case 'l':
turnleft(turntime);
break;
case 'r':
turnright(turntime);
break;
case 's':
turnleft(turnaroundtime);
break;
}
}
}
int ping(){
long duration, inches, cm;
//Send Pulse
pinMode(pingPin, OUTPUT);
digitalWrite(pingPin, LOW);
delayMicroseconds(2);
digitalWrite(pingPin, HIGH);
delayMicroseconds(5);
digitalWrite(pingPin, LOW);
//Read Echo
pinMode(pingPin, INPUT);
duration = pulseIn(pingPin, HIGH);
// convert the time into a distance
inches = microsecondsToInches(duration);
cm = microsecondsToCentimeters(duration);
Serial.print("Ping: ");
Serial.println(inches);
return round(inches);
}
void go(){
leftservo.write(30);
rightservo.write(150);
}
void turnleft(int t){
leftservo.write(150);
rightservo.write(150);
delay(t);
}
void turnright(int t){
leftservo.write(30);
rightservo.write(30);
delay(t);
}
void forward(int t){
leftservo.write(30);
rightservo.write(150);
delay(t);
}
void backward(int t){
leftservo.write(150);
rightservo.write(30);
delay(t);
}
void stopmotors(){
leftservo.write(90);
rightservo.write(90);
}
char scan(){
int leftscanval, centerscanval, rightscanval;
char choice;
//Look left
scanservo.write(30);
delay(300);
leftscanval = ping();
//Look right
scanservo.write(150);
delay(1000);
rightscanval = ping();
//center scan servo
scanservo.write(88);
if (leftscanval>rightscanval && leftscanval>centerscanval){
choice = 'l';
}
else if (rightscanval>leftscanval && rightscanval>centerscanval){
choice = 'r';
}
else{
choice = 's';
}
Serial.print("Choice: ");
Serial.println(choice);
return choice;
}
long microsecondsToInches(long microseconds){
return microseconds / 74 / 2;
}
long microsecondsToCentimeters(long microseconds){
return microseconds / 29 / 2;
}
Published by Google Drive–Report Abuse–Updated automatically every 5 minutes
i think if i change things it will work great, but i need more information about H bridge if someone can enplane this to me i will be very happy
that was amazing, ok i have a different H bride but at least i know now how that work,
i test the both DC motor with this code and everything work great
so my next step is to add ultrasonic sensor,
anybody have a simple code so i can use it to my robot,
i search on google and all what i found is different than this bridge, all of them connect the ultrasonic to the bridge pins
in my case there is no pins on the H bridge
298N Dual H-Bridge Motor Controller
narzan:
all of them connect the ultrasonic to the bridge pins
No, none of them will connect the sensor to the h-bridge, that would be crazy. I'd like to see a schematic for that- I think you must be mis-understanding.
You read the distance from the sensor, then decide to carry on forward, or stop, or turn, or reverse, then send the appropriate instruction to the h-bridge.
There's plenty of code around for ultrasonic sensors.
The circuit that you posted a link to shows a motor drive shield on which some of the Arduino pins (A4 and A5) are made available and it is these (and 5v and GND) that the ultrasonic sensor is connected to, not the H bridge itself.
i connect everything and my robot just turn right =( all the time
i used this code and i know i must change things to make it work i found this code on the internet he used a different motor controller
and this is my code
#include <AFMotor.h>
#include <Servo.h>
#include <NewPing.h>
#define TRIG_PIN A4 // Pin A4 on the Motor Drive Shield soldered to the ultrasonic sensor
#define ECHO_PIN A5 // Pin A5 on the Motor Drive Shield soldered to the ultrasonic sensor
#define MAX_DISTANCE 200 // sets maximum useable sensor measuring distance to 200cm
#define MAX_SPEED 180 // sets speed of DC traction motors to 180/256 or about 70% of full speed - to get power drain down.
#define MAX_SPEED_OFFSET 10 // this sets offset to allow for differences between the two DC traction motors
#define COLL_DIST 10 // sets distance at which robot stops and reverses to 10cm
#define TURN_DIST COLL_DIST+10 // sets distance at which robot veers away from object (not reverse) to 20cm (10+10)
NewPing sonar(TRIG_PIN, ECHO_PIN, MAX_DISTANCE); // sets up sensor library to use the correct pins to measure distance.
AF_DCMotor motor1(1, MOTOR12_1KHZ); // create motor #1 using M1 output on Motor Drive Shield, set to 1kHz PWM frequency
AF_DCMotor motor2(4, MOTOR12_1KHZ); // create motor #2, using M2 output, set to 1kHz PWM frequency
Servo myservo; // create servo object to control a servo
int pos = 0; // this sets up variables for use in the sketch (code)
int maxDist = 0;
int maxAngle = 0;
int maxRight = 0;
int maxLeft = 0;
int maxFront = 0;
int course = 0;
int curDist = 0;
String motorSet = "";
int speedSet = 0;
//-- SETUP LOOP --
void setup() {
myservo.attach(9); // attaches the servo on pin 9 (SERVO_2 on the Motor Drive Shield to the servo object
myservo.write(90); // tells the servo to position at 90-degrees ie. facing forward.
delay(2000); // delay for two seconds
checkPath(); // run the CheckPath routine to find the best path to begin travel
motorSet = "FORWARD"; // set the director indicator variable to FORWARD
myservo.write(90); // make sure servo is still facing forward
moveForward(); // run function to make robot move forward
}
//----
//--MAIN LOOP --
void loop() {
checkForward(); // check that if the robot is supposed to be moving forward, that the drive motors are set to move forward - this is needed to overcome some issues with only using 4 AA NiMH batteries
checkPath(); // set ultrasonic sensor to scan for any possible obstacles
}
//----
void checkPath() {
int curLeft = 0;
int curFront = 0;
int curRight = 0;
int curDist = 0;
myservo.write(144); // set servo to face left 54-degrees from forward
delay(120); // wait 120milliseconds for servo to reach position
for(pos = 144; pos >= 36; pos-=18) // loop to sweep the servo (& sensor) from 144-degrees left to 36-degrees right at 18-degree intervals.
{
myservo.write(pos); // tell servo to go to position in variable 'pos'
delay(90); // wait 90ms for servo to get to position
checkForward(); // check the robot is still moving forward
curDist = readPing(); // get the current distance to any object in front of sensor
if (curDist < COLL_DIST) { // if the current distance to object is less than the collision distance
checkCourse(); // run the checkCourse function
break; // jump out of this loop
}
if (curDist < TURN_DIST) { // if current distance is less than the turn distance
changePath(); // run the changePath function
}
if (curDist > curDist) {maxAngle = pos;}
if (pos > 90 && curDist > curLeft) { curLeft = curDist;}
if (pos == 90 && curDist > curFront) {curFront = curDist;}
if (pos < 90 && curDist > curRight) {curRight = curDist;}
}
maxLeft = curLeft;
maxRight = curRight;
maxFront = curFront;
}
//----
void setCourse() { // set direction for travel based on a very basic distance map, simply which direction has the greatest distance to and object - turning right or left?
if (maxAngle < 90) {turnRight();}
if (maxAngle > 90) {turnLeft();}
maxLeft = 0;
maxRight = 0;
maxFront = 0;
}
//----
void checkCourse() { // we're about to hit something so move backwards, stop, find where the empty path is.
moveBackward();
delay(500);
moveStop();
setCourse();
}
//----
void changePath() {
if (pos < 90) {veerLeft();} // if current pos of sensor is less than 90-degrees, it means the object is on the right hand side so veer left
if (pos > 90) {veerRight();} // if current pos of sensor is greater than 90-degrees, it means the object is on the left hand side so veer right
}
//----
int readPing() { // read the ultrasonic sensor distance
delay(70);
unsigned int uS = sonar.ping();
int cm = uS/US_ROUNDTRIP_CM;
return cm;
}
//----
void checkForward() { if (motorSet=="FORWARD") {motor1.run(FORWARD); motor2.run(FORWARD); } } // make sure motors are going forward
//----
void checkBackward() { if (motorSet=="BACKWARD") {motor1.run(BACKWARD); motor2.run(BACKWARD); } } // make sure motors are going backward
//----
// In some cases, the Motor Drive Shield may just stop if the supply voltage is too low (due to using only four NiMH AA cells).
// The above functions simply remind the Shield that if it's supposed to go forward, then make sure it is going forward and vice versa.
//----
void moveStop() {motor1.run(RELEASE); motor2.run(RELEASE);} // stop the motors.
//----
void moveForward() {
motorSet = "FORWARD";
motor1.run(FORWARD); // turn it on going forward
motor2.run(FORWARD); // turn it on going forward
for (speedSet = 0; speedSet < MAX_SPEED; speedSet +=2) // slowly bring the speed up to avoid loading down the batteries too quickly
{
motor1.setSpeed(speedSet+MAX_SPEED_OFFSET);
motor2.setSpeed(speedSet);
delay(5);
}
}
//----
void moveBackward() {
motorSet = "BACKWARD";
motor1.run(BACKWARD); // turn it on going forward
motor2.run(BACKWARD); // turn it on going forward
for (speedSet = 0; speedSet < MAX_SPEED; speedSet +=2) // slowly bring the speed up to avoid loading down the batteries too quickly
{
motor1.setSpeed(speedSet+MAX_SPEED_OFFSET);
motor2.setSpeed(speedSet);
delay(5);
}
}
//----
void turnRight() {
motorSet = "RIGHT";
motor1.run(FORWARD); // turn motor 1 forward
motor2.run(BACKWARD); // turn motor 2 backward
delay(400); // run motors this way for 400ms
motorSet = "FORWARD";
motor1.run(FORWARD); // set both motors back to forward
motor2.run(FORWARD);
}
//----
void turnLeft() {
motorSet = "LEFT";
motor1.run(BACKWARD); // turn motor 1 backward
motor2.run(FORWARD); // turn motor 2 forward
delay(400); // run motors this way for 400ms
motorSet = "FORWARD";
motor1.run(FORWARD); // turn it on going forward
motor2.run(FORWARD); // turn it on going forward
}
//----
void veerRight() {motor2.run(BACKWARD); delay(400); motor2.run(FORWARD);} // veering right? set right motor backwards for 400ms
//----
void veerLeft() {motor1.run(BACKWARD); delay(400); motor1.run(FORWARD);} // veering left? set left motor backwards for 400ms
//----
what i shuld change to make it work great with me ?
i am using
pin 5 for triger
pin 6 for eco
pin 8 for in4
pin 9 for in3
pin 10 for in2
pin 11 for in1
=(
ok i know that's hard, but at least lets make it an open source for everyone,
people used the easy way with servo motors, and Motors Shield,
by the way, there is no good code for smart robot on the internet,
i have a good experience and research on ultrasonic sensor HC-SR04 and if someone asked me i will be happy to give my experience,
the sad thing is always having the same answer, google it!! or make a deep search, sorry if i found something on the internet i wold not make a post here, thank you anyway for the fast replay
the sad thing is always having the same answer, google it!
I didn't say any such thing.
I said make what your sketch is doing more obvious.
Add debug code - find out exactly what your code is doing, don't try to infer what it is doing.
i didn't mean you
just wait and you will see others will say that XD
to be more clear, i found this code on a website, but he used other bridge, and to be honest i am trying to know more about robotics,
and this is my first project in using dc motors and H bridge,
i am sure the problem on this part but everytime i change something i have more problems, so a clean everything and i am start from begin again,
#include <AFMotor.h>
#include <Servo.h>
#include <NewPing.h>
#define TRIG_PIN A4 // Pin A4 on the Motor Drive Shield soldered to the ultrasonic sensor
#define ECHO_PIN A5 // Pin A5 on the Motor Drive Shield soldered to the ultrasonic sensor
#define MAX_DISTANCE 200 // sets maximum useable sensor measuring distance to 200cm
#define MAX_SPEED 180 // sets speed of DC traction motors to 180/256 or about 70% of full speed - to get power drain down.
#define MAX_SPEED_OFFSET 10 // this sets offset to allow for differences between the two DC traction motors
#define COLL_DIST 10 // sets distance at which robot stops and reverses to 10cm
#define TURN_DIST COLL_DIST+10 // sets distance at which robot veers away from object (not reverse) to 20cm (10+10)
NewPing sonar(TRIG_PIN, ECHO_PIN, MAX_DISTANCE); // sets up sensor library to use the correct pins to measure distance.
AF_DCMotor motor1(1, MOTOR12_1KHZ); // create motor #1 using M1 output on Motor Drive Shield, set to 1kHz PWM frequency
AF_DCMotor motor2(4, MOTOR12_1KHZ); // create motor #2, using M2 output, set to 1kHz PWM frequency
Servo myservo; // create servo object to control a servo
i am sure i have problems with pins
pin 5 for triger
pin 6 for eco
pin 8 for in4
pin 9 for in3
pin 10 for in2
pin 11 for in1
the code looks so weird for me!
thanks everyone i found the problem 8) and now everything work great
actually UKHeliBob your replay gives me a hint and that's work for me
A4 and A5 in that circuit is A1-A2
don't ask me why that's when you buy Chinese boards
Hi everyone
i finished my simple robot but i have a motor faster than other
if i use a Potentiometer is that will help?!
or i need to change the code ?!
i know this area not for coding but i will post the code if there is any question about it
#include <AFMotor.h>
#include <Servo.h>
#include <NewPing.h>
#define TRIG_PIN A4 // Pin A4 on the Motor Drive Shield soldered to the ultrasonic sensor
#define ECHO_PIN A5 // Pin A5 on the Motor Drive Shield soldered to the ultrasonic sensor
#define MAX_DISTANCE 200 // sets maximum useable sensor measuring distance to 200cm
#define MAX_SPEED 180 // sets speed of DC traction motors to 180/256 or about 70% of full speed - to get power drain down.
#define MAX_SPEED_OFFSET 10 // this sets offset to allow for differences between the two DC traction motors
#define COLL_DIST 10 // sets distance at which robot stops and reverses to 10cm
#define TURN_DIST COLL_DIST+10 // sets distance at which robot veers away from object (not reverse) to 20cm (10+10)
NewPing sonar(TRIG_PIN, ECHO_PIN, MAX_DISTANCE); // sets up sensor library to use the correct pins to measure distance.
AF_DCMotor motor1(1, MOTOR12_1KHZ); // create motor #1 using M1 output on Motor Drive Shield, set to 1kHz PWM frequency
AF_DCMotor motor2(4, MOTOR12_1KHZ); // create motor #2, using M2 output, set to 1kHz PWM frequency
Servo myservo; // create servo object to control a servo
int pos = 0; // this sets up variables for use in the sketch (code)
int maxDist = 0;
int maxAngle = 0;
int maxRight = 0;
int maxLeft = 0;
int maxFront = 0;
int course = 0;
int curDist = 0;
String motorSet = "";
int speedSet = 0;
//-- SETUP LOOP --
void setup() {
myservo.attach(9); // attaches the servo on pin 9 (SERVO_2 on the Motor Drive Shield to the servo object
myservo.write(90); // tells the servo to position at 90-degrees ie. facing forward.
delay(2000); // delay for two seconds
checkPath(); // run the CheckPath routine to find the best path to begin travel
motorSet = "FORWARD"; // set the director indicator variable to FORWARD
myservo.write(90); // make sure servo is still facing forward
moveForward(); // run function to make robot move forward
}
//----
//--MAIN LOOP --
void loop() {
checkForward(); // check that if the robot is supposed to be moving forward, that the drive motors are set to move forward - this is needed to overcome some issues with only using 4 AA NiMH batteries
checkPath(); // set ultrasonic sensor to scan for any possible obstacles
}
//----
void checkPath() {
int curLeft = 0;
int curFront = 0;
int curRight = 0;
int curDist = 0;
myservo.write(144); // set servo to face left 54-degrees from forward
delay(120); // wait 120milliseconds for servo to reach position
for(pos = 144; pos >= 36; pos-=18) // loop to sweep the servo (& sensor) from 144-degrees left to 36-degrees right at 18-degree intervals.
{
myservo.write(pos); // tell servo to go to position in variable 'pos'
delay(90); // wait 90ms for servo to get to position
checkForward(); // check the robot is still moving forward
curDist = readPing(); // get the current distance to any object in front of sensor
if (curDist < COLL_DIST) { // if the current distance to object is less than the collision distance
checkCourse(); // run the checkCourse function
break; // jump out of this loop
}
if (curDist < TURN_DIST) { // if current distance is less than the turn distance
changePath(); // run the changePath function
}
if (curDist > curDist) {maxAngle = pos;}
if (pos > 90 && curDist > curLeft) { curLeft = curDist;}
if (pos == 90 && curDist > curFront) {curFront = curDist;}
if (pos < 90 && curDist > curRight) {curRight = curDist;}
}
maxLeft = curLeft;
maxRight = curRight;
maxFront = curFront;
}
//----
void setCourse() { // set direction for travel based on a very basic distance map, simply which direction has the greatest distance to and object - turning right or left?
if (maxAngle < 90) {turnRight();}
if (maxAngle > 90) {turnLeft();}
maxLeft = 0;
maxRight = 0;
maxFront = 0;
}
//----
void checkCourse() { // we're about to hit something so move backwards, stop, find where the empty path is.
moveBackward();
delay(500);
moveStop();
setCourse();
}
//----
void changePath() {
if (pos < 90) {veerLeft();} // if current pos of sensor is less than 90-degrees, it means the object is on the right hand side so veer left
if (pos > 90) {veerRight();} // if current pos of sensor is greater than 90-degrees, it means the object is on the left hand side so veer right
}
//----
int readPing() { // read the ultrasonic sensor distance
delay(70);
unsigned int uS = sonar.ping();
int cm = uS/US_ROUNDTRIP_CM;
return cm;
}
//----
void checkForward() { if (motorSet=="FORWARD") {motor1.run(FORWARD); motor2.run(FORWARD); } } // make sure motors are going forward
//----
void checkBackward() { if (motorSet=="BACKWARD") {motor1.run(BACKWARD); motor2.run(BACKWARD); } } // make sure motors are going backward
//----
// In some cases, the Motor Drive Shield may just stop if the supply voltage is too low (due to using only four NiMH AA cells).
// The above functions simply remind the Shield that if it's supposed to go forward, then make sure it is going forward and vice versa.
//----
void moveStop() {motor1.run(RELEASE); motor2.run(RELEASE);} // stop the motors.
//----
void moveForward() {
motorSet = "FORWARD";
motor1.run(FORWARD); // turn it on going forward
motor2.run(FORWARD); // turn it on going forward
for (speedSet = 0; speedSet < MAX_SPEED; speedSet +=2) // slowly bring the speed up to avoid loading down the batteries too quickly
{
motor1.setSpeed(speedSet+MAX_SPEED_OFFSET);
motor2.setSpeed(speedSet);
delay(5);
}
}
//----
void moveBackward() {
motorSet = "BACKWARD";
motor1.run(BACKWARD); // turn it on going forward
motor2.run(BACKWARD); // turn it on going forward
for (speedSet = 0; speedSet < MAX_SPEED; speedSet +=2) // slowly bring the speed up to avoid loading down the batteries too quickly
{
motor1.setSpeed(speedSet+MAX_SPEED_OFFSET);
motor2.setSpeed(speedSet);
delay(5);
}
}
//----
void turnRight() {
motorSet = "RIGHT";
motor1.run(FORWARD); // turn motor 1 forward
motor2.run(BACKWARD); // turn motor 2 backward
delay(400); // run motors this way for 400ms
motorSet = "FORWARD";
motor1.run(FORWARD); // set both motors back to forward
motor2.run(FORWARD);
}
//----
void turnLeft() {
motorSet = "LEFT";
motor1.run(BACKWARD); // turn motor 1 backward
motor2.run(FORWARD); // turn motor 2 forward
delay(400); // run motors this way for 400ms
motorSet = "FORWARD";
motor1.run(FORWARD); // turn it on going forward
motor2.run(FORWARD); // turn it on going forward
}
//----
void veerRight() {motor2.run(BACKWARD); delay(400); motor2.run(FORWARD);} // veering right? set right motor backwards for 400ms
//----
void veerLeft() {motor1.run(BACKWARD); delay(400); motor1.run(FORWARD);} // veering left? set left motor backwards for 400ms
//----
You can do what the Arduino Robot does: Use a potentiometer to set the difference (as a percentage) between the left motor and right motor. It takes the value from the potentiometer (0-1023) and maps that to the range +/- 3% (0.97 to 1.03). Then when you want to go straight you pick a speed for the left motor and use the trim factor to pick the speed for the right motor.
narzan:
everything work great but i have a new problem,
there is a motor faster than other so it turn left, not straight !!
any hint about this problem ?
It's very unlikely that two "identical" motors will actually be "identical"... slight mechanical differences for example, different friction.
There are two ways to address this:
Experiment and try to get the robot going straight by sending different PWMs to the motors. Maybe it will go straight with values of 255 and 230, say. Or come up with a factor so that one side gets a PWM of "x", the other of "0.9x". But that's always going to be messy.
Fit encoders to the motors and actually measure their speed. More complicated hardware, and of course the software needs to read the encoders and adjust the PWMs.. But when it's done properly it will give a straight robot.
edit.... Although johnwasser gave a better solution here which is why you should not ask the same question in two different threads. If I had seen that one I wouldn't have answered here.
sorry everyone, i just think the subject must be not here, and i need to make other post for other problem,
ok i get it now its like opening a ticket
and i am really surprise from people here, thanks everyone,
JimboZA, johnwasser, Nick Gammon