[英]Inaccurate results for arduino uno and ultrasonic sensor
美好的一天,我有一個下面的代碼用於我正在使用的超聲波傳感器,但結果並不准確,我想以厘米為單位顯示距目標的距離。
#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
}
我將不勝感激。
您對您的每次迭代進行大量的浮點運算的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厘米的第四個讀數很可能是一個錯誤。 因此,只需對三個相似結果進行平均即可。
乘以2.54將英寸轉換為厘米
float targetDistanceCentimeters = targetDistance*2.54;
您的代碼看起來正確,所以我的猜測是這是硬件問題。 以我的經驗,超聲波傳感器通常很難測量到與不是牆壁的其他物體或具有相對平坦表面的其他物體的距離。 因此,如果要測試系統的准確性,請針對諸如牆或書本之類的物體進行測試。 如果您的傳感器在測量時正在移動,請確保它的移動速度不太快。 如果要測量到小物體或薄物體的距離,則需要過濾並取平均值。 這完全取決於您要達到的精度,我想說,平均大約二十次過濾后的測量將為您提供適當的結果。
要考慮的另一件事是,您具有正確的電源電壓,並且傳感器沒有以一定角度對准地板,因為這可能會產生不必要的反射。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.