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.
part 1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
part 1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Battery Box AA x 4
I just add one more sensor on top of the third project actually.
Wiring;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
I leave the servo unwired at this stage. For the sensor the wiring is as follow:
GND > Arduino GND
Echo > Pin 6
Trig > Pin 5
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
IA on the left side > pin 9
IA on the right side > pin 10
IB on the left side > pin 11
VCC on both side > + of the battery box
GND on both side > - of the battery box and Arduino GND
Test the sensors;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
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:
In Arduino IDE, select Tools > Serial Monitor. It shows the distance if succeeds.
#define trigPin 5#define echoPin 6void setup(){Serial.begin (9600);pinMode(trigPin, OUTPUT);pinMode(echoPin, INPUT);}int CheckDistance(){long duration, distance;digitalWrite(trigPin, LOW); // Added this linedelayMicroseconds(2); // Added this linedigitalWrite(trigPin, HIGH);// delayMicroseconds(1000); - Removed this linedelayMicroseconds(10); // Added this linedigitalWrite(trigPin, LOW);duration = pulseIn(echoPin, HIGH);distance = (duration/2) / 29.1;return distance;}void loop(){int testDistance = CheckDistance(); /// get object distance using ping/// if object is more than 50 cm away it is out of rangeif (testDistance >= 50 || testDistance <= 0) /// if object is more than 50 cm away it is out of range{Serial.println("Out of range");}else /// object is closer than 50cm, print distance{Serial.print(testDistance);Serial.println(" cm");delay(500); ///wait half a sec before next ping}Then I combine the code in the first stage with the code in the third project and revise a little bit: If the distance between the sensor and the object is more than 30cm, it goes forward. Otherwise it turns right.#define trigPin 5#define echoPin 6int motorPin = 8; //right side to IB - forwwardint motorPin2 = 9; //left side to IA - forwwardint motorPin3 = 10; //right side to IA - backwardint motorPin4 = 11; //left side to IB - backwardvoid 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(){long duration, distance;digitalWrite(trigPin, LOW); // Added this linedelayMicroseconds(2); // Added this linedigitalWrite(trigPin, HIGH);// delayMicroseconds(1000); - Removed this linedelayMicroseconds(10); // Added this linedigitalWrite(trigPin, LOW);duration = pulseIn(echoPin, HIGH);distance = (duration/2) / 29.1;return distance;}void loop(){int testDistance = CheckDistance(); /// get object distance using pingif (testDistance >= 30 || testDistance <= 0) /// if object is more than 30 cm away it goes forward{forward();}else /// object is closer than 30cm, turns right{turnRight();}delay(500); ///wait half a sec before next ping}The servo included with this sensor can move 180 degree. Because I want the smart tank to avoid anything in the front, it would be too sensitive if it avoids obstacles in 180 degree. I want the servo moves in certain degree in front of the tank, not in the full degree of the servo. The servo has to be calibrate and make sure 90 degree is pointing to the front. You can turn the servo anticlockwise until it gets stuck. Then plug the sensor out and on again pointing at 9. After that turn the servo 90 degree clockwise until it points to the front.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#define trigPin 5#define echoPin 6Servo myservo; // create servo object to control a servo// a maximum of eight servo objects can be createdint pos = 0; // variable to store the servo positionint servoDirection = 100;int servoDelay = 20;int motorPin = 8; //right side to IB - forwardint motorPin2 = 9; //left side to IA - forwardint motorPin3 = 10; //right side to IA - backwardint motorPin4 = 11; //left side to IB - backwardvoid setup(){Serial.begin (9600);myservo.attach(7); // attaches the servo on pin 7 to the servo objectmyservo.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(){long duration, distance;digitalWrite(trigPin, LOW);delayMicroseconds(2);digitalWrite(trigPin, HIGH);delayMicroseconds(10);digitalWrite(trigPin, LOW);duration = pulseIn(echoPin, HIGH);distance = (duration/2) / 29.1;return distance;}void sweepServo(){for(pos = 0; pos < 100; pos += 1) // goes from 0 degrees to 100 degrees{ // in steps of 1 degreemyservo.write(pos); // tell servo to go to position in variable 'pos'delay(10);}}void loop(){sweepServo();int testDistance = CheckDistance(); /// get object distance using ping/// if object is more than 30 cm away it is out of rangeif (testDistance >= 30 || testDistance <= 0) /// if object is more than 30 cm away it is out of range and goes forward{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?




No comments:
Post a Comment