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

时间:2017-05-04 10:58:54

标签: python measure

我正在尝试用超声波传感器测量距离,一切看起来都不错但是当我离开程序几分钟(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)

为什么程序会在几分钟后停止?非常感谢你

3 个答案:

答案 0 :(得分:1)

在您的函数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(没有对象,传感器的错误行为,错误连接......)
  • 或者当你等待它达到0时,ECHO已经是1(你在TRIGGER的上升沿之后做了一次time.sleep(0.00001)。在这个时候,ECHO在某些情况下可能已经达到0 ...

如果发生这两件事中的任何一件事,你的程序将永远等待,这可能就是发生的事情。 您应该在循环中包含超时,因此如果“挂起”,您可以调用该函数再次触发传感器。

答案 1 :(得分:0)

我最好的客人是你的代码上有个例外。请尝试此版本并添加输出示例:

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)

答案 2 :(得分:0)

找到原因的正确方法很简单使用LOGGER ! 没有黑盒子你几乎找不到你的地方崩溃的原因!!

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