.. note::

    ¡Hola! Bienvenido a la Comunidad de Entusiastas de SunFounder para Raspberry Pi, Arduino y ESP32 en Facebook. Sumérgete más en Raspberry Pi, Arduino y ESP32 con otros entusiastas.

    **¿Por qué unirse?**

    - **Soporte experto**: Resuelve problemas post-venta y desafíos técnicos con la ayuda de nuestra comunidad y equipo.
    - **Aprende y comparte**: Intercambia consejos y tutoriales para mejorar tus habilidades.
    - **Preestrenos exclusivos**: Obtén acceso anticipado a nuevos anuncios de productos y adelantos.
    - **Descuentos especiales**: Disfruta de descuentos exclusivos en nuestros productos más nuevos.
    - **Promociones y sorteos festivos**: Participa en sorteos y promociones de temporada.

    👉 ¿Listo para explorar y crear con nosotros? Haz clic en [|link_sf_facebook|] y únete hoy mismo.

.. _1.1.4_py_pi5:

1.1.4 Pantalla de 7 segmentos
===================================

Introducción
--------------------

Vamos a intentar controlar una pantalla de 7 segmentos para mostrar una cifra del 0 al 9 y de la A a la F.

Componentes Necesarios
---------------------------------

En este proyecto, necesitamos los siguientes componentes. 

.. image:: ../python_pi5/img/1.1.4_7_segment_list.png

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 AL COMPONENTE
        - ENLACE DE COMPRA

    *   - :ref:`cpn_gpio_extension_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_7_segment`
        - |link_7segment_buy|
    *   - :ref:`cpn_74hc595`
        - |link_74hc595_buy|


Diagrama Esquemático
------------------------

Conecta el pin ST_CP del 74HC595 al GPIO18 de Raspberry Pi, SH_CP al GPIO27 y DS al GPIO17. 
Conecta los puertos de salida paralelos a los 8 segmentos de la pantalla de LED.

Introduce datos en el pin DS al registro de desplazamiento cuando SH_CP 
(la entrada del reloj del registro de desplazamiento) esté en el flanco ascendente, 
y al registro de memoria cuando ST_CP (la entrada del reloj de la memoria) esté en el 
flanco ascendente.

Luego, puedes controlar los estados de SH_CP y ST_CP a través de los GPIOs de la Raspberry 
Pi para transformar la entrada de datos seriales en salida de datos paralelos, con el fin de 
ahorrar GPIOs de Raspberry Pi y controlar la pantalla.

================= ======== ===
Nombre de T-Board físico   BCM
GPIO17            Pin 11   17
GPIO18            Pin 12   18
GPIO27            Pin 13   27
================= ======== ===

.. image:: ../python_pi5/img/1.1.4_7_segment_schematic.png

Procedimientos Experimentales
------------------------------

**Paso 1:** Construye el circuito.

.. image:: ../python_pi5/img/1.1.4_7-Segment_circuit.png

**Paso 2:** Ingresa a la carpeta del código.

.. raw:: html

   <run></run>

.. code-block::

    cd ~/raphael-kit/python-pi5

**Paso 3:** Ejecuta.

.. raw:: html

   <run></run>

.. code-block::

    sudo python3 1.1.4_7-Segment_zero.py

Después de ejecutar el código, verás la pantalla de 7 segmentos mostrar los dígitos del 0 al 9 y las letras de la A a la F.

.. warning::

    Si recibe el mensaje de error ``RuntimeError: Cannot determine SOC peripheral base address``, consulte :ref:`faq_soc`

**Código**

.. note::
    Puedes **Modificar/Resetear/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. Después de confirmar que no hay problemas, puedes usar el botón de Copiar para copiar el código modificado, luego abrir el código fuente en el Terminal a través del comando ``nano`` y pegarlo.

.. raw:: html

    <run></run>

.. code-block:: python

   #!/usr/bin/env python3
   from gpiozero import OutputDevice
   from time import sleep

   # GPIO pins connected to 74HC595 shift register
   SDI = OutputDevice(17)   # Serial Data Input
   RCLK = OutputDevice(18)  # Memory Clock Input (Register Clock)
   SRCLK = OutputDevice(27) # Shift Register Clock

   # Hexadecimal digit codes for a common cathode 7-segment display
   segCode = [
       0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d,
       0x07, 0x7f, 0x6f, 0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71
   ]

   def hc595_shift(data):
       # Shift 8 bits of data into the 74HC595
       for bit in range(8):
           # Set SDI high or low based on data bit
           SDI.value = 0x80 & (data << bit)
           # Trigger shift register clock
           SRCLK.on()
           sleep(0.001)
           SRCLK.off()
       # Latch data to output by triggering memory clock
       RCLK.on()
       sleep(0.001)
       RCLK.off()

   def display_all_on():
       # Function to turn all segments on (for common cathode 7-segment display)
       all_on_code = 0x3f
       hc595_shift(all_on_code)
       print("Displaying all segments on")

   try:
       while True:
           # Display each hexadecimal digit on 7-segment display
           for code in segCode:
               hc595_shift(code)  # Shift the code into 74HC595
               # Print the displayed segment code
               print(f"Displaying segCode[{segCode.index(code)}]: 0x{code:02X}")
               sleep(0.5)  # Pause between displaying each digit

   except KeyboardInterrupt:
       # Gracefully handle script interruption (e.g., Ctrl+C)
       pass

       
**Explicación del Código**

#. Este fragmento importa las clases necesarias para el proyecto. ``OutputDevice`` de ``gpiozero`` se usa para controlar componentes de hardware conectados a los pines GPIO, y ``sleep`` de ``time`` se usa para agregar retrasos.

   .. code-block:: python

       #!/usr/bin/env python3
       from gpiozero import OutputDevice
       from time import sleep

#. SDI, RCLK y SRCLK corresponden a los pines de Entrada de Datos Serial, Entrada de Reloj de Memoria (Reloj de Registro) y Reloj de Registro de Desplazamiento del 74HC595.

   .. code-block:: python

       # GPIO pins connected to 74HC595 shift register
       SDI = OutputDevice(17)   # Serial Data Input
       RCLK = OutputDevice(18)  # Memory Clock Input (Register Clock)
       SRCLK = OutputDevice(27) # Shift Register Clock


#. ``segCode`` es una matriz que contiene códigos hexadecimales para cada dígito que se mostrará en la pantalla de 7 segmentos.

   .. code-block:: python

       # Hexadecimal digit codes for a common cathode 7-segment display
       segCode = [
           0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d,
           0x07, 0x7f, 0x6f, 0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71
       ]

#. Esta función desplaza 8 bits de datos en el 74HC595. Introduce cada bit en serie en ``SDI``, alterna ``SRCLK`` para desplazar el bit y usa ``RCLK`` para fijar los datos en la salida.

   .. code-block:: python

       def hc595_shift(data):
           # Shift 8 bits of data into the 74HC595
           for bit in range(8):
               # Set SDI high or low based on data bit
               SDI.value = 0x80 & (data << bit)
               # Trigger shift register clock
               SRCLK.on()
               sleep(0.001)
               SRCLK.off()
           # Latch data to output by triggering memory clock
           RCLK.on()
           sleep(0.001)
           RCLK.off()

#. Esta función enciende todos los segmentos de la pantalla enviando un código específico a ``hc595_shift``.

   .. code-block:: python

       def display_all_on():
           # Function to turn all segments on (for common cathode 7-segment display)
           all_on_code = 0x3f
           hc595_shift(all_on_code)
           print("Displaying all segments on")

#. En el bucle principal, cada código en ``segCode`` se envía a la pantalla en secuencia, con un retraso entre cada uno.

   .. code-block:: python

       try:
           while True:
               # Display each hexadecimal digit on 7-segment display
               for code in segCode:
                   hc595_shift(code)  # Shift the code into 74HC595
                   # Print the displayed segment code
                   print(f"Displaying segCode[{segCode.index(code)}]: 0x{code:02X}")
                   sleep(0.5)  # Pause between displaying each digit

#. Esta parte del código maneja de manera adecuada la interrupción del script (como Ctrl+C).

   .. code-block:: python

       except KeyboardInterrupt:
           # Gracefully handle script interruption (e.g., Ctrl+C)
           pass

