.. note:: ¡Hola! Bienvenido a la comunidad de entusiastas de SunFounder para Raspberry Pi, Arduino y ESP32 en Facebook. Únete a otros apasionados y profundiza en el uso de Raspberry Pi, Arduino y ESP32. **¿Por qué unirte?** - **Soporte de expertos**: Resuelve problemas postventa y desafíos técnicos con la ayuda de nuestra comunidad y equipo. - **Aprende y comparte**: Intercambia consejos y tutoriales para mejorar tus habilidades. - **Avances exclusivos**: Obtén acceso anticipado a anuncios de nuevos productos y adelantos exclusivos. - **Descuentos especiales**: Disfruta de descuentos exclusivos en nuestros productos más recientes. - **Promociones festivas y sorteos**: Participa en sorteos y promociones de temporada. 👉 ¿Listo para explorar y crear con nosotros? Haz clic en [|link_sf_facebook|] y únete hoy mismo. .. _py_pi5_counting_device: 3.1.1 Dispositivo Contador ============================= Introducción --------------- Aquí crearemos un sistema contador que muestra números, compuesto por un sensor PIR y una pantalla de 4 dígitos de segmento. Cuando el sensor PIR detecta que alguien pasa, el número en la pantalla de 4 dígitos aumentará en 1. Puedes utilizar este contador para contar el número de personas que atraviesan un pasillo. Componentes necesarios -------------------------- En este proyecto, necesitamos los siguientes componentes. .. image:: ../python_pi5/img/4.1.7_counting_device_list_1.png :align: center .. image:: ../python_pi5/img/4.1.7_counting_device_list_2.png :align: center .. Es definitivamente conveniente comprar un kit completo, aquí tienes el enlace: .. .. list-table:: .. :widths: 20 20 20 .. :header-rows: 1 .. * - Nombre .. - ELEMENTOS EN ESTE KIT .. - ENLACE .. * - Kit Raphael .. - 337 .. - |link_Raphael_kit| .. También puedes comprarlos por separado en los enlaces a continuación. .. .. list-table:: .. :widths: 30 20 .. :header-rows: 1 .. * - INTRODUCCIÓN AL COMPONENTE .. - ENLACE DE COMPRA .. * - :ref:`gpio_extension_board` .. - |link_gpio_board_buy| .. * - :ref:`breadboard` .. - |link_breadboard_buy| .. * - :ref:`wires` .. - |link_wires_buy| .. * - :ref:`resistor` .. - |link_resistor_buy| .. * - :ref:`4_digit` .. - \- .. * - :ref:`74hc595` .. - |link_74hc595_buy| .. * - :ref:`pir` .. - \- Diagrama esquemático ------------------------ ============ ======== ======== === T-Board Name physical wiringPi BCM GPIO17 Pin 11 0 17 GPIO27 Pin 13 2 27 GPIO22 Pin 15 3 22 SPIMOSI Pin 19 12 10 GPIO18 Pin 12 1 18 GPIO23 Pin 16 4 23 GPIO24 Pin 18 5 24 GPIO26 Pin 37 25 26 ============ ======== ======== === .. image:: ../python_pi5/img/4.1.7_counting_device_schematic.png :align: center Procedimientos experimentales -------------------------------- **Paso 1**: Construye el circuito. .. image:: ../python_pi5/img/4.1.7_counting_device_circuit.png **Paso 2**: Ve a la carpeta del código. .. raw:: html .. code-block:: cd ~/davinci-kit-for-raspberry-pi/python-pi5 **Paso 3**: Ejecuta el archivo ejecutable. .. raw:: html .. code-block:: sudo python3 3.1.1_CountingDevice.py Después de ejecutar el código, cuando el sensor PIR detecte que alguien pasa, el número en la pantalla de 4 dígitos aumentará en 1. El módulo PIR tiene dos potenciómetros: uno para ajustar la sensibilidad y otro para ajustar la distancia de detección. Para mejorar el funcionamiento del módulo PIR, gíralos ambos en sentido contrario a las agujas del reloj hasta el final. .. image:: ../python_pi5/img/4.1.7_PIR_TTE.png :width: 400 :align: center .. warning:: Si aparece el mensaje de error ``RuntimeError: Cannot determine SOC peripheral base address``, consulta :ref:`faq_soc` **Código** .. note:: Puedes **Modificar/Restablecer/Copiar/Ejecutar/Detener** el código a continuación. Pero antes, debes ir a la ruta del código fuente como ``davinci-kit-for-raspberry-pi/python-pi5``. Después de modificar el código, puedes ejecutarlo directamente para ver el efecto. .. raw:: html .. code-block:: python #!/usr/bin/env python3 from gpiozero import OutputDevice, MotionSensor # Inicializar el sensor de movimiento PIR en GPIO 26 pir = MotionSensor(26) # Inicializar pines del registro de desplazamiento SDI = OutputDevice(24) # Entrada de Datos Seriales RCLK = OutputDevice(23) # Entrada del Reloj de Registro SRCLK = OutputDevice(18) # Entrada del Reloj de Registro de Desplazamiento # Inicializar pines de la pantalla de 7 segmentos placePin = [OutputDevice(pin) for pin in (10, 22, 27, 17)] # Definir códigos de dígitos para la pantalla de 7 segmentos number = (0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90) # Contador para el número mostrado counter = 0 def clearDisplay(): # Limpia la pantalla apagando todos los segmentos for _ in range(8): SDI.on() SRCLK.on() SRCLK.off() RCLK.on() RCLK.off() def hc595_shift(data): # Desplaza datos en el registro de desplazamiento 74HC595 for i in range(8): SDI.value = 0x80 & (data << i) SRCLK.on() SRCLK.off() RCLK.on() RCLK.off() def pickDigit(digit): # Activa un dígito específico de la pantalla de 7 segmentos for pin in placePin: pin.off() placePin[digit].on() def display(): # Actualiza la pantalla con el valor actual del contador global counter clearDisplay() pickDigit(0) hc595_shift(number[counter % 10]) clearDisplay() pickDigit(1) hc595_shift(number[counter % 100 // 10]) clearDisplay() pickDigit(2) hc595_shift(number[counter % 1000 // 100]) clearDisplay() pickDigit(3) hc595_shift(number[counter % 10000 // 1000]) def loop(): # Bucle principal para actualizar la pantalla y comprobar movimiento global counter currentState = 0 lastState = 0 while True: display() currentState = 1 if pir.motion_detected else 0 if currentState == 1 and lastState == 0: counter += 1 lastState = currentState try: loop() except KeyboardInterrupt: # Apagar todos los pines cuando se interrumpe el script SDI.off() SRCLK.off() RCLK.off() pass **Explicación del Código** #. Esta línea importa las clases ``OutputDevice`` y ``MotionSensor`` de la biblioteca ``gpiozero``. ``OutputDevice`` puede ser un LED, motor, o cualquier dispositivo que se desee controlar como salida. ``MotionSensor`` es típicamente un sensor PIR (Infrarrojo Pasivo) usado para detectar movimiento. .. code-block:: python #!/usr/bin/env python3 from gpiozero import OutputDevice, MotionSensor #. Inicializa el sensor de movimiento PIR conectado al pin GPIO 26. .. code-block:: python # Inicializar el sensor de movimiento PIR en GPIO 26 pir = MotionSensor(26) #. Inicializa los pines GPIO conectados a la Entrada de Datos Seriales (SDI), la Entrada del Reloj de Registro (RCLK) y la Entrada del Reloj del Registro de Desplazamiento (SRCLK) del registro de desplazamiento. .. code-block:: python # Inicializar pines del registro de desplazamiento SDI = OutputDevice(24) # Entrada de Datos Seriales RCLK = OutputDevice(23) # Entrada del Reloj de Registro SRCLK = OutputDevice(18) # Entrada del Reloj del Registro de Desplazamiento #. Inicializa los pines para cada dígito de la pantalla de 7 segmentos y define los códigos binarios para mostrar los números del 0 al 9. .. code-block:: python # Inicializar pines de la pantalla de 7 segmentos placePin = [OutputDevice(pin) for pin in (10, 22, 27, 17)] # Definir códigos de dígitos para la pantalla de 7 segmentos number = (0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90) #. Limpia la pantalla de 7 segmentos apagando todos los segmentos antes de mostrar el siguiente dígito. .. code-block:: python def clearDisplay(): # Limpia la pantalla apagando todos los segmentos for _ in range(8): SDI.on() SRCLK.on() SRCLK.off() RCLK.on() RCLK.off() #. Desplaza un byte de datos al registro de desplazamiento 74HC595, controlando los segmentos de la pantalla. .. code-block:: python def hc595_shift(data): # Desplaza datos en el registro de desplazamiento 74HC595 for i in range(8): SDI.value = 0x80 & (data << i) SRCLK.on() SRCLK.off() RCLK.on() RCLK.off() #. Selecciona qué dígito de la pantalla de 7 segmentos activar. Cada dígito es controlado por un pin GPIO separado. .. code-block:: python def pickDigit(digit): # Activa un dígito específico de la pantalla de 7 segmentos for pin in placePin: pin.off() placePin[digit].on() #. Inicia la visualización para el dígito de unidades primero, seguido de la activación para el dígito de las decenas. Posteriormente, activa las pantallas para los dígitos de centenas y millares en orden. Esta rápida sucesión de activaciones crea la ilusión de una pantalla continua de cuatro dígitos. .. code-block:: python def display(): # Actualiza la pantalla con el valor actual del contador global counter clearDisplay() pickDigit(0) hc595_shift(number[counter % 10]) clearDisplay() pickDigit(1) hc595_shift(number[counter % 100 // 10]) clearDisplay() pickDigit(2) hc595_shift(number[counter % 1000 // 100]) clearDisplay() pickDigit(3) hc595_shift(number[counter % 10000 // 1000]) #. Define el bucle principal donde la pantalla se actualiza continuamente y se verifica el estado del sensor PIR. Si se detecta movimiento, el contador se incrementa. .. code-block:: python def loop(): # Bucle principal para actualizar la pantalla y comprobar movimiento global counter currentState = 0 lastState = 0 while True: display() currentState = 1 if pir.motion_detected else 0 if currentState == 1 and lastState == 0: counter += 1 lastState = currentState #. Ejecuta el bucle principal y asegura que el script pueda ser interrumpido con un comando de teclado (Ctrl+C), apagando todos los pines para una salida limpia. .. code-block:: python try: loop() except KeyboardInterrupt: # Apaga todos los pines cuando el script es interrumpido SDI.off() SRCLK.off() RCLK.off() pass