Неточные результаты для arduino uno и ультразвукового датчика

Добрый день, у меня есть следующий код для ультразвукового датчика, который я использую, но результат неточный, и я хотел бы отобразить расстояние от цели в сантиметрах.

    #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


  }  

Буду признателен за любую помощь.


person Empire Drcongo    schedule 26.05.2016    source источник


Ответы (3)


Преобразуйте дюймы в сантиметры, умножив на 2,54

float targetDistanceCentimeters = targetDistance*2.54;

Ваш код выглядит правильно, поэтому я предполагаю, что это проблема с оборудованием. По моему опыту, ультразвуковые датчики обычно плохо измеряют расстояние до любого объекта, кроме стены или другого большого объекта с относительно плоской поверхностью. Поэтому, если вы хотите проверить точность своей системы, проверьте ее на таком предмете, как стена или книга. Если ваш датчик движется во время измерения, убедитесь, что он не движется слишком быстро. Если вы измеряете расстояние до небольшого или тонкого объекта, вам необходимо отфильтровать и получить среднее значение измерений. Все зависит от вас, насколько точными вы хотите быть. Я бы сказал, что в среднем двадцать или около того отфильтрованных измерений дадут вам соответствующий результат.

Также следует учитывать, что у вас правильное напряжение питания и что датчик не направлен на пол под каким-то углом, так как это может привести к нежелательным отражениям.

person NoobPointerException    schedule 27.05.2016

Вы выполняете много вычислений с плавающей запятой на каждой итерации вашего loop. Вместо того, чтобы выполнять эти вычисления, вы можете предварительно вычислить единственный множитель, который преобразует pingTime в расстояние в сантиметрах.

Сначала нам нужно рассчитать метрическую скорость звука для ваших 776,5 миль в час.

776,5 миль / час * 1609,34 (метры в миле) = 1249652,51 метра / час

1249652,51 метра / час / 3600 = 347,126 метра / секунду

Итак, мы можем предварительно вычислить множитель следующим образом:

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

Очевидно, это можно свести к простому:

float speedOfSound_cm_p_us = 0.0347126; // cm per microsecond

Затем мы можем предварительно вычислить множитель, разделив speedOfSound_cm_p_us на 2, поскольку звук должен пройти к отражающей поверхности и обратно.

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

Опять же, мы могли бы просто заменить этот шаг на:

float pingTime_multiplier = 0.0173563;

Однако это магическое число должно быть хорошо задокументировано в вашем коде.

Как только мы pingTime_multiplier вычислили, loop функция становится намного проще. Просто умножьте pingTime на pingTime_multiplier, чтобы получить расстояние в сантиметрах.

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

Это значительно сокращает объем работы, которую Arduino должен выполнять каждый раз при прохождении цикла.

person mttrb    schedule 27.05.2016
comment
четкое объяснение, спасибо, я также перенастрою мое оборудование - person Empire Drcongo; 29.05.2016

Я хочу отображать расстояние до цели в сантиметрах.

Google говорит, что дюйм равен 2,54 см, поэтому просто умножьте полученный результат на это.

результат не точен

Для получения более точных результатов возьмите среднее количество выборок (3 или более), и вы можете реализовать некоторые эвристики, которые отбрасывают результаты, явно превышающие / заниженные.

Скажем, если три показания находятся на расстоянии 0-5 см друг от друга, то четвертое показание на расстоянии 40 см, скорее всего, будет ошибкой. Так что просто сделайте среднее из трех похожих результатов.

person Chris A    schedule 27.05.2016