用超声波传感器和覆盆子测量距离
问题描述:
我想用超声波传感器测量距离,一切都很好,但是当我离开程序几分钟(3-4分钟)工作时,程序停止测量距离。用超声波传感器和覆盆子测量距离
我需要程序不会停止,因为我需要它来安全警报。该程序每隔一秒收集一段距离并在scree中显示。但是,如果距离大于10,则程序会显示警告消息,并且不显示的距离,直到它的10少跟着你可以看到代码:
import time
import RPi.GPIO as GPIO
# Usamos la referencia BOARD para los pines GPIO
GPIO.setmode(GPIO.BOARD)
# Definimos los pines que vamos a usar
GPIO_TRIGGER = 11
GPIO_ECHO = 13
GPIO_LED = 15
# Configuramos los pines como entradas y salidas
GPIO.setup(GPIO_TRIGGER,GPIO.OUT) # Trigger
GPIO.setup(GPIO_ECHO,GPIO.IN) # Echo
GPIO.setup(GPIO_LED ,GPIO.OUT) #Led
# -----------------------
# Definimos algunas funciones
# -----------------------
def medida():
# Esta funcion mide una distancia
GPIO.output(GPIO_TRIGGER, True)
time.sleep(0.00001)
GPIO.output(GPIO_TRIGGER, False)
start = time.time()
while GPIO.input(GPIO_ECHO)==0:
start = time.time()
while GPIO.input(GPIO_ECHO)==1:
stop = time.time()
elapsed = stop-start
distancia = (elapsed * 34300)/2
return distancia
def media_distancia():
# Esta funcion recoge 3 medidas
# y devuelve la media de las 3.
distancia1=medida()
time.sleep(0.1)
distancia2=medida()
time.sleep(0.1)
distancia3=medida()
distancia = distancia1 + distancia2 + distancia3
distancia = distancia/3
return distancia
# -----------------------
# Programa principal
# -----------------------
print ("Medida con sensor de ultrasonidos")
# Ponemos el Trigger en falso (low)
GPIO.output(GPIO_TRIGGER, False)
# Ponemos el Led en falso (low)
GPIO.output(GPIO_LED, False)
# Metemos el bloque principal en un Try para asi poder
# comprobar si el usuario presiona Ctrl + C
# y poder ejecutar una limpieza del GPIO, esto tambien
# evita el usuario tener que ver muchos mensajes de error
try:
while True: # Este bucle se repite siempre
# Lo primero que hago es medir la distancia
distancia = media_distancia()
# Compruebo si la distancia es menor que 10
# Si es menor que 10 muestro la distancia por pantalla
if distancia < 10:
distancia = media_distancia() # Medidos la distancia
print ("Distancia: %.1f" % distancia, " - " , "Fecha:", time.strftime("%c")) # Mostramos la distancia por pantalla
GPIO.output(GPIO_LED, False)
time.sleep(1) # Esperamos 1 segundo
distancia = media_distancia()
a = 0 # Utilizo la variable a para poder para el proceso mas adelante
# Pregunto si la variable a es igual a 1
# Si lo es no hago nada y repito el if anterior
if a == 1:
pass
# Pero si no es 1 le asigno el valor 0
# Para poder seguir con el IF siguiente
else:
a = 0
if distancia > 10 and a == 0: # Si la distancia es mayor que 10cms
print ("La distancia es mayor de 10 cms. Alarma activada!!", " - ", "Fecha:", time.strftime("%c")) # Se interrumpe el bucle y se muestra un aviso
GPIO.output(GPIO_LED, True)
a = 1 # Pongo la variable en 1 para parar el proceso y que no se repita
distancia = media_distancia() # Seguimos midiento la distancia
while distancia < 10: # Pero si la distancia vuelve a ser menor de 10
break # Se termina este bucle y volvemos al principio nuevamente
except KeyboardInterrupt: # Si el usuario presiona crtl + C
# Limpiamos los pines GPIO y salimos del programa
print ("Apagando LED")
time.sleep(1)
GPIO.output(GPIO_LED, False)
print ("Limpiando GPIO")
GPIO.cleanup()
print ("GPIO limpio")
print ("Saliendo...")
time.sleep(1)
为什么有些分钟后程序停止?非常感谢你
答
我最好的客人是你的代码上有个例外。请试试这个版本,并添加输出的一个例子:
import time
import RPi.GPIO as GPIO
# Usamos la referencia BOARD para los pines GPIO
GPIO.setmode(GPIO.BOARD)
# Definimos los pines que vamos a usar
GPIO_TRIGGER = 11
GPIO_ECHO = 13
GPIO_LED = 15
# Configuramos los pines como entradas y salidas
GPIO.setup(GPIO_TRIGGER,GPIO.OUT) # Trigger
GPIO.setup(GPIO_ECHO,GPIO.IN) # Echo
GPIO.setup(GPIO_LED ,GPIO.OUT) #Led
# -----------------------
# Definimos algunas funciones
# -----------------------
def medida():
# Esta funcion mide una distancia
GPIO.output(GPIO_TRIGGER, True)
time.sleep(0.00001)
GPIO.output(GPIO_TRIGGER, False)
start = time.time()
while GPIO.input(GPIO_ECHO)==0:
start = time.time()
while GPIO.input(GPIO_ECHO)==1:
stop = time.time()
elapsed = stop-start
distancia = (elapsed * 34300)/2
return distancia
def media_distancia():
# Esta funcion recoge 3 medidas
# y devuelve la media de las 3.
distancia1=medida()
time.sleep(0.1)
distancia2=medida()
time.sleep(0.1)
distancia3=medida()
distancia = distancia1 + distancia2 + distancia3
distancia = distancia/3
return distancia
# -----------------------
# Programa principal
# -----------------------
print ("Medida con sensor de ultrasonidos")
# Ponemos el Trigger en falso (low)
GPIO.output(GPIO_TRIGGER, False)
# Ponemos el Led en falso (low)
GPIO.output(GPIO_LED, False)
# Metemos el bloque principal en un Try para asi poder
# comprobar si el usuario presiona Ctrl + C
# y poder ejecutar una limpieza del GPIO, esto tambien
# evita el usuario tener que ver muchos mensajes de error
continuar = True
while continuar: # Este bucle se repite siempre
try:
# Lo primero que hago es medir la distancia
distancia = media_distancia()
# Compruebo si la distancia es menor que 10
# Si es menor que 10 muestro la distancia por pantalla
if distancia < 10:
distancia = media_distancia() # Medidos la distancia
print ("Distancia: %.1f" % distancia, " - " , "Fecha:", time.strftime("%c")) # Mostramos la distancia por pantalla
GPIO.output(GPIO_LED, False)
time.sleep(1) # Esperamos 1 segundo
distancia = media_distancia()
a = 0 # Utilizo la variable a para poder para el proceso mas adelante
# Pregunto si la variable a es igual a 1
# Si lo es no hago nada y repito el if anterior
if a == 1:
pass
# Pero si no es 1 le asigno el valor 0
# Para poder seguir con el IF siguiente
else:
a = 0
if distancia > 10 and a == 0: # Si la distancia es mayor que 10cms
print ("La distancia es mayor de 10 cms. Alarma activada!!", " - ", "Fecha:", time.strftime("%c")) # Se interrumpe el bucle y se muestra un aviso
GPIO.output(GPIO_LED, True)
a = 1 # Pongo la variable en 1 para parar el proceso y que no se repita
distancia = media_distancia() # Seguimos midiento la distancia
while distancia < 10: # Pero si la distancia vuelve a ser menor de 10
break # Se termina este bucle y volvemos al principio nuevamente
except KeyboardInterrupt: # Si el usuario presiona crtl + C
continuar = False
except (Exception) as error:
print (str(error))
# Limpiamos los pines GPIO y salimos del programa
print ("Apagando LED")
time.sleep(1)
GPIO.output(GPIO_LED, False)
print ("Limpiando GPIO")
GPIO.cleanup()
print ("GPIO limpio")
print ("Saliendo...")
time.sleep(1)
答
正确的方法找到这样的原因很简单使用记录仪! 没有黑匣子,你很难找到你的地方崩溃的原因!
Python有一个准备使用,检查doc
进口记录器模块:
import logging
配置它来创建一个文件...
logging.basicConfig(filename='example.log',level=logging.DEBUG)
和乞讨登录你发现每一个地方都有可疑
logging.warning('Watch out!') # will print a message to the console
logging.info('I told you so') # will not print anything
答
在你的函数medida():
你触发使用传感器:
GPIO.output(GPIO_TRIGGER, True)
time.sleep(0.00001)
GPIO.output(GPIO_TRIGGER, False)
然后等待该ECHO设置为0开始计算时间,终于等待ECHO设置为1,停止计时
while GPIO.input(GPIO_ECHO)==0:
start = time.time()
while GPIO.input(GPIO_ECHO)==1:
stop = time.time()
现在想象一下,这个任意两个转变的情况不会发生:
- 也许ECHO永远不会获取1,因为没有ECHO完全返回(没有任何对象,传感器的不当行为,错误连接...)
- 或者也许ECHO已经是1当你等待它达到0(你正在做一个time.sleep(0.00001)后TRIGGER的上升沿。在这个时候,也许ECHO在某些情况下已经达到0 ...
如果这两件事发生,你的程序将永远等待,这可能是发生了什么。 你应该在循环中加入一个超时值,所以如果“挂起”,你可以调用函数来再次触发传感器。
+0
所以,立即后,我应该把一个time.sleep(1)?在Whiles中?或者你的想法是什么?非常感谢你的朋友! –
你能显示一个输出的例子吗? – VMRuiz
为什么你只是不使用记录器 –
你是什么意思的“程序停止测量距离?”程序是否终止或者它在不测量距离的情况下继续执行?如果是后者,那么可能会陷入函数medida()中的一个循环中。在您的代码中放置调试打印,以了解它卡住的位置。你应该在你的循环中放入超时,所以如果卡住了,你可以清理过程并重新开始。 –