简体   繁体   中英

Inaccurate results for arduino uno and ultrasonic sensor

Good day, I have the following code for an ultrasonic sensor that I'm using, but the result is not being accurate and I'd like to display the distance from the target in centimetres.

    #include <LiquidCrystal.h> //Load Liquid Crystal Library
LiquidCrystal LCD(10, 9, 5, 4, 3, 2);  //Create Liquid Crystal Object called LCD

int trigPin=13; //Sensor Trip pin connected to Arduino pin 13
int echoPin=11;  //Sensor Echo pin connected to Arduino pin 11
int myCounter=0;  //declare your variable myCounter and set to 0
int servoControlPin=6; //Servo control line is connected to pin 6
float pingTime;  //time for ping to travel from sensor to target and return
float targetDistance; //Distance to Target in inches
float speedOfSound=776.5; //Speed of sound in miles per hour when temp is 77 degrees.

void setup() {

Serial.begin(9600);
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);

LCD.begin(16,2); //Tell Arduino to start your 16 column 2 row LCD
LCD.setCursor(0,0);  //Set LCD cursor to upper left corner, column 0, row 0
LCD.print("Target Distance:");  //Print Message on First Row
}

void loop() {

  digitalWrite(trigPin, LOW); //Set trigger pin low
  delayMicroseconds(2000); //Let signal settle
  digitalWrite(trigPin, HIGH); //Set trigPin high
  delayMicroseconds(15); //Delay in high state
  digitalWrite(trigPin, LOW); //ping has now been sent
  delayMicroseconds(10); //Delay in high state

  pingTime = pulseIn(echoPin, HIGH);  //pingTime is presented in microceconds
  pingTime=pingTime/1000000; //convert pingTime to seconds by dividing by 1000000 (microseconds in a second)
  pingTime=pingTime/3600; //convert pingtime to hourse by dividing by 3600 (seconds in an hour)
  targetDistance= speedOfSound * pingTime;  //This will be in miles, since speed of sound was miles per hour
  targetDistance=targetDistance/2; //Remember ping travels to target and back from target, so you must divide by 2 for actual target distance.
  targetDistance= targetDistance*63360;    //Convert miles to inches by multipling by 63360 (inches per mile)

  LCD.setCursor(0,1);  //Set cursor to first column of second row
  LCD.print("                "); //Print blanks to clear the row
  LCD.setCursor(0,1);   //Set Cursor again to first column of second row
  LCD.print(targetDistance); //Print measured distance
  LCD.print(" inches");  //Print your units.
  delay(250); //pause to let things settle


  }  

I will appreciate any help.

You are performing a lot of floating point calculations on every iteration of your loop . Rather than performing these calculations you can pre-compute a single multiplier that will convert the pingTime to a distance in centimetres.

First we need to calculate the metric speed of sound from your 776.5 mph.

776.5 miles/hour * 1609.34 (meters in a mile) = 1249652.51 metres/hour

1249652.51 metres/hour / 3600 = 347.126 metres/second

So we can precompute a multiplier as follows:

float speedOfSound = 347.126; // metres per second
float speedOfSound_cm_p_us = speedOfSound * 100 / 1000000; // speedOfSound in centimetres per microsecond

Obviously, this could be reduced to simply:

float speedOfSound_cm_p_us = 0.0347126; // cm per microsecond

Next we can precompute the multiplier by dividing speedOfSound_cm_p_us by 2 as the sound has to travel to the reflective surface and back again.

float pingTime_multiplier = speedOfSound_cm_p_us / 2; // The sound travels there and back so divide by 2.

Again, we could simply replace this step with:

float pingTime_multiplier = 0.0173563;

However, this magic number should be well documented in your code.

Once we have pingTime_multiplier calculated the loop function becomes much simpler. Simply multiply the pingTime by the pingTime_multiplier to get the distance in centimetres.

pingTime = pulseIn(echoPin, HIGH);  // pingTime is presented in microseconds
targetDistance = pingTime * pingTime_multiplier;

This significantly reduces the amount of work that the Arduino has to do each time through the loop.

I'd like to display the distance from the target in centimetres.

Google says an inch is 2.54 cm, so just multipy your result by this.

the result is not being accurate

For more accurate results, take an average of a number of samples (3 or more), and you could implement some heuristics which discard grossly over/under range results.

Say if three readings are around 0-5cm apart, then a fourth reading 40cm away is most likely an error. So just do the average of the three similar results.

Convert inches to centimeters by multiplying by 2.54

float targetDistanceCentimeters = targetDistance*2.54;

Your code looks correct, so my guess is that this is a hardware problem. In my experience ultra sound sensors are typically quite bad at measuring distance to any object that is not a wall or other large object with relatively flat surface. So if you want to test the accuracy of your system, test it against such object ie wall or book. If your sensor is moving while making the measurements make sure that it is not moving too fast. If you are measuring distance to small or thin object you will need to filter and take the average of the measurements. It's all up to you how accurate you want to be, I'd say that average of twenty or so of filtered measurements will give you appropriate result.

Another things to consider is that you have the correct supply voltage and that the sensor is not directed against the floor at some angle, as this might give unwanted reflections.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM