python - 超声波范围传感器 (HC-SR04) 在 Raspberry Pi 上给出不一致的读数
问题描述
我目前正在我的树莓派上研究超声波传感器(和温度,但这对这个问题并不重要),由于空间限制我无法使用面包板,这就是我设置它的方式。我以前在 Arduino 上使用过超声波传感器,它工作得非常好,但我是树莓和 python 编码的新手,所以如果我正在做的事情有任何问题,请纠正我。
编辑
是的,我确实将电阻器焊接到了它自己的 Raspberry Pi 上,因为该板仅用于此功能。
下面是我用来计算距离的脚本,它读取最后 10 个值并计算所述值的平均值。
import RPi.GPIO as GPIO
import time, sys
import statistics
GPIO.setmode(GPIO.BCM)
log=__import__("logger")
TRIG = 23
ECHO = 24
log.log("Settng up Distance module...","distance.py")
GPIO.setup(TRIG,GPIO.OUT)
GPIO.setup(ECHO,GPIO.IN)
history=[]
total=0
count=0
distance=0
avg=0
dist=[]
distlist=[]
scan=False
GPIO.setmode(GPIO.BCM)
TRIG = 23
ECHO = 24
GPIO.setup(TRIG,GPIO.OUT)
GPIO.setup(ECHO,GPIO.IN)
def status():
history=[]
starttime=time.time()
for i in range(10):
GPIO.output(TRIG, False)
time.sleep(0.1)
#print("Waiting for sensor to settle...")
#print("Please wait...")
# ==========
# GPIO Setup
# ==========
GPIO.output(TRIG, True)
time.sleep(0.00001)
GPIO.output(TRIG, False)
#print("Sending...")
start=time.time()
pulse_start=start
while GPIO.input(ECHO)==0 and pulse_start-start<=0.0005:
pulse_start=time.time()
if round(pulse_start-start,3)>=0.300:
print(timeout)
else:
#print("Receiving...")
pulse_end=0
pulse_duration=0
while GPIO.input(ECHO)==1 and pulse_duration<2:
pulse_end=time.time()
pulse_duration=pulse_end-pulse_start
#print("Measuring...")
pulse_duration=pulse_end-pulse_start
# ====================
# Calculating Distance
# ====================
distance=pulse_duration*17150
distance=round(distance,2)
history.append(distance)
validcount=0
total=0
print(history)
for i in history:
if i<150:
validcount+=1
total+=i
if validcount>1:
avg_dist=round(total/validcount,2)
print("Average distance:",avg_dist)
if avg_dist<=50:
return([avg_dist,True,avg_dist,avg_dist])
else:
return([avg_dist,False,avg_dist,avg_dist])
else:
print("Timeout")
return([999,False,999,999])
while True: print(status()); time.sleep(1)
以下是我站在传感器附近时从传感器获得的读数。
Average distance: -4590081542678.66
[-4590081542678.66, True, -4590081542678.66, -4590081542678.66]
[185.12, 341.6, 17.71, 188.05, 185.94, 185.55, 188.08, 185.58, 184.6, 185.09]
Timeout
[999, False, 999, 999]
[185.58, 186.09, 185.2, 184.4, 185.11, 185.6, 185.56, 186.47, 186.81, 187.24]
Timeout
[999, False, 999, 999]
[187.71, 186.07, 185.59, 185.6, 185.12, 185.61, 185.56, 186.83, 186.41, 184.68]
Timeout
[999, False, 999, 999]
[2243.37, 2245.42, 22.79, 24.57, 2245.48, 2243.77, 2245.33, 2245.12, 2245.18, 2245.28]
Average distance: 23.68
[23.68, True, 23.68, 23.68]
[2244.04, 2246.04, 348.54, 348.56, 348.58, 349.46, 349.44, 348.51, 350.32, 348.05]
Timeout
[999, False, 999, 999]
[348.65, 104.17, 103.76, 100.39, 348.94, 99.49, 348.99, 348.5, 348.14, 348.59]
Average distance: 101.95
[101.95, False, 101.95, 101.95]
[2244.2, 2245.87, 2246.03, 2246.21, 2243.82, 2246.09, 2245.4, 2245.17, 2245.98, 2245.81]
Timeout
[999, False, 999, 999]
[2243.19, 2245.8, 2245.89, 2245.82, 2245.66, 2245.76, 2245.65, 2245.69, 2245.58, 2245.89]
Timeout
[999, False, 999, 999]
[2242.55, 2245.85, 25.14, 24.11, 23.9, 23.2, 2243.35, 2246.04, 2246.33, 2245.93]
Average distance: 24.09
[24.09, True, 24.09, 24.09]
[2243.13, 19.03, 18.33, 17.64, 2246.25, 2244.32, 2245.29, 2245.44, 2245.78, 2246.06]
Average distance: 18.33
[18.33, True, 18.33, 18.33]
[2242.59, 2245.8, 2245.47, 2245.62, 2245.73, 2245.8, 2245.86, 2246.05, 2246.22, 2245.91]
Timeout
[999, False, 999, 999]
[2243.81, 2246.36, 2246.1, 2246.07, 2246.09, 2246.05, 2246.13, 2245.92, 2246.07, 2246.3]
Timeout
[999, False, 999, 999]
[2243.94, 2246.02, 2246.03, 2246.21, 2246.15, 2245.89, 2245.9, 2245.99, 2245.96, 2245.99]
Timeout
[999, False, 999, 999]
[2242.87, 2245.97, 18.78, 17.93, 17.81, 2243.93, 2246.01, 2245.86, 2245.95, 2246.04]
Average distance: 18.17
因此,我的程序所做的是从传感器中获取最后 10 位数字并计算列表中该值的平均值,但正如您所见,即使我站在它附近,读数也超过了 THOUSANDS 的范围。
我知道距离传感器 (HC-SR04) Recording Inconsistent Values page 这个问题,虽然它确实让我了解了这个问题,但不幸的是没有找到解决方案。但我推测问题在于脉冲触发时间过长6 秒导致链接页面中提到的高值,但我不确定这是否是唯一的问题或如何解决它。
我将不胜感激任何反馈、建议或回答。先感谢您。
解决方案
因此,在我进行了一些故障排除后,我发现我的电阻器上的焊料没有正确焊接到树莓派板上,所以我在给它适当的焊料后,它现在给出了一致的读数,但是高价值的问题确实没变。它仍然会提供高价值,所以我解决这个问题的方法是使用过滤器来过滤掉高价值。
for i in history:
if i<150:
validcount+=1
total+=i
if validcount>1:
avg_dist=round(total/validcount,2)
print("Average distance:",avg_dist)
if avg_dist<=50:
return([avg_dist,True,avg_dist,avg_dist])
else:
return([avg_dist,False,avg_dist,avg_dist])
else:
print("Timeout")
return([999,False,999,999])
并通过加快读取数据的速度。
for i in range(10):
GPIO.output(TRIG, False)
time.sleep(0.1)
#print("Waiting for sensor to settle...")
#print("Please wait...")
# ==========
# GPIO Setup
# ==========
GPIO.output(TRIG, True)
time.sleep(0.00001) #lowered the delay on the reading
GPIO.output(TRIG, False)
#print("Sending...")
start=time.time()
pulse_start=start
while GPIO.input(ECHO)==0 and pulse_start-start<=0.0005:
pulse_start=time.time()
if round(pulse_start-start,3)>=0.300:
print(timeout)
else:
#print("Receiving...")
pulse_end=0
pulse_duration=0
while GPIO.input(ECHO)==1 and pulse_duration<2:
pulse_end=time.time()
pulse_duration=pulse_end-pulse_start
#print("Measuring...")
pulse_duration=pulse_end-pulse_start
# ====================
# Calculating Distance
# ====================
distance=pulse_duration*17150
distance=round(distance,2)
这有效地提供了更快的读取速度,如果出现一个有效值,它将忽略所有突然的高值。我希望这有助于其他有同样问题的人。