Arduino obstacle avoidance car crashes and then read ultrasonic sensor - arduino

I've been working on a Arduino obstacle avoidance car, I'm using an arduino uno, two TT motors 1:48, one ultrasonic sensor SR04, one universal wheel and a L298D module with PWM to slow down motors.
I use serial monitor to check ultrasonic measure in cm, and seems to work fine except some times throws weird values line 2300, 2400 cm, which is not posible because the maximum measure distance is 400cm. I can also force those values if I put my hand over the sensor. There is a way to avoid that?
Also when I put the car on the floor sometimes it detects the minimum distance and the car stops before crashes to the wall, but other times it crashes and then reads the sensor and then executes a routine in case the distance is less that the distance threshold. I don't know why that happens, is not supposed to stop always almost instantly when the sensor reads the distance minimum distance and then rotate to avoid it?
This is my code:
int distance = 0;
long readUltrasonicDistance(int triggerPin, int echoPin)
{
pinMode(triggerPin, OUTPUT); // Clear the trigger
digitalWrite(triggerPin, LOW);
delayMicroseconds(2);
// Sets the trigger pin to HIGH state for 10 microseconds
digitalWrite(triggerPin, HIGH);
delayMicroseconds(10);
digitalWrite(triggerPin, LOW);
pinMode(echoPin, INPUT);
// Reads the echo pin, and returns the sound wave travel time in microseconds
return pulseIn(echoPin, HIGH);
}
void setup()
{
pinMode(10, OUTPUT);
pinMode(11, OUTPUT);
pinMode(6, OUTPUT);
pinMode(7, OUTPUT);
pinMode(8, OUTPUT);
pinMode(9, OUTPUT);
}
void loop()
{
// Speed always the same
analogWrite(10, 110);
analogWrite(11, 110);
distance = 0.01723 * readUltrasonicDistance(3, 2);
delay(100); // Wait for 100 millisecond(s)
if (distance < 8) {
digitalWrite(6, LOW);
digitalWrite(7, LOW);
digitalWrite(8, LOW);
digitalWrite(9, LOW);
delay(500); // Wait for 500 millisecond(s)
digitalWrite(6, LOW);
digitalWrite(7, HIGH);
digitalWrite(8, HIGH);
digitalWrite(9, LOW);
delay(500); // Wait for 500 millisecond(s)
digitalWrite(6, LOW);
digitalWrite(7, LOW);
digitalWrite(8, LOW);
digitalWrite(9, HIGH);
analogWrite(10, 90);
analogWrite(11, 90);
delay(500); // Wait for 500 millisecond(s)
} else {
digitalWrite(6, HIGH);
digitalWrite(7, LOW);
digitalWrite(8, LOW);
digitalWrite(9, HIGH);
}
}
I hope you can help me

I can't see too much wrong with the code, but I do have a number of suggestions:
I would recommend using the NewPing library for accessing the sensor. This will handle the sensor trigger and return the distance in cm. It also handles any errors - and returns 0. It can also do some sampling - where it gives you a median of a series of measurements to try and reduce the errors you're seeing.
You have quite a large delay - delay(100) - between measuring the distance, and checking for proximity. A robot can travel quite some distance in 100ms, and I don't think this delay is needed.
I would normally slow the robot down as you get closer to the object. So perhaps go to 60% of your normal speed when you get within 15cm for example. This gives the robot more time to measure the distance and react as it gets nearer the obstacle.
These sensors are no good for measuring distances if you approach an obstacle - such as a wall - at much of an angle. At 45 degrees for example, it just won't see the wall at all and happily crash into it. So you need to be aware of that.

Related

Improve arduino for loop and void loop

I have wrote code for my Arduino project. It has a for loop. After for loop done there is a void loop.
I am expecting starting gap should reduce from 100 to 0 and remains constant. But when the code runs it goes 100 to 0 and reset the values again to 100. Then again values will go to 100 to 0. This time it remains 0.
My issue is why it takes two time to remain 0.What are the changes I should do to code to get expected output.
Expected output is only one loop. 100 is reducing to 0. then remain 0.
thank you.
Expected output is like this. Sine wave is come from a AC supply. Please neglect the shape of sine and assume it as a pulse (PWM).
Code:
int minGap = 0;//motor full speed gap
int pulseWidth = 10;//pulse lenght
int startGap = 100;//starting gap
int gapReduseRate = 1;//gap reduse rate
void setup() {
// initialize digital pin LED_BUILTIN as an output.
pinMode(3, OUTPUT);
pinMode(9, OUTPUT);
pinMode(5, OUTPUT);
pinMode(6, OUTPUT);
for(int i=startGap ; i>minGap ; i=i-gapReduseRate){
digitalWrite(3, HIGH); // turn the LED on (HIGH is the voltage level)
digitalWrite(9, HIGH);
digitalWrite(5, HIGH);
digitalWrite(6, HIGH);// turn the LED on (HIGH is the voltage level)
delayMicroseconds(pulseWidth); // wait for a second
digitalWrite(3, LOW); // turn the LED off by making the voltage LOW
digitalWrite(9, LOW);
digitalWrite(5, LOW);
digitalWrite(6, LOW);// turn the LED off by making the voltage LOW
delayMicroseconds(i); // wait for a second
}
}
// the loop function runs over and over again forever
void loop() {
digitalWrite(3, HIGH); // turn the LED on (HIGH is the voltage level)
digitalWrite(9, HIGH);
digitalWrite(5, HIGH);
digitalWrite(6, HIGH);// turn the LED on (HIGH is the voltage level)
delayMicroseconds(pulseWidth); // wait for a second
digitalWrite(3, LOW); // turn the LED off by making the voltage LOW
digitalWrite(9, LOW);
digitalWrite(5, LOW);
digitalWrite(6, LOW);// turn the LED off by making the voltage LOW
delayMicroseconds(minGap); // wait for a second
}

Program only works when connected to PC

new to arduino programming, making a proximity sensor with an HC-SRO4 module. It works almost flawlessly when connected to my computer via USB, but whenever I connect it to the wall, it stops working. What I've noticed is that the "TX" light also isn't on when it's connected to the wall, but it is when connected to the PC. The adapter i'm using when it's plugged into the wall is 9V/1A DC that came with the arduino.
void setup() {
#define LED 8
#define trigPin 12
#define echoPin 13
Serial.begin (9600);
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
pinMode(LED, OUTPUT);
}
void loop() {
int duration, distance;
digitalWrite(trigPin, HIGH);
delayMicroseconds(1000);
digitalWrite(trigPin, LOW);
duration = pulseIn(echoPin, HIGH);
distance = (duration/2) / 29.1
;if (distance >= 60 || distance <= 0){
Serial.println("no object detected");
digitalWrite(LED, LOW);}
else {
Serial.println("object detected");
digitalWrite(LED, HIGH);
}}
There is a bug where the serial command suche as serial.begin, serial.write and serial.read if they are meant to for debug purposes on your cpu have a blocking effect on your program. I've experienced it once or twice so try commenting those lines out.

Ultrasonic program giving me an odd error

I created a program that is intended to turn a servo motor 180 degrees then back if an object is within 20cm of the ultrasonic sensor. This works fine except sometimes when the if condition is not met. In this case, the motor doesn't move at all and the distance is put into the serial monitor. This works fine sometimes, but in most cases the serial monitor just prints 0 repeatedly and I have to restart the program for it to work again. Even when I put an object within 20cm of the sensor it still prints 0. I am quite new to Arduino so this really just stumped me haha. Any tips or help would be greatly appreciated.
#include <Servo.h>
Servo servo1; // create servo object to control a servo
#define trigPin 13
#define echoPin 12
void setup()
{
Serial.begin(9600);
servo1.attach(9); // attaches the servo on pin 9 to the servo object
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
}
void loop()
{
long duration = 0, distance = 0;
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
duration = pulseIn(echoPin, HIGH);
distance = (duration / 2) / 29.1;
if(distance > 2 && distance < 20){
servo1.write(180);
Serial.println(distance);
delay(1000);
servo1.write(-180);
}
else{
servo1.write(0);
Serial.println(distance);
}
delay(2000);
}
See what happens when you try this code, as I cleaned it up a little bit:
#include <Servo.h>
#define trigPin 13
#define echoPin 12
Servo servo1; // create servo object to control a servo
void setup() {
Serial.begin (9600);
servo1.attach(9); // attaches the servo on pin 9 to the servo object
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
}
void loop() {
float duration, distance;
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(10);
digitalWrite(trigPin, LOW);
duration = pulseIn(echoPin, HIGH);
distance = (duration / 2) * 29.1;
if (duration) {
if (distance > 2 && distance < 20) {
servo1.write(180);
Serial.println(distance);
delay(1000);
servo1.write(-180);
}
else {
servo1.write(0);
Serial.println(distance);
}
}
delay(2000);
}
I think if you use a float it might work. However, if it doesn't work, try switching up the pin assignments to different pins on the Arduino and see if that works. If the distance measurment is off the best way to adjust it is with the multiplied value in the distance variable in the void loop ().This one works for me.

Arduino Ultra Sonic Sensor always returns 0

I am doing a basic project in Arduino UNO connecting an Ultra Sonic sensor (HC-SR04) which should print in the serial monitor the distance of the closest object but it always print 0.
This is my code:
long distance;
long time;
void setup(){
Serial.begin(9600);
pinMode(4, OUTPUT);
pinMode(2, INPUT);
}
void loop(){
digitalWrite(2,LOW);
delayMicroseconds(5);
digitalWrite(2, HIGH);
delayMicroseconds(10);
time = pulseIn(4, HIGH);
distance = int(0.017*time);
Serial.print("Distance: ");
Serial.print(distance);
Serial.println(" cm.");
delay(1000);
}
And this is the breadboard:
The primary issue that I see is that your code doesn't match your wiring diagram.
For example, your diagram shows Trig connected to pin 4. The Trig should be the output from your Arduino but you have it defined as an input.
The Echo is connected to pin 2 and it should be an input, but you have it defined as an output.
Finally, in your loop(), you are not even using pin 2 or pin 4, but pins 9 and 8. Another issue is the timing you use in setting the trigger pulse - it does not match the datasheet. I would do something like this (assuming that you are actually connected to the pins shown in your diagram):
#define sensorTrigPin 4
#define sensorEchoPin 2
void setup()
{
Serial.begin(9600);
pinMode(sensorTrigPin, OUTPUT);
pinMode(sensorEchoPin, INPUT);
}
void loop()
{
int pulseWidth = 0;
digitalWrite(sensorTrigPin, HIGH);
delayMicroseconds(10);
digitalWrite(sensorTrigPin, LOW);
pulseWidth = pulseIn(sensorEchoPin, HIGH);
Serial.print("Pulse Width: ");
Serial.print(pulseWidth);
delay(1000);
}
Note that pulseWidth is just the amount of time that it takes from the beginning of the Echo pulse going high to the end of the same pulse (when it goes low). You would still have to calculate the distance based on the value of pulseWidth.
UPDATE BASED ON RECENT EDIT TO THE QUESTION
If you change a portion of your loop() code to this, it should work:
void loop(){
digitalWrite(4, HIGH); //was (2, LOW)
delayMicroseconds(10); //was (5)
digitalWrite(4, LOW); //was (2, HIGH)
//REMOVED EXTRA DELAY
time = pulseIn(2, HIGH); //was (4,HIGH);
... //Keep the rest of your code the same.
}
Try connecting your VCC of the sensor to 3V3 instead of 5V. This might sound odd, but I tried it and it worked well. Also, please make sure that your echo and trig pin match the code.

arduino Ultrasound srf05 wrong value

My Arduino board is Arduino Due ATmega328p. My Ultrasound is srf05.
I measure the distance is 5cm but my serial show me "531".Serial Monitor show the int of distance which value is always be 531.Why?
Here are the codes.
#define ECHOPIN 2 // Pin to receive echo pulse
#define TRIGPIN 3 // Pin to send trigger pulse
void setup(){
Serial.begin(9600);
pinMode(ECHOPIN, INPUT);
pinMode(TRIGPIN, OUTPUT);
}
void loop(){
digitalWrite(TRIGPIN, LOW); // Set the trigger pin to low for 2uS
delayMicroseconds(2);
digitalWrite(TRIGPIN, HIGH); // Send a 10uS high to trigger ranging
delayMicroseconds(10);
digitalWrite(TRIGPIN, LOW); // Send pin low again
int distance = pulseIn(ECHOPIN, HIGH); // Read in times pulse
distance = distance/58; // Calculate distance from time of pulse
Serial.println(distance);
delay(50); // Wait 50mS before next ranging
}
The srf05 times out if it doesn't receive the echo pulse. The width of the pulse is 30 ms.
30,000 / 58 is 517, which is close to 531. It looks like your device is not receiving an echo from the object. This makes your problem a hardware issue, and not a programming issue. (The code looks correct.)

Resources