.. note::

    Ciao, benvenuto nella Community di SunFounder Raspberry Pi & Arduino & ESP32 Enthusiasts su Facebook! Approfondisci il mondo di Raspberry Pi, Arduino ed ESP32 insieme ad altri appassionati.

    **Perché unirti a noi?**

    - **Supporto tecnico esperto**: Risolvi problemi post-vendita e sfide tecniche con l'aiuto della nostra comunità e del nostro team.
    - **Impara e condividi**: Scambia consigli e tutorial per migliorare le tue competenze.
    - **Anteprime esclusive**: Ottieni accesso anticipato agli annunci di nuovi prodotti e alle anteprime.
    - **Sconti speciali**: Approfitta di sconti esclusivi sui nostri prodotti più recenti.
    - **Promozioni festive e giveaway**: Partecipa a giveaway e promozioni durante le festività.

    👉 Sei pronto a esplorare e creare con noi? Clicca [|link_sf_facebook|] e unisciti oggi stesso!

.. _1.1.4_py_pi5:

1.1.4 Display a 7 segmenti
=============================

Introduzione
-----------------

Proviamo a pilotare un display a 7 segmenti per visualizzare una cifra da 0 a 9 e
da A a F.

Componenti Necessari
------------------------------

Per questo progetto, avremo bisogno dei seguenti componenti. 

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

È decisamente conveniente acquistare un kit completo, ecco il link:

.. list-table::
    :widths: 20 20 20
    :header-rows: 1

    *   - Nome	
        - COMPONENTI NEL KIT
        - LINK
    *   - Raphael Kit
        - 337
        - |link_Raphael_kit|

Puoi anche acquistarli separatamente dai link sottostanti.

.. list-table::
    :widths: 30 20
    :header-rows: 1

    *   - INTRODUZIONE AI COMPONENTI
        - LINK D'ACQUISTO

    *   - :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|


Schema Elettrico
---------------------

Collega il pin ST_CP del 74HC595 al GPIO18 del Raspberry Pi, SH_CP al GPIO27, DS
al GPIO17 e le porte di uscita parallele agli 8 segmenti del display a 7 segmenti.

Inserisci i dati nel pin DS nel registro a scorrimento quando SH_CP (l'ingresso di clock
del registro a scorrimento) è al fronte di salita, e nel registro di memoria
quando ST_CP (l'ingresso di clock della memoria) è al fronte di salita.

Quindi puoi controllare gli stati di SH_CP e ST_CP tramite i
GPIO del Raspberry Pi per trasformare i dati seriali in ingresso in dati paralleli
in uscita, in modo da risparmiare GPIO del Raspberry Pi e pilotare il display.

============ ======== ===
T-Board Name physical BCM
GPIO17       Pin 11   17
GPIO18       Pin 12   18
GPIO27       Pin 13   27
============ ======== ===

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


Procedure Sperimentali
------------------------------

**Passo 1:** Costruisci il circuito.

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

**Passo 2:** Entra nella cartella del codice.

.. raw:: html

   <run></run>

.. code-block::

    cd ~/raphael-kit/python-pi5

**Passo 3:** Esegui.

.. raw:: html

   <run></run>

.. code-block::

    sudo python3 1.1.4_7-Segment_zero.py

Dopo l'esecuzione del codice, vedrai il display a 7 segmenti visualizzare 0-9, A-F.

.. warning::

    Se viene visualizzato l'errore ``RuntimeError: Cannot determine SOC peripheral base address``, fare riferimento a :ref:`faq_soc`. 

**Code**

.. note::
    Puoi **Modificare/Reset/Copy/Esegui/Ferma** il codice qui sotto. Ma prima, devi andare nella directory del codice come ``raphael-kit/python-pi5``. Dopo aver modificato il codice, puoi eseguirlo direttamente per vedere l'effetto. Dopo aver confermato che non ci sono problemi, puoi utilizzare il pulsante Copy per copiare il codice modificato, quindi aprire il codice sorgente nel Terminal tramite il comando ``nano`` e incollarlo.

.. raw:: html

    <run></run>

.. code-block:: python

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

   # Pin GPIO collegati al registro a scorrimento 74HC595
   SDI = OutputDevice(17)   # Ingresso Dati Seriali
   RCLK = OutputDevice(18)  # Ingresso Clock Memoria (Clock del Registro)
   SRCLK = OutputDevice(27) # Clock del Registro a Scorrimento

   # Codici esadecimali per i display a 7 segmenti a catodo comune
   segCode = [
       0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d,
       0x07, 0x7f, 0x6f, 0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71
   ]

   def hc595_shift(data):
       # Inserisci 8 bit di dati nel 74HC595
       per bit in range(8):
           # Imposta SDI alto o basso in base al bit dei dati
           SDI.value = 0x80 & (data << bit)
           # Attiva il clock del registro a scorrimento
           SRCLK.on()
           sleep(0.001)
           SRCLK.off()
       # Latch dei dati all'uscita attivando il clock della memoria
       RCLK.on()
       sleep(0.001)
       RCLK.off()

   def display_all_on():
       # Funzione per accendere tutti i segmenti (per display a 7 segmenti a catodo comune)
       all_on_code = 0x3f
       hc595_shift(all_on_code)
       print("Displaying all segments on")

   try:
       while True:
           # Visualizza ciascuna cifra esadecimale sul display a 7 segmenti
           per code in segCode:
               hc595_shift(code)  # Inserisci il codice nel 74HC595
               # Stampa il codice del segmento visualizzato
               print(f"Displaying segCode[{segCode.index(code)}]: 0x{code:02X}")
               sleep(0.5)  # Pausa tra la visualizzazione di ciascuna cifra

   except KeyboardInterrupt:
       # Gestisci in modo sicuro l'interruzione dello script (es. Ctrl+C)
       pass


**Spiegazione del Codice**

#. Questo snippet importa le classi necessarie per il progetto. ``OutputDevice`` dalla libreria ``gpiozero`` viene utilizzato per controllare i componenti hardware collegati ai pin GPIO, e ``sleep`` dalla libreria ``time`` serve per aggiungere dei ritardi.

   .. code-block:: python

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

#. SDI, RCLK e SRCLK corrispondono ai pin Serial Data Input, Memory Clock Input (Clock del Registro) e Shift Register Clock del 74HC595.

   .. code-block:: python

       # Pin GPIO collegati al registro a scorrimento 74HC595
       SDI = OutputDevice(17)   # Ingresso Dati Seriali
       RCLK = OutputDevice(18)  # Ingresso Clock Memoria (Clock del Registro)
       SRCLK = OutputDevice(27) # Clock del Registro a Scorrimento


#. ``segCode`` è un array che contiene i codici esadecimali per ciascuna cifra da visualizzare sul display a 7 segmenti.

   .. code-block:: python

       # Codici esadecimali per i display a 7 segmenti a catodo comune
       segCode = [
           0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d,
           0x07, 0x7f, 0x6f, 0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71
       ]

#. Questa funzione inserisce 8 bit di dati nel 74HC595. Inserisce serialmente ciascun bit in ``SDI``, alterna ``SRCLK`` per spostare il bit e utilizza ``RCLK`` per latchare i dati sull'uscita.

   .. code-block:: python

       def hc595_shift(data):
           # Inserisci 8 bit di dati nel 74HC595
           per bit in range(8):
               # Imposta SDI alto o basso in base al bit dei dati
               SDI.value = 0x80 & (data << bit)
               # Attiva il clock del registro a scorrimento
               SRCLK.on()
               sleep(0.001)
               SRCLK.off()
           # Latch dei dati all'uscita attivando il clock della memoria
           RCLK.on()
           sleep(0.001)
           RCLK.off()

#. Questa funzione accende tutti i segmenti del display inviando un codice specifico a ``hc595_shift``.

   .. code-block:: python

       def display_all_on():
           # Funzione per accendere tutti i segmenti (per display a 7 segmenti a catodo comune)
           all_on_code = 0x3f
           hc595_shift(all_on_code)
           print("Displaying all segments on")

#. Nel ciclo principale, ciascun codice in ``segCode`` viene inviato al display in sequenza, con un ritardo tra ciascuno.

   .. code-block:: python

       try:
           while True:
               # Visualizza ciascuna cifra esadecimale sul display a 7 segmenti
               per code in segCode:
                   hc595_shift(code)  # Inserisci il codice nel 74HC595
                   # Stampa il codice del segmento visualizzato
                   print(f"Displaying segCode[{segCode.index(code)}]: 0x{code:02X}")
                   sleep(0.5)  # Pausa tra la visualizzazione di ciascuna cifra

#. Questa parte del codice gestisce in modo sicuro l'interruzione dello script (come Ctrl+C).

   .. code-block:: python

       except KeyboardInterrupt:
           # Gestisci in modo sicuro l'interruzione dello script (es. Ctrl+C)
           pass

