.. note:: Ciao, benvenuto nella Community di appassionati di SunFounder Raspberry Pi & Arduino & ESP32 su Facebook! Approfondisci le tue conoscenze su Raspberry Pi, Arduino ed ESP32 insieme ad altri appassionati. **Perché unirti?** - **Supporto esperto**: Risolvi i problemi post-vendita e le sfide tecniche con l'aiuto della nostra community 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 anteprime esclusive. - **Sconti Speciali**: Approfitta di sconti esclusivi sui nostri nuovi prodotti. - **Promozioni e Omaggi Festivi**: Partecipa a omaggi e promozioni speciali per le festività. 👉 Pronto a esplorare e creare con noi? Clicca su [|link_sf_facebook|] e unisciti oggi! .. _4.1.18_py_pi5: 4.1.15 GIOCO - 10 Secondi ============================== Introduzione ------------------- Seguimi per creare un dispositivo di gioco che metterà alla prova la tua concentrazione. Fissa un interruttore di inclinazione a un bastoncino 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**, hai vinto. Puoi sfidare i tuoi amici per vedere chi è il mago del tempo. Componenti Necessari ------------------------------ In questo progetto, abbiamo bisogno dei seguenti componenti. .. image:: ../python_pi5/img/4.1.18_game_10_second_list.png :width: 800 :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 * - Kit Raphael - 337 - |link_Raphael_kit| Puoi anche acquistare i componenti separatamente dai link sottostanti. .. list-table:: :widths: 30 20 :header-rows: 1 * - INTRODUZIONE AI COMPONENTI - LINK PER L'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 del Circuito ------------------------ ============ ======== ======== === 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.18_game_10_second_schematic.png :align: center Procedure Sperimentali --------------------------------- **Passo 1**: Assembla il circuito. .. image:: ../python_pi5/img/4.1.18_game_10_second_circuit.png **Passo 2**: Vai alla cartella del codice. .. raw:: html .. code-block:: cd ~/raphael-kit/python-pi5 **Passo 3**: Esegui il file eseguibile. .. raw:: html .. code-block:: sudo python3 4.1.18_GAME_10Second_zero.py Agita la bacchetta, 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**, hai vinto. Agita ancora una volta per iniziare il prossimo round del gioco. .. warning:: Se viene visualizzato l'errore ``RuntimeError: Cannot determine SOC peripheral base address``, fare riferimento a :ref:`faq_soc`. **Code** .. note:: Puoi **Modificare/Reimpostare/Copiare/Eseguire/Interrompere** il codice qui sotto. Tuttavia, prima di farlo, devi accedere al percorso sorgente del codice, come ad esempio ``raphael-kit/python-pi5``. Dopo aver modificato il codice, puoi eseguirlo direttamente per vedere l'effetto. .. raw:: html .. code-block:: python #!/usr/bin/env python3 from gpiozero import OutputDevice, Button import time import threading # Inizializza il pulsante collegato al GPIO 26 sensorPin = Button(26) # Definisce i pin GPIO collegati al registro a scorrimento 74HC595 SDI = OutputDevice(24) # Input dati seriali RCLK = OutputDevice(23) # Clock del registro SRCLK = OutputDevice(18) # Clock del registro a scorrimento # Definisce i pin GPIO per la selezione delle cifre sul display a 7 segmenti placePin = [OutputDevice(pin) for pin in (10, 22, 27, 17)] # Definisce i codici per i segmenti dei numeri da 0 a 9 sul display a 7 segmenti number = (0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90) # Variabili per il contatore e il timer 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 and timer1 is not 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() **Spiegazione del Codice** #. Lo script inizia importando i moduli necessari. La libreria ``gpiozero`` viene utilizzata per interfacciarsi con i dispositivi GPIO come i pulsanti, mentre i moduli ``time`` e ``threading`` possono essere utilizzati per gestire operazioni relative al tempo o simultanee. .. code-block:: python #!/usr/bin/env python3 from gpiozero import OutputDevice, Button import time import threading #. Inizializza un oggetto ``Button`` dalla libreria GPIO Zero, collegandolo al pin GPIO 26. Questa configurazione consente il rilevamento delle pressioni del pulsante. .. code-block:: python # Inizializza il pulsante collegato al GPIO 26 sensorPin = Button(26) #. Inizializza i pin GPIO collegati agli ingressi Serial Data Input (SDI), Register Clock Input (RCLK) e Shift Register Clock Input (SRCLK) del registro a scorrimento. .. code-block:: python # Definisce i pin GPIO collegati al registro a scorrimento 74HC595 SDI = OutputDevice(24) # Input dati seriali RCLK = OutputDevice(23) # Clock del registro SRCLK = OutputDevice(18) # Clock del registro a scorrimento #. Inizializza i pin per ciascuna cifra del display a 7 segmenti e definisce i codici binari per visualizzare i numeri da 0 a 9. .. code-block:: python # Definisce i pin GPIO per la selezione delle cifre sul display a 7 segmenti placePin = [OutputDevice(pin) for pin in (10, 22, 27, 17)] # Definisce i codici per i segmenti dei numeri da 0 a 9 sul display a 7 segmenti number = (0xc0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90) #. Funzioni per controllare il display a 7 segmenti. ``clearDisplay`` spegne tutti i segmenti, ``hc595_shift`` sposta i dati nel registro a scorrimento, e ``pickDigit`` attiva una cifra specifica sul display. .. 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() #. Funzione per visualizzare il valore corrente del contatore sul display a 7 segmenti. .. 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]) #. Funzione per gestire i cambi di stato (avvio/arresto) del contatore in base alle pressioni del pulsante. .. 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 #. Ciclo principale che controlla continuamente lo stato del pulsante e aggiorna il display. Richiama ``stateChange`` quando lo stato del pulsante 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 #. Funzione timer che incrementa il contatore a intervalli regolari (ogni 0,01 secondi). .. 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 #. Esegue il ciclo principale e consente un'uscita pulita dal programma utilizzando un'interruzione della tastiera (Ctrl+C). .. code-block:: python try: loop() except KeyboardInterrupt: if timer1: timer1.cancel()