用超声波传感器和覆盆子测量距离

问题描述:

我想用超声波传感器测量距离,一切都很好,但是当我离开程序几分钟(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) 

为什么有些分钟后程序停止?非常感谢你

+0

你能显示一个输出的例子吗? – VMRuiz

+0

为什么你只是不使用记录器 –

+0

你是什么意思的“程序停止测量距离?”程序是否终止或者它在不测量距离的情况下继续执行?如果是后者,那么可能会陷入函数medida()中的一个循环中。在您的代码中放置调试打印,以了解它卡住的位置。你应该在你的循环中放入超时,所以如果卡住了,你可以清理过程并重新开始。 –

我最好的客人是你的代码上有个例外。请试试这个版本,并添加输出的一个例子:

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中?或者你的想法是什么?非常感谢你的朋友! –