Arduino Robot That Avoids Human
by HackARobot in Circuits > Arduino
7472 Views, 51 Favorites, 0 Comments
Arduino Robot That Avoids Human
In my previous instructable, I showed that it is very simple to control DC motors using Arduino Nano compatible controller and Fabric Shield. You can get this robot through my Kickstarter project.
I am going show you how to read the Ultrasonic Distance Sensor and use the measured distance to guide a robot. In this tutorial, the robot moves backward and turns away if it senses something that is too close.
Plug in an Ultrasonic Distance Sensor
Please follow my other instructable to connect the motors. In addition, you will need to attach the ultrasonic distance sensor (HC-SR04) to the Fabric Shield. There are female header pins specifically designed to connect to this sensor. See picture attached.
Basically, the "Trig" and "Echo" pins connect to A1 and A0 pins of Arduino Nano respectively.
Program the Arduino Nano Controller
Connect the Arduino Nano controller to your PC through the USB cable provided. You need to unplug the controller from the Fabric Shield before programming.
You may copy and paste the program from next section and upload it to the controller through standard IDE from Arduino.cc.
Once it is uploaded, you may unplug the USB cable and insert the Arduino Nano controller to the Fabric Shield. The next step is to provide 6V DC power and your robot is ready to go. Simple, right :)
The Code
Detailed operation of the Ultrasonic Distance Sensor could be found in the HC_SR04 datasheet.
The code used in this robot is really simple. In the main loop (loop()), it measure the distance by calling the getDistance() function.
If the distance between the robot and the obstacle (in this case , my hands) is too close (say 10cm), the robot move backward for 300 milliseconds and randomly turn the left or right for another 200 milliseconds.
void loop() { distance = getDistance(); Serial.print("Distance = "); Serial.print(distance); Serial.println("cm"); if (distance < 10) { robotBackward(300); if (random(2)==0) { robotRight(200); } else { robotLeft(200); } } robotStop(50); }
Here is how the 'getDistance()' function work:
float getDistance() { digitalWrite(TRIGGER_PIN, LOW); delayMicroseconds(2); digitalWrite(TRIGGER_PIN, HIGH); delayMicroseconds(10); digitalWrite(TRIGGER_PIN, LOW); return ( pulseIn(ECHO_PIN, HIGH) *0.017); }
It sends out a rising edge on "Trig" pin by first sending out LOW and followed by HIGH. After 10 micro-seconds, it lowers the "Trig" signal again. This makes the sensor send out ultrasonic pulses. Later on, it monitors the echo reflected by the obstacles. If the obstacle is closer, it takes less time to receive the echos. On the other hand, if the obstacle is far away, it takes more time to wait for the echos. The sensor send out a HIGH pulse on "Echo" pin and the pulse width equals to the round trip delay of the ultrasonic pulses (in microseconds).
Since the speed of sound is 340 meter/second, the distance could be calculated by D = 0.5 * pulse_width * 340 m/s * 1e-6
The complete program is listed here:
// pins controller motors #define motor1_pos 3 #define motor1_neg 10 #define motor2_pos 6 #define motor2_neg 9 #define motor_en A2 #define TRIGGER_PIN 15 // (A1) Arduino pin tied to trigger pin on the ultrasonic sensor. #define ECHO_PIN 14 // (A0) Arduino pin tied to echo pin on the ultrasonic sensor. float distance; void setup() { Serial.begin(57600); setupMotor(); } void loop() { distance = getDistance(); Serial.print("Distance = "); Serial.print(distance); Serial.println("cm"); if (distance < 10) { robotBackward(300); if (random(2)==0) { robotRight(200); } else { robotLeft(200); } } robotStop(50); } void setupMotor() { pinMode(motor1_pos,OUTPUT); pinMode(motor1_neg,OUTPUT); pinMode(motor2_pos,OUTPUT); pinMode(motor2_neg,OUTPUT); pinMode(motor_en,OUTPUT); enableMotor(); robotStop(50); } //----------------------------------------------------------------------------------------------------- // Ultrasonic Distance Sensor //----------------------------------------------------------------------------------------------------- float getDistance() { digitalWrite(TRIGGER_PIN, LOW); delayMicroseconds(2); digitalWrite(TRIGGER_PIN, HIGH); delayMicroseconds(10); digitalWrite(TRIGGER_PIN, LOW); return ( pulseIn(ECHO_PIN, HIGH) *0.017); } //----------------------------------------------------------------------------------------------------- // motor //----------------------------------------------------------------------------------------------------- void enableMotor() { //Turn on the motor driver chip : L293D digitalWrite(motor_en, HIGH); } void disableMotor() { //Turn off the motor driver chip : L293D digitalWrite(motor_en, LOW); } void robotStop(int ms){ digitalWrite(motor1_pos, LOW); digitalWrite(motor1_neg, LOW); digitalWrite(motor2_pos, LOW); digitalWrite(motor2_neg, LOW); delay(ms); } void robotForward(int ms){ digitalWrite(motor1_pos, HIGH); digitalWrite(motor1_neg, LOW); digitalWrite(motor2_pos, HIGH); digitalWrite(motor2_neg, LOW); delay(ms); } void robotBackward(int ms){ digitalWrite(motor1_pos, LOW); digitalWrite(motor1_neg, HIGH); digitalWrite(motor2_pos, LOW); digitalWrite(motor2_neg, HIGH); delay(ms); } void robotRight(int ms){ digitalWrite(motor1_pos, LOW); digitalWrite(motor1_neg, HIGH); digitalWrite(motor2_pos, HIGH); digitalWrite(motor2_neg, LOW); delay(ms); } void robotLeft(int ms){ digitalWrite(motor1_pos, HIGH); digitalWrite(motor1_neg, LOW); digitalWrite(motor2_pos, LOW); digitalWrite(motor2_neg, HIGH); delay(ms); }