Measure distance with ultrasonic sensor and Raspberry - python

I am trying to measure a distance with ultrasonic sensor and everything looks well but when I leave the program for a some minutes (3-4 minutes) working, the program stops the measure of distance.
I need that the program dont stops because I need it to a security alarm. The program collects every one second a distance and show it in scree. But if distance is more than 10, the program shows a alert message and dont show the distance until it is less of 10. Following you can see the code:
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)
Why does the program stops after some minutes?

In your function medida(): you are triggering the sensor using:
GPIO.output(GPIO_TRIGGER, True)
time.sleep(0.00001)
GPIO.output(GPIO_TRIGGER, False)
Then waiting that the ECHO sets to 0 to start counting time and finally waiting the ECHO to set to 1 to stop counting time
while GPIO.input(GPIO_ECHO)==0:
start = time.time()
while GPIO.input(GPIO_ECHO)==1:
stop = time.time()
Now imagine that any of this two transitions doesn't happen:
maybe the ECHO never gets to 1 because there's no ECHO returned at all (no object, misbehavior of the sensor, misconnection...)
or maybe the ECHO is already 1 when you wait for it to get to 0 (you are doing a time.sleep(0.00001) after the rising edge of TRIGGER. In this time maybe the ECHO already gets to 0 in some cases...
If any of this two things happen, your program will wait forever, which is probably what is happening.
You should include a timeout in your loops, so if thins "hang" you can call the function to trigger the sensor again.

My best guest is that there is an exception somewhere on your code. Please, try this version and add an example of the output:
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)

The correct way to find the reason of such is simple USE A LOGGER!
without blackbox you will hardly find the reason why your place crash!!
python has one ready to use, check the doc
import the logger module:
import logging
configure it to create a file...
logging.basicConfig(filename='example.log',level=logging.DEBUG)
and begging to log on every spot you find suspicious
logging.warning('Watch out!') # will print a message to the console
logging.info('I told you so') # will not print anything

Related

Make a Menu using Match Case Python

I have created another MENU in a different exercise using IF in this time I did it with MATCH CASE and I have a doubt, is it possible to print the menu again and if it is possible how I would do it, I think in an if but it is the first time that I use these sentences.
this is my code:
...Later i need to work with dictionaries so with this method can do it?, or I need to use IF to create the menu from the beginning?
menu = """
1. Datos del pasajero.
2. Agrega una ciudad.
3. Ingresa DNI para ver las ciudades que coinciden con el dato.
4. Escribe una ciudad para ver el # de pasajeros.
5. Ingresa DNI para ver los paises que coinciden con el dato.
6. Ingresa un pais y mostrar el total de personas que viajan.
7. Terminar el programa
"""
viajeros = {}
paises = {}
print(menu)
dato_leido = int(input('Escriba una opcion para comenzar con el programa: '))
match dato_leido:
case 1:
print('Escriba los datos del pasajero: ')
case 2:
print('Agrega una ciudad a la lista:')
case 3:
print('Ingresa el DNI del pasajero para ver a que ciudad ha viajado: ')
case 4:
print('Ingrese una ciudad para ver el numero de pasajeros: ')
case 5:
print('Ingresa el DNI de una persona para ver a que paises viaja: ')
case 6:
print('Ingresa un pais y mostrar el total de personas que viajan: ')
case _:
print('Saliendo del programa en 3, 2, 1(FIN).')

i don't know why happens this: AttributeError: 'NoneType' object has no attribute 'append'

my code in python have this error, i'm listen python and don't know why happens, in the console the python interpreter print this:
Introdusca el titulo del libro> crisal
introdusca el autor del libro> roijari
introdusca la editorial del libro> tor
introdusca el precio del libro> 456
Traceback (most recent call last):
File "/home/crisal/programas-en-python/tadcomp_clase3.py", line 32, in <module>
cargar_en_libreria(lr,l)
File "/home/crisal/programas-en-python/tad_comp_libre.py", line 10, in cargar_en_libreria
libreria.append(libro)
AttributeError: 'NoneType' object has no attribute 'append'
the problem happens when import the funtion that load the data in abstact data type(ADT) in the list that is allocated in the ADT with the name 'tad_comp_libre' and the code in python is this(main):
## EJERCICIO PRACTICO ##
#cargar cuatro libros
#imprimir los datos de todo los libros
#eliminar el 2º libro
#imprimir libros restantes
# estructura intrer de los libros
## nombre
## editorial
## autor
## precio
from tad_libro import*
from tad_comp_libre import*
#creo un for carador de los libro
l=crear_libro() #crea los libros
lr=crear_libreria() #crea la libreria
#introdusco los datos que van a tener los libros y los pone en la libreria
for i in range(0,3):
nom=input("Introdusca el titulo del libro> ")
aut=input("introdusca el autor del libro> ")
edi=input("introdusca la editorial del libro> ")
prec=float(input("introdusca el precio del libro> "))
cargar_libro(l,nom,aut,edi,prec)
cargar_en_libreria(lr,l)
#imprime los datos de los libros
for i in range(0,tamanio(lr)):
b_l=buscar_libro(lr,i)
print("--------------------------\n")
print("titulo: ",Vernombre(l))
print("autor: ",Verautor(l))
print("Ediorial: ",Vereditorial(l))
print("Precio: ",Verprecio(l))
print("--------------------------\n")
opc=1
##elimino el segundo libro:
opc=int(input("desea eliminar un libro?: Si(1)/No(0)>>"))
while opc==1:
nom=input("elija el libro que desea eliminar(nombre)")
b_l=buscar_libro2(lr,nom)
borrar_libro(lr,b_l)
opc=int(input("desea eliminar otro libro?: Si(1)/No(0)>>"))
else:
print("se a terminado el proceso de eliinacion de libros")
#imprime de nuevo la lista
for i in lr:
print("--------------------------\n")
print("titulo: ",Vernombre(i))
print("autor: ",Verautor(i))
print("Ediorial: ",Vereditoria(i))
print("Precio: ",Verprecio(i))
print("--------------------------\n")
(tad_libro)
def crear_libro():
libro=["","","",0]
return libro
def cargar_libro(libro,n,a,e,p):
libro[0]=n
libro[1]=a
libro[2]=e
libro[3]=p
def Vernombre(libro):
return libro[0]
def Verautor(libro):
return libro[1]
def Vereditorial(libro):
return libro[2]
def Verprecio(libro):
return libro[3]
def modifNom(libro,nom1):
libro[0]=nom1
def modifaut(libro,aut1):
libro[1]=aut1
def modifpre(libro,pre1):
libro[2]=pre1
(tad_comp_libre)
in this ADT happens the problem when load the data
from tad_libro import*
#crea el tipo de dato libreria
def crear_libreria():
libreria=[]
#carga los datos de los libros en la libreia
def cargar_en_libreria(libreria,libro):
libreria.append(libro)
#libro elimina un libro puntual de la libreria
def borrar_libro(libreria,l):
libreria.remove(l)
#devuelve el tamanio de la libreria
def tamanio(libreria):
return len(libreria)
#busca un libro dentro de la libreria
def buscar_libro(libreria,i):
return libreria[i]
def bucar_libro2(libreria,nombre):
for i in libreia:# el parametro libreria transforma el indice de tipo tad_libro porque es el tipo de dato que hay alojado en libreria
if Vernombre(i)==nombre:
return i
if you can help my, i'm will really thanks they, sorry for the code in spanish
crear_libreria needs to return its result. Right now, it stored in a variable that is immediately destroyed. As a result, the lr global is set to None.
Do this:
#crea el tipo de dato libreria
def crear_libreria():
return []

I can't use a function defined in another file, as if it wasn't there

I'm creating a problem written un python in Jupyter notebook. I have a file named as "myfunctions1.py", where I have defined a function called ClearSky. In the very same directory I'm writing a new programe but it turns out that every time I try to use the name of the file as a module and I try to access the function I get an error.
def ClearSky(csvfile):
#Fem que obvie els tabuladors
df = pandas.read_csv(csvfile, delimiter = "\\t")
#Subsitueix els Nan per strings amb 000
df.fillna("000", inplace=True)
#Convertiré en un array tot el percal
NUBarray = df.to_numpy()
#Creem la llista dels clear sky on anirem afegint els dies que toquen
clearsky = []
#Les úniques columnes no nules han de ser les de dia/mes/any
#Que venen a ser la columna 0, 1 i 2, per això comencem per la columna 3
col = NUBarray.shape[1]
row = NUBarray.shape[0]
lastcol = col - 1
#Fem dos bucles, el primer anirà fila a fia que és el dia, el segon anirà columna a columna
#Per a tenir un dia clear sky les columnes han d'estar totes composades per 000
for n in range(0,row):
for k in range(3,col):
#Trenco el primer bucle si trobem una columna diferent a '000'
if NUBarray[n,k] != "000":
break
#Si no s'ha trencat fins la última columna i aquesta val '000'
#Afegim a la llista el dia, el més i l'any que són les columnes 0,1 i 2
else:
if k == lastcol:
clearsky.append(NUBarray[n,0])
clearsky.append(NUBarray[n,1])
clearsky.append(NUBarray[n,2])
#Aquesta part només afecta si hem trencat el primer bucle, li diem que vagi al següent dia
#Així no cal que mire totes les columnes, no ens interessa
continue
#Me torna una llista però vull que sigue unarray de 3 columnes
#Puc trobar el nombre de files dividint per tres
#Uso reshape per a canviar la dimensió
clearskyrows = int(len(clearsky)/3)
clearskyarray = array(clearsky)
#Retorno un array amb els dies de cel clar
return clearskyarray.reshape(clearskyrows,3)
What I do in another file:
from myfunctions1 import ClearSky
I'm getting the error:
ImportError Traceback (most recent call last)/var/folders/h3/_ws68mys35vfc_g11qml5cmr0000gn/T/ipykernel_10758/2584126548.py in <module>16 #Let's improt useful functions17 from numpy import array,reshape,stack---> 18 from myfunctions1 import ClearSky
ImportError: cannot import name 'ClearSky' from 'myfunctions1' (/Users/andreacerapalatsi/Practiquesempresa/myfunctions1.py)

Python function return 'None' list

I have a function that removes duplicates from a list, and if removed, fills again those blanks with another entry of another list with all possible entries.
Right now, I have a function which does this work, but I don`t know why, at time to store that complete list without duplicates in another list when I call it, it appears as "none". But it works properly.
This is the function:
def elimina_Rep(dondeborrar, cantidadNecesaria, fichcompleto):
sinRep = [] # Donde almacenaremos las NO repetidas
sinRep_AUX = [] # Para borrar en la borrada, (varios ciclos de borrado)
for elem in dondeborrar: # Primera busqueda de elementos duplicados
if(elem not in sinRep): sinRep.append(elem) # Obtenemos una lista sin repeticiones
if sinRep == dondeborrar : pass # Comprobamos que haya diferencia de cantidad entre ambas
else:
while(sinRep != sinRep_AUX):
dif = (cantidadNecesaria - len(sinRep)) # Obtenemos cuantos elementos hemos borrado
for i in range(0,dif): # Generamos tantas nuevas entradas como las que hemos borrado
sinRep.append(random.choice(fichcompleto)) # Obtenemos una nueva lista completa (pero con posibles repeticiones)
for j in sinRep: # Comprobamos que no haya repeticiones de la primera busqueda
if(j not in sinRep_AUX): # Segunda busqueda de elementos duplicados
sinRep_AUX.append(j) # Obtenemos una lista sin repeticiones sinRep_AUX desde la primera sin rep
if(sinRep == sinRep_AUX):
return sinRep_AUX
else:
sinRep = sinRep_AUX
sinRep_AUX = []
If I print at the end of the function the content of sinrep_AUX (final correct list) all is OK, the problem appears in the calling at time to store it.
def gen_Preg(asignatura, porcentaje):
preguntas = [] # Creamos una lista vacia para alamcenar las preguntas
porc = int((porcentaje/100)*totalpreguntas) # Obtenemos cuantas preguntas necesitamos de esa asignatura por %
# Bucle for para obtener y escribir la 1a vez (con posibles duplicaciones)
with open(asignatura, 'r') as aPreg:
fichero = aPreg.read().strip().splitlines() # Obtenemos el fichero sin posibles espacios
for i in range(0,porc):
preguntas.append(random.choice(fichero))
random.shuffle(preguntas) # Mezclamos las preguntas generadas
preg_filt = elimina_Rep(preguntas, porc, fichero) # Tenemos un archivo con preguntas sin repeticiones
print(preg_filt)
Here, the first line shows the content of print sinRep_AUX from function elimina_Rep, and the last line, shows the content of preg_filt, that I suppose that is the list which store the returned list of the function when I call it
['Como te llamas?', 'Donde vives?', 'Como tomas apuntes?']
None
I've tried to change the return line from return sinRep_AUX to return elimina_Rep(dondeborrar, cantidadNecesaria, fichcompleto) as I saw in other posts, but it doesn't work
You only return something when if sinRep == dondeborrar fails and then during the loop if(sinRep == sinRep_AUX) succeeds.
You can solve these problems by moving the return statement to the end of the function.
def elimina_Rep(dondeborrar, cantidadNecesaria, fichcompleto):
sinRep = [] # Donde almacenaremos las NO repetidas
sinRep_AUX = [] # Para borrar en la borrada, (varios ciclos de borrado)
for elem in dondeborrar: # Primera busqueda de elementos duplicados
if(elem not in sinRep): sinRep.append(elem) # Obtenemos una lista sin repeticiones
if sinRep == dondeborrar : pass # Comprobamos que haya diferencia de cantidad entre ambas
else:
while(sinRep != sinRep_AUX):
dif = (cantidadNecesaria - len(sinRep)) # Obtenemos cuantos elementos hemos borrado
for i in range(0,dif): # Generamos tantas nuevas entradas como las que hemos borrado
sinRep.append(random.choice(fichcompleto)) # Obtenemos una nueva lista completa (pero con posibles repeticiones)
for j in sinRep: # Comprobamos que no haya repeticiones de la primera busqueda
if(j not in sinRep_AUX): # Segunda busqueda de elementos duplicados
sinRep_AUX.append(j) # Obtenemos una lista sin repeticiones sinRep_AUX desde la primera sin rep
if(sinRep == sinRep_AUX):
break
else:
sinRep = sinRep_AUX
sinRep_AUX = []
return sinRep_AUX

How to insert a new line after each element in a list? Python

I tried to append some elements to a new list, and I wanted to separate each one by a new line. I tried this:
for i in list_rents:
result.append("{}: {}\n".format(i, 'Caro' if i > avg else 'Precio razonable'))
print("El precio promedio de la lista dada es {}, por lo que estas son las comparaciones independientes:\n {}".format(avg, result))
The last part worked as I expected, but the first one did not, why does that happen, and how can I solve it?
Here's the output:
El precio promedio de la lista dada es 24.166666666666668, por lo que estas son las comparaciones independientes:
['21.0: Precio razonable\n', '12.0: Precio razonable\n', '32.0: Caro\n', '23.0: Precio razonable\n', '43.0: Caro\n', '14.0: Precio razonable\n']
And here is the full code:
result = []
ans = input('Quieres agregar un elemento a la lista de precios de rentas? (S) Si, (N) No.')
while ans == 'S':
new_value = float(input('Ingrese el valor del nuevo elemento'))
if new_value > 0:
list_rents.append(new_value)
else:
print('Programa terminado, ese es un valor inaceptable')
sys.exit()
ans = input('Quieres agregar un elemento a la lista de precios de rentas? (S) Si, (N) No.')
avg = sum(list_rents)/len(list_rents)
for i in list_rents:
result.append("{}: {}\n".format(i, 'Caro' if i > avg else 'Precio razonable'))
print("El precio promedio de la lista dada es {}, por lo que estas son las comparaciones independientes:\n {}".format(avg, result))
If you want to turn a list of strings li into a single string, joined by newlines, you should use "\n".join(li), instead of adding a newline to each string individually (because you'll still have a list then).

Categories

Resources