Ultrasonic sensor Makes a lot of delays

Hello,

I hope you're doing well. I'm working on a firefighter robot project and have encountered an issue. While the robot successfully senses black lines and moves correctly, enabling the ultrasonic sensor introduces a delay. This delay disrupts the black line sensing and causes the robot's movement to be inaccurate. Below is my code. I appreciate any assistance you can provide. Thank you!


int s1 = 7;  //Sensor1 ==> pin7
int s2 = 3;  //Sensor2 ==> Pin3
int s3 = 4;  //Sensor3 ==> Pin4
int s4 = 5;  //Sensor4 ==> Pin5
int s5 = 6;  //Sensor5 ==> Pin6

// Motor & L298
//Channel A
int IN1 = 8;  // IN1 ==> Pin8
int IN2 = 9;  // IN2 ==> Pin9
int ENA = 10; // Enable A ==> Pin10

//Channel B
int IN3 = 12; // IN3 ==> 12
int IN4 = 13; // IN4 ==> 13
int ENB = 11; // Enable B ==> Pin11

// default motors speed 
int MotorSpeedA=0;
int MotorSpeedB=0;

//UltraSonic SRF04
int PingPin = 2; // TrigPin ==> Pin2
int EchoPin = A0; // EchoPin ==> A0
unsigned long duration, cm;

void setup(){
    //Activate Serial Monitor
//    Serial.begin(9900);
    Serial.begin(9600);
    
    //Sensor Setting
    pinMode(s1, INPUT);
    pinMode(s2, INPUT);
    pinMode(s3, INPUT);
    pinMode(s4, INPUT);
    pinMode(s5, INPUT);

    //L298 Setting
    //Channel A  Motor in Right Side
    pinMode(IN1, OUTPUT);
    pinMode(IN2, OUTPUT);
    pinMode(ENA, OUTPUT);
    digitalWrite(ENA,LOW);
    
    //Channel B  Motor in Left Side
    pinMode(IN3, OUTPUT);
    pinMode(IN4, OUTPUT);
    pinMode(ENB, OUTPUT);
    digitalWrite(ENA,LOW);

    // UltraSonic
    pinMode(PingPin, OUTPUT);
    pinMode(EchoPin, INPUT);
}

//Function for Moving Forward
void MoveForward(){
    MotorSpeedA= 110;
    MotorSpeedB= 130;
    
    digitalWrite(IN1,LOW);
    digitalWrite(IN2,HIGH);

    digitalWrite(IN3,LOW);
    digitalWrite(IN4,HIGH);

    analogWrite(ENA,MotorSpeedA);
    analogWrite(ENB,MotorSpeedB);
}

//function for Moving BackWard
void MoveBackWard(){
    MotorSpeedA= 60;
    MotorSpeedB= 80;

    digitalWrite(IN1,HIGH);
    digitalWrite(IN2,LOW);

    digitalWrite(IN3,HIGH);
    digitalWrite(IN4,LOW);

    analogWrite(ENA,MotorSpeedA);
    analogWrite(ENB,MotorSpeedB); 
}

// Function for stop 
void Stop(){
    MotorSpeedA= 0;
    MotorSpeedB= 0;
    
    digitalWrite(IN1,LOW);
    digitalWrite(IN2,LOW);

    digitalWrite(IN3,LOW);
    digitalWrite(IN4,LOW);

    analogWrite(ENA,MotorSpeedA);
    analogWrite(ENB,MotorSpeedB); 
}

// Function for Turning Robot to left
void TurnLeft(){
    digitalWrite(IN1,LOW);
    digitalWrite(IN2,HIGH);

    digitalWrite(IN3,HIGH);
    digitalWrite(IN4,LOW);

    MotorSpeedA = 60;
    MotorSpeedB = 80;

    analogWrite(ENA,MotorSpeedA);
    analogWrite(ENB,MotorSpeedB);
}

// Function For Turning Robot to Right
void TurnRight(){
    digitalWrite(IN1,HIGH);
    digitalWrite(IN2,LOW);

    digitalWrite(IN3,LOW);
    digitalWrite(IN4,HIGH);

    MotorSpeedA = 60;
    MotorSpeedB = 80;

    analogWrite(ENA,MotorSpeedA);
    analogWrite(ENB,MotorSpeedB);
}

// read sensors
boolean sens1,sens2,sens3,sens4,sens5; // Variables for Sensor
int SensorDigitalRead(){
    sens1 = digitalRead(s1);
    sens2 = digitalRead(s2);
    sens3 = digitalRead(s3);
    sens4 = digitalRead(s4);
    sens5 = digitalRead(s5);

    return sens1,sens2,sens3,sens4,sens5;
}

// Print Sensors Value on Screen
void SensorPrint(){
////    Serial.prnt("S1= \n");
////    Serial.print(sens1);
////    Serial.print(" S2= \n");
////    Serial.print(sens2);
////    Serial.print(" S3= \n");
////    Serial.print(sens3);
////    Serial.print(" S4= \n");
////    Serial.print(sens4);
////    Serial.print(" S5= \n");
////    Serial.print(sens5);
      Serial.println(cm);
      delay(10);
}

void loop(){
    
    SensorDigitalRead();

    if (UltraSonic() == true){
      Stop();
    }

    else if (sens1 && sens2 && sens3 && sens4 && sens5){
      Stop();
    }

    else if (sens3 && sens5){
      Stop();
    }
    
    // go ahead
    else if(sens1 || sens1 && (sens2 || sens3 || sens4 || sens5)){
        MoveForward();
    }
    
    else if((!sens1 && (sens2 || sens3 ))){
        TurnLeft();
    }

    else if((!sens1 && (sens4 || sens5))){
        TurnRight();
    }

    else if(!sens1 && !sens2 && !sens3 && !sens4 && !sens5){
        MoveBackWard();
    }
}



bool UltraSonic(){
    digitalWrite(PingPin,LOW);
    delayMicroseconds(2);
    digitalWrite(PingPin,HIGH);
    delayMicroseconds(5);
    digitalWrite(PingPin, LOW);
     
    duration = pulseIn(EchoPin, HIGH); // Measure Time of Fligh in Micro Secondes
    cm = MicroStoCm(duration);

    if (cm < 10) {
      return true;
    }
    else{
      return false;
    } 
 }

//Function For Convert MicroSecondes to Centimeter
unsigned long MicroStoCm(unsigned long MicroS){
    return (MicroS/29)/2;
}

if there is no obstacle pulseIn() will lag for one second creating the issue you see.

consider using the NewPing - Arduino Reference library which has been written to take this issue into account.

2 Likes

Please explain.

luckily enough they are global variables and OP is not using the return value.

couldn't the pulseIn() timeout argument be specified to speed things up. a value of 100 (msec) should be more than enough time to detect something within 50 ft. less time could be specified

Sure that’s an option too but 100ms is a long time (depending what the rest of the code does)

how about 20 msec for within 10'?

Please check the HCSR04 just with a basic code. No other component. Only Arduino ,HCSR04 and the basic distance measurement code.

1 Like

and don't forget that time must be allotted after each ping and before the next to allow the ping to dissipate to avoid interfering with the next ping

If you read the link to pulseIn that gcjr gave us, then you will find out that the 'timeout' that can be specified is the time spent waiting for the pulse to start.

Quoted from that link:

timeout (optional): the number of microseconds to wait for the pulse to start; default is one second. Allowed data types: unsigned long .

It is not the width of the received pulse, so it can be set much shorter.

Have a look at these oscilloscope traces for distances of 1metre, and 10cm:


target at 1m.


target at 10cm.

In both cases the echo pulse begins approximately 500µs after the trigger pulse. So the timeout could be set as low as 1ms (1000µs).

Returns the length of the pulse in microseconds or gives up and returns 0 if no complete pulse was received within the timeout.

That link has some conflicting information:

Returns
The length of the pulse (in microseconds) or 0 if no pulse started before the timeout. Data type: unsigned long.

Returns the length of the pulse in microseconds or gives up and returns 0 if no complete pulse was received within the timeout.

what it does with and without a timeout parameter

i don't think it's the length of the pulse, that's determined by the code, it's the length to time until it detects the pulse

Going asynchronous is great

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.