Professional Documents
Culture Documents
Sensor
In the previous projects I tried different ways to control the smart tank manually. But how
about if the tank makes its own decision and control itself? It should be quite interesting.
Ultrasonic sensor can help to do so by sending sound wave in front of the sensor. It
receives the wave once the wave meets obstacles and reflects to the sensor so as to
determine the distance. So I've bought an ultrasonic sensor and start another project.
Step 1: Parts
HC-SR04 Ultrasonic Sensor with Servo and Rack
Smart Tank
Arduino Uno
Small Breadboard
Battery Box AA x 4
I just add one more sensor on top of the third project actually.
Step 2: Wiring
I leave the servo unwired at this stage. For the sensor the wiring is as follow:
VCC > 5V
For the smart tank I listed the wiring again below. That is the same as the previous
projects:
IB on the right side > pin 8
GND on both side > - of the battery box and Arduino GND
Step 3: Test the sensor
I wanna test if the sensor works, so I google it and find anything can help. Google is our
friend and this link can be one of the reference:
http://arthursrobotorial.blogspot.hk/2012_12_01_archive.html
//code
#define trigPin 5
#define echoPin 6
void setup()
Serial.begin (9600);
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
int CheckDistance()
digitalWrite(trigPin, HIGH);
digitalWrite(trigPin, LOW);
return distance;
void loop()
Serial.println("Out of range");
Serial.print(testDistance);
Serial.println(" cm");
In Arduino IDE, select Tools > Serial Monitor. It shows the distance if succeeds
#define trigPin 5
#define echoPin 6
void setup()
Serial.begin (9600);
pinMode(motorPin, OUTPUT);
pinMode(motorPin2, OUTPUT);
pinMode(motorPin3, OUTPUT);
pinMode(motorPin4, OUTPUT);
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
void
forward(){
digitalWrite(motorPin, HIGH);
digitalWrite(motorPin2, HIGH);
digitalWrite(motorPin3, LOW);
digitalWrite(motorPin4, LOW);
void backward() {
digitalWrite(motorPin, LOW);
digitalWrite(motorPin2, LOW);
digitalWrite(motorPin3, HIGH);
digitalWrite(motorPin4, HIGH);
void turnLeft() {
digitalWrite(motorPin, HIGH);
digitalWrite(motorPin2, LOW);
digitalWrite(motorPin3, LOW);
digitalWrite(motorPin4, HIGH);
}
void turnRight() {
digitalWrite(motorPin, LOW);
digitalWrite(motorPin2, HIGH);
digitalWrite(motorPin3, HIGH);
digitalWrite(motorPin4, LOW);
int CheckDistance()
digitalWrite(trigPin, HIGH);
digitalWrite(trigPin, LOW);
return distance;
void loop()
forward();
turnRight();
}
The result seems ok
For the wiring of the servo, brown one to Arduino GND, red to 5V and yellow to pin 7.
There is an example in Arduino library for our reference: Examples > Servo > sweep. As
I said before, I don't want the servo keeps turning 180 degree, so I adjust the angle so
as to fit the need. Here I use 0 to 100 degree. I have also adjust the servo to ensure it
moves pointing to the front. I think the response of the servo is quite slow if keep using
the example, so I delete the second part of the loop.
#include <Servo.h>
#define trigPin 5
#define echoPin 6
void setup()
Serial.begin (9600);
myservo.write(pos);
pinMode(motorPin, OUTPUT);
pinMode(motorPin2, OUTPUT);
pinMode(motorPin3, OUTPUT);
pinMode(motorPin4, OUTPUT);
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
void forward(){
digitalWrite(motorPin, HIGH);
digitalWrite(motorPin2, HIGH);
digitalWrite(motorPin3, LOW);
digitalWrite(motorPin4, LOW);
void backward() {
digitalWrite(motorPin, LOW);
digitalWrite(motorPin2, LOW);
digitalWrite(motorPin3, HIGH);
digitalWrite(motorPin4, HIGH);
void turnLeft() {
digitalWrite(motorPin, HIGH);
digitalWrite(motorPin2, LOW);
digitalWrite(motorPin3, LOW);
digitalWrite(motorPin4, HIGH);
void turnRight() {
digitalWrite(motorPin, LOW);
digitalWrite(motorPin2, HIGH);
digitalWrite(motorPin3, HIGH);
digitalWrite(motorPin4, LOW);
int CheckDistance()
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
return distance;
void sweepServo()
for(pos = 0; pos < 100; pos += 1) // goes from 0 degrees to 100 degrees
{ // in steps of 1 degree
delay(10);
void loop()
sweepServo();
Serial.println("out of range");
forward();
else /// object is closer than 30cm, turn right and print distance
turnRight();
Serial.print(testDistance);
Serial.println("cm");
}
One problem arises: it has to run the loop completely before another loop starts. The
sensor detect one time only when the servo move from 0 degree to 100 degree. I want
the sensor detecting the distance without waiting the servo moves. In other word, I want
the sensor detects several times in one servo rotation. How to do that?
Step 6: Troubleshooting
Google tells me I can use the function "millis" or "interrupt" to do so, but I still don't
understand after reading several articles...... : ( The most common example is called
Blink Without Delay. I still don't know how to use it in my situation...... So.... I try another
way that is very cumbersome and the code is as follow:
#include <Servo.h>
#define trigPin 5
#define echoPin 6
void setup()
Serial.begin (9600);
myservo.write(pos);
pinMode(motorPin, OUTPUT);
pinMode(motorPin2, OUTPUT);
pinMode(motorPin3, OUTPUT);
pinMode(motorPin4, OUTPUT);
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
void forward(){
digitalWrite(motorPin, HIGH);
digitalWrite(motorPin2, HIGH);
digitalWrite(motorPin3, LOW);
digitalWrite(motorPin4, LOW);
void backward() {
digitalWrite(motorPin, LOW);
digitalWrite(motorPin2, LOW);
digitalWrite(motorPin3, HIGH);
digitalWrite(motorPin4, HIGH);
void turnLeft() {
digitalWrite(motorPin, HIGH);
digitalWrite(motorPin2, LOW);
digitalWrite(motorPin3, LOW);
digitalWrite(motorPin4, HIGH);
void turnRight() {
digitalWrite(motorPin, LOW);
digitalWrite(motorPin2, HIGH);
digitalWrite(motorPin3, HIGH);
digitalWrite(motorPin4, LOW);
int CheckDistance()
digitalWrite(trigPin, HIGH);
digitalWrite(trigPin, LOW);
return distance;
}
void sweepServo1(){
for(pos = 10; pos < 40; pos += 1) // goes from 0 degrees to 100 degrees
{ // in steps of 1 degree
delay(10);
forward();
turnRight();
Serial.print(testDistance);
Serial.println("cm");
void sweepServo2(){
for(pos = 40; pos < 80; pos += 1) // goes from 0 degrees to 100 degrees
{ // in steps of 1 degree
delay(10);
forward();
{
turnRight();
Serial.print(testDistance);
Serial.println("cm");
void sweepServo3(){
for(pos = 80; pos < 120; pos += 1) // goes from 0 degrees to 100 degrees
{ // in steps of 1 degree
delay(10);
forward();
turnRight();
Serial.print(testDistance);
Serial.println("cm");
void loop()
sweepServo1();
sweepServo2();
sweepServo3();
I separate the servo sweep into three parts (sweepServo1 to 3). Each part controls
different angles and all parts are looped together in orders.
Step 7: Result
It works! After trial and error, I think 30 cm is appropriate and the tank has enough time
to respond. But the final code can be made much more simple. Please tell me how to
revise if anyone knows how to add the function "millis" or "interrupt". Next time I will try a
very different stuff. Thanks for your watching. See you!