.. note::

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

    **Perché unirti a noi?**

    - **Supporto esperto**: Risolvi i problemi post-vendita e le sfide tecniche con l'aiuto della nostra community e del nostro team.
    - **Impara & Condividi**: Scambia suggerimenti e tutorial per migliorare le tue competenze.
    - **Anteprime esclusive**: Accedi in anteprima agli annunci di nuovi prodotti e alle anticipazioni.
    - **Sconti speciali**: Approfitta di sconti esclusivi sui nostri nuovi prodotti.
    - **Promozioni e Giveaway**: Partecipa a promozioni festive e giveaway.

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

.. _4.1.18_py:


4.1.18 GIOCO - 10 Secondi
===================================

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

Ora ti guiderò nella creazione di un dispositivo di gioco per sfidare la tua concentrazione.
Fissa l'interruttore a inclinazione a un bastone per creare una bacchetta magica. Agita la 
bacchetta e il display a 4 cifre inizierà a contare, agitala di nuovo per fermare il conteggio. 
Se riesci a mantenere il conteggio visualizzato su **10.00**, allora hai vinto. Puoi giocare 
con i tuoi amici per vedere chi è il mago del tempo.


Componenti necessari
------------------------------

In questo progetto, ci servono i seguenti componenti.

.. image:: ../img/list_GAME_10_Second.png
    :align: center

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

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

    *   - Nome	
        - ELEMENTI IN QUESTO KIT
        - LINK
    *   - Raphael Kit
        - 337
        - |link_Raphael_kit|

Puoi anche acquistare i componenti separatamente dai link qui sotto.

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

    *   - INTRODUZIONE COMPONENTI
        - LINK 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_4_digit`
        - \-
    *   - :ref:`cpn_74hc595`
        - |link_74hc595_buy|
    *   - :ref:`cpn_tilt_switch`
        - \-



Schema elettrico
------------------------

============ ======== ======== ===
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:: ../img/Schematic_three_one13.png
   :align: center

Procedure sperimentali
---------------------------------

**Passo 1**: Costruisci il circuito.

.. image:: ../img/image277.png

**Passo 2**: Vai alla cartella del codice.

.. raw:: html

   <run></run>

.. code-block::

    cd ~/raphael-kit/python/

**Passo 3**: Esegui il file eseguibile.

.. raw:: html

   <run></run>

.. code-block::

    sudo python3 4.1.18_GAME_10Second.py

Agita la bacchetta magica, il display a 4 cifre inizierà a contare, agitala di 
nuovo per fermare il conteggio. Se riesci a fermare il conteggio a **10.00**, 
hai vinto. Agitala ancora una volta per iniziare un nuovo round del gioco.

**Codice**

.. note::
    Puoi **Modificare/Reimpostare/Copiare/Eseguire/Interrompere** il codice qui sotto. Ma prima di farlo, devi andare nel percorso del codice sorgente come ``raphael-kit/python``. Dopo aver modificato il codice, puoi eseguirlo direttamente per vedere l'effetto.

.. raw:: html

    <run></run>

.. code-block:: python

    #!/usr/bin/env python3
    import RPi.GPIO as GPIO
    import time
    import threading

    sensorPin = 26

    SDI = 24
    RCLK = 23
    SRCLK = 18

    placePin = (10, 22, 27, 17)
    number = (0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90)

    counter = 0
    timer =0
    gameState =0

    def clearDisplay():
        for i in range(8):
            GPIO.output(SDI, 1)
            GPIO.output(SRCLK, GPIO.HIGH)
            GPIO.output(SRCLK, GPIO.LOW)
        GPIO.output(RCLK, GPIO.HIGH)
        GPIO.output(RCLK, GPIO.LOW)    

    def hc595_shift(data): 
        for i in range(8):
            GPIO.output(SDI, 0x80 & (data << i))
            GPIO.output(SRCLK, GPIO.HIGH)
            GPIO.output(SRCLK, GPIO.LOW)
        GPIO.output(RCLK, GPIO.HIGH)
        GPIO.output(RCLK, GPIO.LOW)

    def pickDigit(digit):
        for i in placePin:
            GPIO.output(i,GPIO.LOW)
        GPIO.output(placePin[digit], GPIO.HIGH)

    def 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():
        global gameState
        global counter
        global timer1
        if gameState == 0:
            counter = 0
            time.sleep(1)
            timer() 
        elif gameState ==1:
            timer1.cancel()
            time.sleep(1)
        gameState = (gameState+1)%2

    def loop():
        global counter
        currentState = 0
        lastState = 0
        while True:
            display()
            currentState=GPIO.input(sensorPin)
            if (currentState == 0) and (lastState == 1):
                stateChange()
            lastState=currentState

    def timer():  
        global counter
        global timer1
        timer1 = threading.Timer(0.01, timer) 
        timer1.start()  
        counter += 1

    def setup():
        GPIO.setmode(GPIO.BCM)
        GPIO.setup(SDI, GPIO.OUT)
        GPIO.setup(RCLK, GPIO.OUT)
        GPIO.setup(SRCLK, GPIO.OUT)
        for i in placePin:
            GPIO.setup(i, GPIO.OUT)
        GPIO.setup(sensorPin, GPIO.IN)

    def destroy():   # Quando si preme "Ctrl+C", viene eseguita questa funzione.
        GPIO.cleanup()
        global timer1
        timer1.cancel()

    if __name__ == '__main__':  # Programma che parte da qui
        setup()
        try:
            loop()
        except KeyboardInterrupt:
            destroy()

**Spiegazione del Codice**

.. code-block:: python

    def stateChange():
        global gameState
        global counter
        global timer1
        if gameState == 0:
            counter = 0
            time.sleep(1)
            timer() 
        elif gameState ==1:
            timer1.cancel()
            time.sleep(1)
        gameState = (gameState+1)%2

Il gioco è diviso in due modalità:

``gameState==0`` è la modalità "start", in cui il tempo viene cronometrato e
visualizzato sul display a 7 segmenti, e scuotendo l'interruttore a inclinazione 
si entra nella modalità "show".

``gameState==1`` è la modalità "show", che interrompe il conteggio e visualizza il 
tempo sul display a 7 segmenti. Scuotendo nuovamente l'interruttore a inclinazione 
si resetta il cronometro e si riavvia il gioco.

.. code-block:: python

    def loop():
        global counter
        currentState = 0
        lastState = 0
        while True:
            display()
            currentState=GPIO.input(sensorPin)
            if (currentState == 0) and (lastState == 1):
                stateChange()
            lastState=currentState

``loop()`` è la funzione principale. Prima viene visualizzato il tempo sul display a 
7 segmenti e viene letta la variazione di stato dell'interruttore a inclinazione. Se 
lo stato cambia, viene chiamata la funzione ``stateChange()``.

.. code-block:: python

    def timer():  
        global counter
        global timer1
        timer1 = threading.Timer(0.01, timer) 
        timer1.start()  
        counter += 1

Dopo che l'intervallo raggiunge 0,01s, la funzione timer viene chiamata; viene 
aggiunto 1 al contatore, e il timer viene utilizzato nuovamente per eseguire se 
stesso ripetutamente ogni 0,01s.

Immagine del Fenomeno
---------------------------

.. image:: ../img/image278.jpeg
   :align: center



