RBPi + LCD + Sensor ultrasónico HC-SR04

¿Algo falla o no sabes como funciona? Pide ayuda aquí!
Responder
Juanludcb
Pi Newbie
Pi Newbie
Mensajes: 8
Registrado: 26 Oct 2021, 21:19
Agradecido: 2 veces
Agradecimiento recibido: 0

Buenos días,

Tengo un problema con un proyecto que quiero sacar adelante para una exposición. Va a estar expuesta en una pared todo al aire, sin carcasas ni soportes, todo visto.
La idea es tener expuesta la RBPi y que esta reproduzca un video en loop cada vez que un sensor ultrasónico detecte un objeto a menos de 2 metros de distancia. Tengo claro que se tiene que hacer con una RBPi ya que Arduino no tiene potencia para esto.
De momento Tengo conectada la RBPi a una pantalla de 7" , unos altavoces para que se oiga, le tengo instalado el Raspbian, y he bajado el video a la resolución de la pantalla para que este pese lo justo y necesario. Funciona todo bien.

Me encuentro con varios problemas:
- He visto que la RBPi trabaja a 3.3V y el sensor HC-SR04 al ser de Arduino es de 5V. Ese es la primera barrera que me encuentro. Sé que habría que igualar los voltajes mediante resistencias, pero mi idea de electrónica es limitada.
- La RBPi va a estar expuesta, no quiero que se vea nada más que un video a pantalla completa mienrtas haya alguien delante de la pantalla, cuando el sensor no detecte señal de vuelta, que la pantalla quede en blanco. Había pensado en poner un par de frames en blanco al principio, pero no sé si será mejor de otra manera.
- El tema del encendido, es otro problema que me encuentro. Cuando encienda la RBPi el programa debe correr sin que se llegue a ver el SO cargado, es decir, no me importa que se vea el inicio de carga del sistema operativo, son todo órdenes y comandos, queda bonito.. pero no me gusta la idea de que cargue algo con iconos y un escritorio, y mucho menos que haya que clicar sobre un ejecutable para hacerlo funcionar.

No sé si es posible, o quizás es demasiado ambicioso.
Podrían echarme una mano?

Un saludo.

Juanlu
Avatar de Usuario
egrueda
Pi God
Pi God
Mensajes: 3426
Registrado: 10 Feb 2017, 19:31
Agradecido: 7 veces
Agradecimiento recibido: 269 veces

1. Tienes 5v en el GPIO, en el pin 4
2 y 3. Lo suyo es que auto-arranque la aplicación y muestre el logo y las instrucciones, mientras el sensor no detecta nada.
Hay muchas formas de hacer un autostart, no tienes por qué arrancar al escritorio gráfico
Estos usuarios agradecieron al autor egrueda por el mensaje:
Juanludcb
Juanludcb
Pi Newbie
Pi Newbie
Mensajes: 8
Registrado: 26 Oct 2021, 21:19
Agradecido: 2 veces
Agradecimiento recibido: 0

Ante todo gracias por la rápida respuesta.

Me parece genial que se pueda autoejecutar una la aplicación, he estado buscando info y he encontrado lo siguiente por si a alguien pudiera servirle:

https://raspberrypi-espana.es/ejecutar- ... de-inicio/

Sobre el tema del sensor, Esto es lo que he podido obtener de información sobre el sensor HC-SR04:

The HC-SR04 Ultrasonic sensor we’ll be using in this tutorial for the Raspberry Pi has four pins: ground (GND), Echo Pulse Output (ECHO), Trigger Pulse Input (TRIG), and 5V Supply (Vcc). We power the module using Vcc, ground it using GND, and use our Raspberry Pi to send an input signal to TRIG, which triggers the sensor to send an ultrasonic pulse. The pulse waves bounce off any nearby objects and some are reflected back to the sensor. The sensor detects these return waves and measures the time between the trigger and returned pulse, and then sends a 5V signal on the ECHO pin.

ECHO will be “low” (0V) until the sensor is triggered when it receives the echo pulse. Once a return pulse has been located ECHO is set “high” (5V) for the duration of that pulse. Pulse duration is the full time between the sensor outputting an ultrasonic pulse, and the return pulse being detected by the sensor receiver. Our Python script must therefore measure the pulse duration and then calculate distance from this.

IMPORTANT. The sensor output signal (ECHO) on the HC-SR04 is rated at 5V. However, the input pin on the Raspberry Pi GPIO is rated at 3.3V. Sending a 5V signal into that unprotected 3.3V input port could damage your GPIO pins, which is something we want to avoid! We’ll need to use a small voltage divider circuit, consisting of two resistors, to lower the sensor output voltage to something our Raspberry Pi can handle.

O sea que es el pin echo el que devuelve los 5V a la RBPi, lo cual puede quemarla, por eso recalca que hay que usar un divisor de voltaje. Lo bueno es que especifican la fórmula para calcular las resistencias necesarias, así que intentaré seguir los pasos. Soy un poco pez, pero muy enreda, así que espero avanzar sin necesidad de quemar la placa y tener que verme comprando varias para sacar el proyecto adelante! :suerte

Lo que saco en claro es que hay que hacer un divisor de voltaje mediante un par de resistencias. Os paso el enlace que he podido encontrar al respecto:

https://thepihut.com/blogs/raspberry-pi ... spberry-pi

Iré subiendo cosillas según vaya avanzando el proyecto.

Gracias de nuevo y un saludO!
Avatar de Usuario
egrueda
Pi God
Pi God
Mensajes: 3426
Registrado: 10 Feb 2017, 19:31
Agradecido: 7 veces
Agradecimiento recibido: 269 veces

Bueno, tengo la sensación de que esa documentación corresponde a la raspberry pi 1, la de la salida de vídeo amarilla, quizá la explicación no sea válida para la raspi 3 o la 4
hc-sr04-tut-8_1024x1024.jpg
Avatar de Usuario
egrueda
Pi God
Pi God
Mensajes: 3426
Registrado: 10 Feb 2017, 19:31
Agradecido: 7 veces
Agradecimiento recibido: 269 veces

¡Ah, vale! que es el retorno, perdona
Juanludcb
Pi Newbie
Pi Newbie
Mensajes: 8
Registrado: 26 Oct 2021, 21:19
Agradecido: 2 veces
Agradecimiento recibido: 0

Uff no había pensado en que puede ser diferente dependiendo del modelo! Bien visto!
Juanludcb
Pi Newbie
Pi Newbie
Mensajes: 8
Registrado: 26 Oct 2021, 21:19
Agradecido: 2 veces
Agradecimiento recibido: 0

Buenos días,

Pues estoy cerquita, pero algo estancado.
He logrado conectar todo, haciendo un divisor de voltaje como especifiqué. Ahora estoy con el código, pero no soy capaz de hacerlo funcionar como debería. Os paso código:

Código: Seleccionar todo

import vlc
import time

media_player = vlc.MediaPlayer()

media_player.set_fullscreen(False)

media = vlc.Media("video.mp4")

media_player.set_media(media)

while True:
      GPIO.setmode(GPIO.BOARD)

      PIN_TRIGGER = 12
      PIN_ECHO = 16

      GPIO.setup(PIN_TRIGGER, GPIO.OUT)
      GPIO.setup(PIN_ECHO, GPIO.IN)

      GPIO.output(PIN_TRIGGER, GPIO.LOW)

      time.sleep(1)

      GPIO.output(PIN_TRIGGER, GPIO.HIGH)

      time.sleep(0.00001)

      GPIO.output(PIN_TRIGGER, GPIO.LOW)

      while GPIO.input(PIN_ECHO)==0:
            pulse_start_time = time.time()
      while GPIO.input(PIN_ECHO)==1:
            pulse_end_time = time.time()

      pulse_duration = pulse_end_time - pulse_start_time
      distance = round(pulse_duration * 17150, 2)
      
      print (distance,"cm")
      
      if 2 < distance < 5:
            media_player.play()
      elif distance > 10:
            media_player.set_pause(1)
El sensor funciona, ya que me devuelve la distancia al pasar la mano, pero no reproduce el vídeo. Alguna idea de por qué puede ser?

Gracias y saludos!
Avatar de Usuario
egrueda
Pi God
Pi God
Mensajes: 3426
Registrado: 10 Feb 2017, 19:31
Agradecido: 7 veces
Agradecimiento recibido: 269 veces

Depura más el código, mete "print" para ver dónde entra.
Mete "print" en el if del final, uno antes de media_player.play() y otro antes de media_player.set_pause() para confirmar que entra en el primero
Crea un "else" para todos los demás casos y haz un print para ver si entras en él.

Una vez hecho eso, depura un poco más:
Deja que empiece a reproducir, dale unos segundos, y comprueba si está reproduciendo

Código: Seleccionar todo

media_player.play()
time.sleep(5)
value = media_player.is_playing()
print("Is playing : ")
print(value)
Pero antes de nada, asegúrate de que entra en el if del media_player.play()
Estos usuarios agradecieron al autor egrueda por el mensaje:
Juanludcb
Juanludcb
Pi Newbie
Pi Newbie
Mensajes: 8
Registrado: 26 Oct 2021, 21:19
Agradecido: 2 veces
Agradecimiento recibido: 0

Ostras Gracias, me ha servido de mucho!

Está funcionando!!

Ahora me encuentro otro problema. El video se pausa, cuando este debería detenerse y no encuentro la manera de llamar al stop. Además que el código debería hacer loop infinito. Es decir, la intención es que una vez se reproduzca el video completo, comience de nuevo, osea que nunca se detenga el código y empiece de nuevo. He estado buscando pero se me escapa de mis conocimientos, creo que me estoy enfangando o complicando demasiado. Alguna idea de cómo podría solventarlo?

Mil gracias de nuevo!
Avatar de Usuario
egrueda
Pi God
Pi God
Mensajes: 3426
Registrado: 10 Feb 2017, 19:31
Agradecido: 7 veces
Agradecimiento recibido: 269 veces

Si quieres un loop, tienes que usar el método vlm_set_loop del player.
Ejemplo: https://www.geeksforgeeks.org/python-vl ... the-media/
Juanludcb
Pi Newbie
Pi Newbie
Mensajes: 8
Registrado: 26 Oct 2021, 21:19
Agradecido: 2 veces
Agradecimiento recibido: 0

egrueda escribió: 01 Nov 2021, 12:23 Si quieres un loop, tienes que usar el método vlm_set_loop del player.
Ejemplo: https://www.geeksforgeeks.org/python-vl ... the-media/
Gracias, pero por más intentos que he hecho de implementarlo, no doy con la manera... Buscando y rebuscando maneras de conseguir llegar a lo que pretendo he podido añadir alguna cosilla. La verdad es que funcionar funciona. El video se pausa y comienza desde 0, pero una vez termina el video se acabó, el programa termina. Además haciendo pruebas me he dado cuenta de que si me acerco y me separo del sensor unas cuantas veces, alrededor de la 6 o 7 vez el programa termina y el video continua reproduciéndose solo, sin mostrar lectura de la distancia, y aunque me separe ya no hace pausa, como si el programa terminase y dejase el video reproducirse solo hasta el final.

Código: Seleccionar todo

#!/usr/bin/python
import RPi.GPIO as GPIO
import vlc
import time

media_player = vlc.MediaPlayer()

media_player.set_fullscreen(False)

media = vlc.Media("video.mp4")

media_player.set_media(media)

while True:
      GPIO.setmode(GPIO.BOARD)

      PIN_TRIGGER = 12
      PIN_ECHO = 16

      GPIO.setup(PIN_TRIGGER, GPIO.OUT)
      GPIO.setup(PIN_ECHO, GPIO.IN)

      GPIO.output(PIN_TRIGGER, GPIO.LOW)

      time.sleep(1)

      GPIO.output(PIN_TRIGGER, GPIO.HIGH)

      time.sleep(0.00001)

      GPIO.output(PIN_TRIGGER, GPIO.LOW)

      while GPIO.input(PIN_ECHO)==0:
            pulse_start_time = time.time()
      while GPIO.input(PIN_ECHO)==1:
            pulse_end_time = time.time()

      pulse_duration = pulse_end_time - pulse_start_time
      distance = round(pulse_duration * 17150, 2)
      
      print (distance,"cm")
      
      if distance > 31:
          media_player.set_position(0.0)
          time.sleep(0.5)
          media_player.set_pause(1)
          time.sleep(1)
          value = media_player.set_pause(1)
          print("No hay nadie : ")  
            
      elif 2 < distance < 30: 
          media_player.play()
          time.sleep(1)
          value = media_player.is_playing()
          print("Detectado, reproduciendo : ")
Siento tanta lata, alguna idea? Me estoy desesperando un poco, estoy viendo que me he metido en un jardín de tres pares... :destroyer

gracias de nuevo.
Juanludcb
Pi Newbie
Pi Newbie
Mensajes: 8
Registrado: 26 Oct 2021, 21:19
Agradecido: 2 veces
Agradecimiento recibido: 0

He probado también con:

Código: Seleccionar todo

      if 2 < distance < 30: 
          media_player.play()
          time.sleep(1)
          print("Detectado, reproduciendo : ")
            
      elif distance > 31:
          media_player.stop()
          time.sleep(1)
          print("No hay nadie : ")
De este modo funciona mucho más rápido, pero sigue pasando lo mismo.

Dejo el Shell para que podáis ver los errores que me salen.

Código: Seleccionar todo

5.62 cm
Detectado, reproduciendo : 
4.7 cm
Detectado, reproduciendo : 
43.69 cm
No hay nadie : 
11.02 cm
[64379d38] mmal_codec decoder: VCSM init succeeded: Legacy
[64379d38] main decoder error: buffer deadlock prevented
libEGL warning: DRI2: failed to authenticate
[00833000] mmal_xsplitter vout display error: Failed to open Xsplitter:opengles2 module
Detectado, reproduciendo : 
8.91 cm
Detectado, reproduciendo : 
6.74 cm
Detectado, reproduciendo : 
43.03 cm
No hay nadie : 
6.62 cm
[5e8473c8] mmal_codec decoder: VCSM init succeeded: Legacy
[5e8473c8] main decoder error: buffer deadlock prevented
libEGL warning: DRI2: failed to authenticate
[5ea03078] mmal_xsplitter vout display error: Failed to open Xsplitter:opengles2 module
Detectado, reproduciendo : 
Avatar de Usuario
egrueda
Pi God
Pi God
Mensajes: 3426
Registrado: 10 Feb 2017, 19:31
Agradecido: 7 veces
Agradecimiento recibido: 269 veces

Bueno, todos los proyectos tienen complicaciones, por eso me cabreo a veces cuando la gente cree que un proyecto se hace en media hora :-D

Por un lado, yo cambiaría el "elif" por un "else", así el vídeo se detiene en cualquier otra circunstancia y no sólo en el supuesto de > 31
Es decir, en cada loop debería asegurarse de que el vídeo está parado.
E incluso cuando arranca el vídeo, antes debería asegurarse de que está parado.

Por otro lado, para el loop, fíjate en el ejemplo que enlazo.
Ahí parten de una instancia diferente: player = vlc.Instance()
Mientras que tú usas algo como: media = vlc.MediaPlayer()
Es algo así como hacer referencia a un cine o a una película de ese cine ;-)
Estos usuarios agradecieron al autor egrueda por el mensaje:
grafenwalderr
Responder