.. note:: ¡Hola! Bienvenido a la Comunidad de Entusiastas de SunFounder Raspberry Pi & Arduino & ESP32 en Facebook. Profundiza en Raspberry Pi, Arduino y ESP32 con otros entusiastas. **¿Por qué unirse?** - **Soporte experto**: 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 vistas previas. - **Descuentos especiales**: Disfruta de descuentos exclusivos en nuestros productos más recientes. - **Promociones y sorteos festivos**: Participa en sorteos y promociones festivas. 👉 ¿Listo para explorar y crear con nosotros? Haz clic en [|link_sf_facebook|] y únete hoy mismo. .. _4.1.18_py_pi5: 4.1.15 JUEGO - 10 Segundos =============================== Introducción ---------------------- A continuación, sigue mis instrucciones para crear un dispositivo de juego que pondrá a prueba tu concentración. Ata el interruptor de inclinación a un palo para hacer una varita mágica. Agita la varita, la pantalla de 4 dígitos comenzará a contar, agítala de nuevo para detener la cuenta. Si logras mantener el conteo en **10.00**, entonces ganas. Puedes jugar con tus amigos para ver quién es el mago del tiempo. Componentes necesarios ------------------------------ En este proyecto, necesitamos los siguientes componentes. .. image:: ../python_pi5/img/4.1.18_game_10_second_list.png :width: 800 :align: center Es definitivamente conveniente comprar un kit completo, aquí está 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 DEL COMPONENTE - ENLACE DE COMPRA * - :ref:`cpn_gpio_board` - |link_gpio_board_buy| * - :ref:`cpn_breadboard` - |link_breadboard_buy| * - :ref:`cpn_wires` - |link_wires_buy| * - :ref:`cpn_resistor` - |link_resistor_buy| * - :ref:`cpn_4_digit` - \- * - :ref:`cpn_74hc595` - |link_74hc595_buy| * - :ref:`cpn_tilt_switch` - \- Diagrama esquemático -------------------------- ================== ====== ======== === Nombre del T-Board físico 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.18_game_10_second_schematic.png :align: center Procedimientos experimentales ----------------------------------- **Paso 1**: Construye el circuito. .. image:: ../python_pi5/img/4.1.18_game_10_second_circuit.png **Paso 2**: Ve a la carpeta del código. .. raw:: html .. code-block:: cd ~/raphael-kit/python-pi5 **Paso 3**: Ejecuta el archivo ejecutable. .. raw:: html .. code-block:: sudo python3 4.1.18_GAME_10Second_zero.py Agita la varita, la pantalla de 4 dígitos comenzará a contar, agítala de nuevo para detener la cuenta. Si logras mantener el conteo en **10.00**, entonces ganas. Agítala una vez más para comenzar la siguiente ronda del juego. .. warning:: Si recibe el mensaje de error ``RuntimeError: Cannot determine SOC peripheral base address``, consulte :ref:`faq_soc` **Código** .. note:: Puedes **Modificar/Restablecer/Copiar/Ejecutar/Detener** el código a continuación. Pero antes de eso, necesitas ir a la ruta del código fuente como ``raphael-kit/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, Button import time import threading # Inicializa el botón conectado al GPIO 26 sensorPin = Button(26) # Define los pines GPIO conectados al registro de desplazamiento 74HC595 SDI = OutputDevice(24) # Entrada de datos serial RCLK = OutputDevice(23) # Reloj de registro SRCLK = OutputDevice(18) # Reloj de registro de desplazamiento # Define los pines GPIO para la selección de dígitos en la pantalla de 7 segmentos placePin = [OutputDevice(pin) para pin en (10, 22, 27, 17)] # Define los códigos de segmentos para los números del 0 al 9 en la pantalla de 7 segmentos number = (0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90) # Variables del contador y del temporizador counter = 0 timer1 = None gameState = 0 def clearDisplay(): """ Clear all segments on the 7-segment display. """ for _ in range(8): SDI.on() SRCLK.on() SRCLK.off() RCLK.on() RCLK.off() def hc595_shift(data): """ Shift data to the 74HC595 shift register to display a digit. """ for i in range(8): SDI.value = 0x80 & (data << i) SRCLK.on() SRCLK.off() RCLK.on() RCLK.off() def pickDigit(digit): """ Select which digit to display on the 7-segment display. """ for pin in placePin: pin.off() placePin[digit].on() def display(): """ Display the current counter value on the 7-segment display. """ 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] - 0x80) clearDisplay() pickDigit(3) hc595_shift(number[counter % 10000 // 1000]) def stateChange(): """ Handle state changes for the counter based on button presses. """ global gameState, counter, timer1 if gameState == 0: counter = 0 time.sleep(1) timer() elif gameState == 1 y timer1 no es None: timer1.cancel() time.sleep(1) gameState = (gameState + 1) % 2 def loop(): """ Main loop to check for button presses and update the display. """ global counter currentState = 0 lastState = 0 while True: display() currentState = sensorPin.value if (currentState == 0) and (lastState == 1): stateChange() lastState = currentState def timer(): """ Timer function that increments the counter every 0.01 second. """ global counter, timer1 timer1 = threading.Timer(0.01, timer) timer1.start() counter += 1 try: loop() except KeyboardInterrupt: if timer1: timer1.cancel() **Explicación del Código** #. El script comienza importando los módulos necesarios. La biblioteca ``gpiozero`` se utiliza para interactuar con dispositivos GPIO como botones, y los módulos ``time`` y ``threading`` pueden utilizarse para manejar tareas relacionadas con el tiempo u operaciones concurrentes. .. code-block:: python #!/usr/bin/env python3 from gpiozero import OutputDevice, Button import time import threading #. Inicializa un objeto ``Button`` de la biblioteca GPIO Zero, conectándolo al pin GPIO 26. Esta configuración permite detectar las pulsaciones del botón. .. code-block:: python # Inicializa el botón conectado al GPIO 26 sensorPin = Button(26) #. Inicializa los pines GPIO conectados a la entrada de datos en serie (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 # Define los pines GPIO conectados al registro de desplazamiento 74HC595 SDI = OutputDevice(24) # Entrada de datos serial RCLK = OutputDevice(23) # Reloj de registro SRCLK = OutputDevice(18) # Reloj de 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 # Define los pines GPIO para la selección de dígitos en la pantalla de 7 segmentos placePin = [OutputDevice(pin) para pin en (10, 22, 27, 17)] # Define los códigos de segmentos para los números del 0 al 9 en la pantalla de 7 segmentos number = (0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90) #. Funciones para controlar la pantalla de 7 segmentos. ``clearDisplay`` apaga todos los segmentos, ``hc595_shift`` desplaza datos al registro de desplazamiento y ``pickDigit`` activa un dígito específico en la pantalla. .. code-block:: python def clearDisplay(): """ Clear all segments on the 7-segment display. """ for _ in range(8): SDI.on() SRCLK.on() SRCLK.off() RCLK.on() RCLK.off() def hc595_shift(data): """ Shift data to the 74HC595 shift register to display a digit. """ for i in range(8): SDI.value = 0x80 & (data << i) SRCLK.on() SRCLK.off() RCLK.on() RCLK.off() def pickDigit(digit): """ Select which digit to display on the 7-segment display. """ for pin in placePin: pin.off() placePin[digit].on() #. Función para mostrar el valor actual del contador en la pantalla de 7 segmentos. .. code-block:: python def display(): """ Display the current counter value on the 7-segment display. """ 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] - 0x80) clearDisplay() pickDigit(3) hc595_shift(number[counter % 10000 // 1000]) #. Función para manejar los cambios de estado (inicio/detención) del contador basados en las pulsaciones del botón. .. code-block:: python def stateChange(): """ Handle state changes for the counter based on button presses. """ global gameState, counter, timer1 if gameState == 0: counter = 0 time.sleep(1) timer() elif gameState == 1 and timer1 is not None: timer1.cancel() time.sleep(1) gameState = (gameState + 1) % 2 #. Bucle principal que verifica continuamente el estado del botón y actualiza la pantalla. Llama a ``stateChange`` cuando el estado del botón cambia. .. code-block:: python def loop(): """ Main loop to check for button presses and update the display. """ global counter currentState = 0 lastState = 0 while True: display() currentState = sensorPin.value if (currentState == 0) and (lastState == 1): stateChange() lastState = currentState #. Función del temporizador que incrementa el contador a intervalos regulares (cada 0.01 segundo). .. code-block:: python def timer(): """ Timer function that increments the counter every 0.01 second. """ global counter, timer1 timer1 = threading.Timer(0.01, timer) timer1.start() counter += 1 #. Ejecuta el bucle principal y permite una salida limpia del programa utilizando una interrupción de teclado (Ctrl+C). .. code-block:: python try: loop() except KeyboardInterrupt: if timer1: timer1.cancel()