I am building a robot, that, among other things, should stop when there is something in front of it. I am planning on having 4 motors, but as of yet only have 1 DC motor hooked up to a Leonardo through the Arduino motor shield. I have also attached a parallax PING))) ultrasonic sensor to pin 7. I have written the code so the motor should go, until something is less than 5 inches away from it. Simple right. Apparently not. The motor just moves, no matter what happens, or how close I put something to the ultrasonic sensor. The sensor flashes every 5 or so seconds, not rapidly like it did when I tried the Arduino example code.
/*******************************\
(c) ma7730 2015
code to move motor until obstacle
\*******************************/
float inches;
float duration;
const int pingPin = 7; //ultrasonic sensor on pin 7
const int distance = 5; // closest it can be
float detectObject(){
pinMode(pingPin, OUTPUT); // Set pin to OUTPUT
digitalWrite(pingPin, LOW); // Ensure pin is low
delayMicroseconds(2);
digitalWrite(pingPin, HIGH); // Start ranging
delayMicroseconds(5); // with 5 microsecond burst
digitalWrite(pingPin, LOW); // End ranging
pinMode(pingPin, INPUT); // Set pin to INPUT
duration = pulseIn(pingPin, HIGH); // Read echo pulse
inches = duration / 74 / 2;
return inches; //return distance to nearest object in inches
}
void moveForward(){
//forward @ full speed
digitalWrite(12, HIGH); //establishes forward direction
digitalWrite(9, LOW); //disengage the brake
analogWrite(3, 255); //spins the motor at full speed
delay(3000);
}
void stopMotor(){
digitalWrite(9, HIGH); //brake
}
void setup(){
pinMode(12, OUTPUT); //initiates motor as output
pinMode(9, OUTPUT); //initiates brake as output
}
void loop(){
moveForward(); //move forward
detectObject(); //look for obstacle
if(detectObject() < distance) stopMotor(); //if there is something less than 5 inches away, stop
else moveForward; //otherwise, keep moving
}
I think it nevers gets to the part where it is supposed to sense for an object, because if I remove the moveForward(); in the void loop, the motor doesn't move no matter what. Maybe I am missing something obvious, but I have been working on this forever and can't seem to figure out what the problem is.
Why does detectObject() return a global variable? Why is duration a float? Are you expecting to measure 3.7 microseconds? The pulseIn() function returns an unsigned long.
detectObject(); //look for obstacle
if(detectObject() < distance) stopMotor(); //if there is something less than 5 inches away, stop
Why do you call the function twice? The first time is useless.
@TomGeorge - Thank you for your quick reply! I deleted the delay in the moveForward() functions, but, there is no difference whatsoever. Also, the delayMicroseconds in the detectObject() function are the exact same as those in the example, so why should that be a problem?
@PaulS - I changed the type of detectObject(), inches, and duration from an int to a long, and nothing changed. The function returns a global variable so that I can use that to evaluate if the motor should stop.
I am a little confused as to what you are saying in the second part of your post. I first look for an obstacle. If there is an obstacle less than distance away (5 inches) the motor should stop. Otherwise it should keep moving. I know, you don't need the else, but it doesn't do any harm. I commented it out and nothing changed.
detectObject(); //look for obstacle
if(detectObject() < distance) stopMotor();
Why call detectObject() and don't do anything with it just to call detectObject again.
If you want to use your global variable you could do:
detectObject(); //look for obstacle
if(inches < distance) stopMotor();
But the function calls order as it is now without the delay in moveForward() and if an obstacle is < 5.
moveForward()
detectObject()
detectObject()
stopMotor()
moveForward()
detectObject()
detectObject()
stopMotor()
.... and so on.
moveForward() is called directly after stopMotor().
To just test if this is the problem and everything else in the code is correct you could put a delay of say 10 seconds in stopMotor() to see if it is stopped for 10 seconds when it should.
And about the else, as it is now it is unnecessary. The robot will always be moving forward if the else is executed as it is now?
You have also forgotten the function call operator () so the function moveForward isn't called. Now it only gives the functions address (if I remember correctly.) and discards it. (Basically the same as just writing 47 there instead of moveForward as PaulS pointed out.)