Неточные результаты для 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


  }  

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

3 ответа

Решение

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

float targetDistanceCentimeters = targetDistance*2.54;

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

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

Вы выполняете много вычислений с плавающей запятой на каждой итерации вашего 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 должен выполнять каждый раз в цикле.

Я хотел бы отобразить расстояние от цели в сантиметрах.

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

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

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

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

Другие вопросы по тегам