-
Drive 10m ahead
-
If the ultrasonic sensor detects obstacle 30cm front, the robot stops.
-
If the obstacle is removed, it continues to move
-
if the obstacle is not removed for 1 minute, it moves but changes path.
-
The changed path is following: Move backward by 30 cm. Drive with semi-circle of D=2m to to the left to avoid obstacle.
-
After finishing the 10m straight to front, it ends.
Start making code for:
- motor control.
- ultrasonic sensor reading
- using the working motor control create code for estimating distance.
- make code handling time limits.
Merge the parts together and adjust them.
You need a lot more sensors than that to avoid an obstacle. I would add a 6axis gyro to know the direction of the car and if the car is moving. Ultrasonic sensors are handy but they describe an obstacle not alwase verry accurate, they have there limits. If you want to be MORE sure there is an obstacle you probebly need a lidar that is turns around 360 degrees.
When is the assignment due?
You have to drive 10m: How are you doing odometry? That is, how do you know you've traveled 10m? Encoders on the wheels/motors would be a good start.
What should I add to achieve number 4,5 to the coding?
void loop() {
float duration, distance;
digitalWrite(IR_TRIG, HIGH);
delay(10);
digitalWrite(IR_TRIG, LOW);
duration = pulseIn(IR_ECHO, HIGH);
distance = ((float)(340 * duration) / 10000) / 2;
Serial.print("\nDIstance : ");
Serial.println(distance);
if(distance < 20) { //sense obstacle (20cm)
Serial.println("stop");
stop(); //stop(3sec)
}else{ // no obstacle
Serial.println("forward");
forward();
}
}
void forward(){
digitalWrite(LEFT_A1, HIGH);
digitalWrite(LEFT_B1, LOW);
digitalWrite(RIGHT_A2, HIGH);
digitalWrite(RIGHT_B2, LOW);
}
void backward(){
digitalWrite(LEFT_A1, LOW);
digitalWrite(LEFT_B1, HIGH);
digitalWrite(RIGHT_A2, LOW);
digitalWrite(RIGHT_B2, HIGH);
delay(500);
}
void left(){
digitalWrite(LEFT_A1, LOW);
digitalWrite(LEFT_B1, HIGH);
digitalWrite(RIGHT_A2, HIGH);
digitalWrite(RIGHT_B2, LOW);
delay(1000);
}
void right(){
digitalWrite(LEFT_A1, HIGH);
digitalWrite(LEFT_B1, LOW);
digitalWrite(RIGHT_A2, LOW);
digitalWrite(RIGHT_B2, HIGH);
delay(1000);
}
void stop(){
digitalWrite(LEFT_A1, LOW);
digitalWrite(LEFT_B1, LOW);
digitalWrite(RIGHT_A2, LOW);
digitalWrite(RIGHT_B2, LOW);
delay(3000);
}
for number 5, it doesnt have to be the exact move as I wrote. It just have to move away and come back to straight line to avoid something that does not move like tree.
First, read the forum instructions. Then you can edit your code in that last post to be usable.
Your wiring diagram suggests you are connecting something to "Vin". DO not use "Vin"or the"barrel jack" on the UNO.
Oh Thank you. Then where should I connect the wire? Actually it works until 3.
This is my coding currently. I have changed the stop time to 30 sec and simplified step 4~5. But it does not function as well as I thought. It stops and goes smooth but it does not move away when an object is blocking. What statement should I use?
#include <SoftwareSerial.h>
#define LEFT_A1 4
#define LEFT_B1 5
#define RIGHT_A2 6
#define RIGHT_B2 7
#define IR_TRIG 9
#define IR_ECHO 8
void setup() {
Serial.begin(9600);
pinMode(LEFT_A1, OUTPUT);
pinMode(RIGHT_A2, OUTPUT);
pinMode(LEFT_B1, OUTPUT);
pinMode(RIGHT_B2, OUTPUT);
pinMode(IR_TRIG, OUTPUT);
pinMode(IR_ECHO, INPUT);
}
void loop() {
float duration, distance;
digitalWrite(IR_TRIG, HIGH);
delay(10);
digitalWrite(IR_TRIG, LOW);
duration = pulseIn(IR_ECHO, HIGH);
distance = ((float)(340 * duration) / 10000) / 2;
Serial.print("\nDistance : ");
Serial.println(distance);
int sum = 0;
if(distance < 20) {
Serial.println("stop");
stop();
sum++ ;
while (sum > 10) {
Serial.println("backward");
backward ();
Serial.println("left");
left ();
Serial.println("forwardi");
forwardi ();
Serial.println("right");
right ();
Serial.println("forwardi");
forwardi ();
Serial.println("forwardi");
forwardi ();
Serial.println("right");
right ();
Serial.println("forwardi");
forwardi ();
Serial.println("left");
left ();
Serial.println("forward");
forward();
}
}else {
Serial.println("forward");
forward();
}
}
void forward(){
digitalWrite(LEFT_A1, HIGH);
digitalWrite(LEFT_B1, LOW);
digitalWrite(RIGHT_A2, HIGH);
digitalWrite(RIGHT_B2, LOW);
}
void forwardi (){
digitalWrite(LEFT_A1, HIGH);
digitalWrite(LEFT_B1, LOW);
digitalWrite(RIGHT_A2, HIGH);
digitalWrite(RIGHT_B2, LOW);
delay (4000);
}
void backward(){
digitalWrite(LEFT_A1, LOW);
digitalWrite(LEFT_B1, HIGH);
digitalWrite(RIGHT_A2, LOW);
digitalWrite(RIGHT_B2, HIGH);
delay(1000);
}
void left(){
digitalWrite(LEFT_A1, LOW);
digitalWrite(LEFT_B1, HIGH);
digitalWrite(RIGHT_A2, HIGH);
digitalWrite(RIGHT_B2, LOW);
delay(1000);
}
void right(){
digitalWrite(LEFT_A1, HIGH);
digitalWrite(LEFT_B1, LOW);
digitalWrite(RIGHT_A2, LOW);
digitalWrite(RIGHT_B2, HIGH);
delay(1000);
}
void stop(){
digitalWrite(LEFT_A1, LOW);
digitalWrite(LEFT_B1, LOW);
digitalWrite(RIGHT_A2, LOW);
digitalWrite(RIGHT_B2, LOW);
delay(3000);
}
The Arduino runs on 5 V - or as near as possible. So you power it by the "5V" pin. There may be a concern about powering it from a PC to the USB port at the same time, so just disconnect the power from the "5V" pin when connected to a PC.
Please also edit the first code in #5 with code tags.
You may have to understand the concept of State machines.
On you program:
- Do not use the delay function. It won't work for your problem. This effect must be done using the millis() or the micros() command
- Let us define certain situations or States.
State=0 the car is moving forward,
State=1 the car stopped because of the obstacle,
State=2 the car is moving backward
State=3 the car is turning left
State=4 mission accomplished
Mapping this with your specs:
State=0 1. Drive 10m ahead
State=1 2. If the ultrasonic sensor detects an obstacle 30cm front, the robot stops.
State=0 3. If the obstacle is removed, it continues to move
4. if the obstacle is not removed for 1 minute, it moves but changes path.
State=2 5. The changed path is as follows: Move backward by 30 cm.
State=3 Drive with a semi-circle of D=2m to the left to avoid obstacles.
State=4 6. After finishing the 10m straight to the front, it ends.
State Transitions are:
0 --> 0 keep moving forward
0 --> 1 obstacle detected 30cm
0 --> 4 10 meters achieved
1 --> 0 obstacle removed
1 --> 1 Waiting
1 --> 2 1 minute elapse Change path
2 --> 2 Still moving backward
2 --> 3 backward or 30 cm achieved
3 --> 3 turning to the left
3 --> 0 2m achieved
4 --> 4 Stop
Try the following code:
#include <SoftwareSerial.h>
#define LEFT_A1 4
#define LEFT_B1 5
#define RIGHT_A2 6
#define RIGHT_B2 7
#define IR_TRIG 9
#define IR_ECHO 8
int currState = 0;
int nextState = 1;
unsigned long int forwardStartTime;
unsigned long int stopStartTime;
unsigned long int backStartTime;
unsigned long int leftStartTime;
unsigned long int totalForwardTime = 0;
void setup() {
Serial.begin(9600);
pinMode(LEFT_A1, OUTPUT);
pinMode(RIGHT_A2, OUTPUT);
pinMode(LEFT_B1, OUTPUT);
pinMode(RIGHT_B2, OUTPUT);
pinMode(IR_TRIG, OUTPUT);
pinMode(IR_ECHO, INPUT);
}
void loop() {
float duration, distance;
digitalWrite(IR_TRIG, HIGH);
delay(10);
digitalWrite(IR_TRIG, LOW);
duration = pulseIn(IR_ECHO, HIGH);
distance = ((float)(340 * duration) / 10000) / 2;
distance = 10;
Serial.print("\nDistance : ");
Serial.println(distance);
/*
STATE=0 1. Drive 10m ahead
STATE=1 2. If the ultrasonic sensor detects obstacle 30cm front, the robot stops.
STATE=0 3. If the obstacle is removed, it continues to move
if the obstacle is not removed for 1 minute, it moves but changes path.
STATE=2 The changed path is following: Move backward by 30 cm.
STATE=3 Drive with semi-circle of D=2m to to the left to avoid obstacle.
STATE4 After finishing the 10m straight to front, it ends.
*/
/* State Trnsitions
0 --> 0 keep moving forward
0 --> 1 obstacle detected 30cm
0 --> 4 10 meters achieved
1 --> 0 obstacle removed
1 --> 1 Waiting
1 --> 2 1 minute elapse Change path
2 --> 2 Still moving backward
2 --> 3 backward or 30 cm achieved
3 --> 3 turning to the left
3 --> 0 2m achieved
4 --> 4 Stop
*/
int prevState = currState;
currState = nextState;
if (currState == 0) {
if (distance <= 30) {
nextState = 1;
} else if (prevState != currState) { // just started
forward();
forwardStartTime = millis();
} else { // keep going forward
unsigned long int timeNow = millis();
totalForwardTime = totalForwardTime + timeNow - forwardStartTime;
forwardStartTime = timeNow;
Serial.print("forwardStartTime:");
Serial.print(forwardStartTime);
if (totalForwardTime >= 10000) { //10 meters achieved
nextState = 4;
}
}
} else if (currState == 1) {
if (distance > 30) { // obstacle removed
nextState = 0;
} else if (prevState != currState) { // just stoped
stop();
stopStartTime = millis();
} else if (millis() - stopStartTime > 60000) { //60 * 1000ms = 1 minute elapse Change path
nextState = 2;
}
} else if (currState == 2) {
if (prevState != currState) { // start moving backward
backward();
backStartTime = millis();
} else if (millis() - backStartTime > 3000) { //back 30 cm achieved
nextState = 3;
}
} else if (currState == 3) {
if (prevState != currState) { // start turning left
left();
leftStartTime = millis();
} else if (millis() - leftStartTime > 20000) { //left 2m achieved
nextState = 0;
}
} else if (currState == 4) { // Stop
if (prevState != currState) { // start turning left
stop();
while (true) {
}
}
}
}
void forward() {
digitalWrite(LEFT_A1, HIGH);
digitalWrite(LEFT_B1, LOW);
digitalWrite(RIGHT_A2, HIGH);
digitalWrite(RIGHT_B2, LOW);
}
void backward() {
digitalWrite(LEFT_A1, LOW);
digitalWrite(LEFT_B1, HIGH);
digitalWrite(RIGHT_A2, LOW);
digitalWrite(RIGHT_B2, HIGH);
}
void left() {
digitalWrite(LEFT_A1, LOW);
digitalWrite(LEFT_B1, HIGH);
digitalWrite(RIGHT_A2, HIGH);
digitalWrite(RIGHT_B2, LOW);
}
void right() {
digitalWrite(LEFT_A1, HIGH);
digitalWrite(LEFT_B1, LOW);
digitalWrite(RIGHT_A2, LOW);
digitalWrite(RIGHT_B2, HIGH);
}
void stop() {
digitalWrite(LEFT_A1, LOW);
digitalWrite(LEFT_B1, LOW);
digitalWrite(RIGHT_A2, LOW);
digitalWrite(RIGHT_B2, LOW);
}
There is still work to be done. You should remove/rewrite the portion with the delay(10) and the pulseIn(). Also the timing of how much on time is 10m, 30cm, 2m. I hope this gives you an idea on what to do.
Thank you for your answers. I have finished my code and done the project. I'll be looking in to your coding for further learnings. Thank you so much!
#include <SoftwareSerial.h>
#define LEFT_A1 4
#define LEFT_B1 5
#define RIGHT_A2 6
#define RIGHT_B2 7
#define IR_TRIG 9
#define IR_ECHO 8
void setup() {
Serial.begin(9600);
pinMode(LEFT_A1, OUTPUT);
pinMode(RIGHT_A2, OUTPUT);
pinMode(LEFT_B1, OUTPUT);
pinMode(RIGHT_B2, OUTPUT);
pinMode(IR_TRIG, OUTPUT);
pinMode(IR_ECHO, INPUT);
}
void loop() {
float duration, distance;
digitalWrite(IR_TRIG, HIGH);
delay(10);
digitalWrite(IR_TRIG, LOW);
duration = pulseIn(IR_ECHO, HIGH);
distance = ((float)(340 * duration) / 10000) / 2;
Serial.print("\nDistance : ");
Serial.println(distance);
int sum = 0;
while(distance < 20) {
Serial.println("stop");
stop();
sum++ ;
Serial.println(sum);
float duration, distance;
digitalWrite(IR_TRIG, HIGH);
delay(10);
digitalWrite(IR_TRIG, LOW);
duration = pulseIn(IR_ECHO, HIGH);
distance = ((float)(340 * duration) / 10000) / 2;
Serial.print("\nDistance : ");
Serial.println(distance);
if(distance >= 20){
Serial.println("forward");
forward();}
if(distance >= 20) {
break;
}
if(sum > 9) {
Serial.println("backward");
backward ();
Serial.println("left");
left ();
Serial.println("forwardi");
forwardi ();
Serial.println("right");
right ();
Serial.println("forwardi");
forwardi ();
Serial.println("forwardi");
forwardi ();
Serial.println("right");
right ();
Serial.println("forwardi");
forwardi ();
Serial.println("left");
left ();
Serial.println("forward");
forward();
sum = 0;
}
}
if(distance >= 20){
Serial.println("forward");
forward();}
}
void forward(){
digitalWrite(LEFT_A1, HIGH);
digitalWrite(LEFT_B1, LOW);
digitalWrite(RIGHT_A2, HIGH);
digitalWrite(RIGHT_B2, LOW);
}
void forwardi (){
digitalWrite(LEFT_A1, HIGH);
digitalWrite(LEFT_B1, LOW);
digitalWrite(RIGHT_A2, HIGH);
digitalWrite(RIGHT_B2, LOW);
delay (2000);
}
void backward(){
digitalWrite(LEFT_A1, LOW);
digitalWrite(LEFT_B1, HIGH);
digitalWrite(RIGHT_A2, LOW);
digitalWrite(RIGHT_B2, HIGH);
delay(1000);
}
void left(){
digitalWrite(LEFT_A1, LOW);
digitalWrite(LEFT_B1, HIGH);
digitalWrite(RIGHT_A2, HIGH);
digitalWrite(RIGHT_B2, LOW);
delay(500);
}
void right(){
digitalWrite(LEFT_A1, HIGH);
digitalWrite(LEFT_B1, LOW);
digitalWrite(RIGHT_A2, LOW);
digitalWrite(RIGHT_B2, HIGH);
delay(500);
}
void stop(){
digitalWrite(LEFT_A1, LOW);
digitalWrite(LEFT_B1, LOW);
digitalWrite(RIGHT_A2, LOW);
digitalWrite(RIGHT_B2, LOW);
delay(3000);
}
So now you are using IR sensors... to measure distance?? If you put them into sunlight they will go off.
Still not using a gyro?
This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.