2017-05-04 86 views
0

我想用超聲波傳感器測量距離,一切都很好,但是當我離開程序幾分鐘(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()中的一個循環中。在您的代碼中放置調試打印,以瞭解它卡住的位置。你應該在你的循環中放入超時,所以如果卡住了,你可以清理過程並重新開始。 –

回答

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) 
0

正確的方法找到這樣的原因很簡單使用記錄儀! 沒有黑匣子,你很難找到你的地方崩潰的原因!

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 
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完全返回(沒有任何對象,傳感器的不當行爲,錯誤連接...)
  • 或者也許ECHO已經是1當你等待它達到0(你正在做一個time.sleep(0.00001)後TRIGGER的上升沿。在這個時候,也許ECHO在某些情況下已經達到0 ...

如果這兩件事發生,你的程序將永遠等待,這可能是發生了什麼。 你應該在循環中加入一個超時值,所以如果「掛起」,你可以調用函數來再次觸發傳感器。

+0

所以,立即後,我應該把一個time.sleep(1)?在Whiles中?或者你的想法是什麼?非常感謝你的朋友! –

相關問題