.. note:: Ciao, benvenuto nella Community di appassionati di Raspberry Pi, Arduino e ESP32 di SunFounder su Facebook! Approfondisci il mondo di Raspberry Pi, Arduino e ESP32 insieme ad altri appassionati. **Perché unirsi?** - **Supporto esperto**: Risolvi problemi post-vendita e sfide tecniche con l'aiuto della nostra community e del nostro team. - **Impara & Condividi**: Scambia consigli e tutorial per migliorare le tue competenze. - **Anteprime esclusive**: Ottieni accesso anticipato agli annunci di nuovi prodotti e anteprime. - **Sconti speciali**: Approfitta di sconti esclusivi sui nostri prodotti più recenti. - **Promozioni festive e giveaway**: Partecipa a giveaway e promozioni festive. 👉 Pronto per esplorare e creare con noi? Clicca [|link_sf_facebook|] e unisciti oggi stesso! .. _4.1.17_py: 4.1.17 GIOCO – Indovina il Numero ============================================== Introduzione ------------------ "Indovina il Numero" è un gioco divertente da fare in gruppo, in cui tu e i tuoi amici vi alterniate nell'inserire un numero (0~99). L'intervallo numerico si riduce con l'inserimento del numero finché un giocatore non indovina correttamente l'enigma. Allora il giocatore viene sconfitto e punito. Ad esempio, se il numero fortunato è 51, che i giocatori non possono vedere, e il giocatore ① inserisce 50, l'intervallo numerico cambia a 50~99; se il giocatore ② inserisce 70, l'intervallo numerico diventa 50~70; se il giocatore ③ inserisce 51, questo giocatore è il "sfortunato". Qui utilizziamo il tastierino per inserire i numeri e l'LCD per mostrare i risultati. Componenti Necessari ------------------------------ In questo progetto, ci servono i seguenti componenti. .. image:: ../img/list_GAME_Guess_Number.png :align: center È sicuramente conveniente acquistare un intero kit, 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 acquistarli separatamente dai link qui sotto. .. list-table:: :widths: 30 20 :header-rows: 1 * - INTRODUZIONE COMPONENTE - LINK DI 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_keypad` - \- * - :ref:`cpn_i2c_lcd` - |link_i2clcd1602_buy| Schema Elettrico ----------------------- ============ ======== ======== ======= T-Board Name physical wiringPi BCM GPIO18 Pin 12 1 18 GPIO23 Pin 16 4 23 GPIO24 Pin 18 5 24 GPIO25 Pin 22 6 25 SPIMOSI Pin 19 12 10 GPIO22 Pin 15 3 22 GPIO27 Pin 13 2 27 GPIO17 Pin 11 0 17 SDA1 Pin 3 SDA1(8) SDA1(2) SCL1 Pin 5 SCL1(9) SDA1(3) ============ ======== ======== ======= .. image:: ../img/Schematic_three_one12.png :align: center Procedure Sperimentali ----------------------------- **Passo 1:** Costruisci il circuito. .. image:: ../img/image273.png **Passo 2**: Configura I2C (vedi :ref:`i2c_config`.) **Passo 3**: Cambia directory. .. raw:: html .. code-block:: cd ~/raphael-kit/python/ **Passo 4**: Esegui. .. raw:: html .. code-block:: sudo python3 4.1.17_GAME_GuessNumber.py Dopo l'avvio del programma, sulla LCD appare la pagina iniziale: .. code-block:: Welcome! Press A to go! Press ‘A’, and the game will start and the game page will appear on the LCD. .. code-block:: Inserisci numero: 0 ‹punto‹ 99 Un numero casuale ' \ **punto**\ ' viene generato ma non visualizzato sull'LCD quando il gioco inizia, e il tuo compito è indovinarlo. Il numero che hai digitato appare alla fine della prima riga fino a quando non viene effettuato il calcolo finale. (Premi 'D' per avviare il confronto e se il numero inserito è maggiore di **10** , il confronto automatico inizia.) L'intervallo numerico di 'punto' viene visualizzato sulla seconda riga. Devi inserire il numero all'interno dell'intervallo. Quando inserisci un numero, l'intervallo si restringe; se indovini correttamente o meno, apparirà "L'hai preso!" .. note:: * Se visualizzi l'errore ``FileNotFoundError: [Errno 2] No such file or directory: '/dev/i2c-1'``, devi fare riferimento a :ref:`i2c_config` per abilitare l'I2C. * Se ricevi l'errore ``ModuleNotFoundError: No module named 'smbus2'``, esegui ``sudo apt install python3-smbus2``. * Se compare l'errore ``OSError: [Errno 121] Remote I/O error``, significa che il modulo è cablato in modo errato o è guasto. * Se il codice e il cablaggio sono corretti, ma l'LCD non mostra ancora contenuti, puoi regolare il potenziometro sul retro per aumentare il contrasto. **Codice** .. note:: Puoi **Modificare/Reimpostare/Copiare/Eseguire/Interrompere** il codice qui sotto. Tuttavia, prima di fare ciò, devi accedere al percorso del codice sorgente come ``raphael-kit/python``. .. raw:: html .. code-block:: python #!/usr/bin/env python3 import RPi.GPIO as GPIO import time import LCD1602 import random ##################### ECCO LA LIBRERIA KEYPAD TRASFERITA DA Arduino ############ #class Key:Definisci alcune delle proprietà di Key class Keypad(): def __init__(self, rowsPins, colsPins, keys): self.rowsPins = rowsPins self.colsPins = colsPins self.keys = keys GPIO.setwarnings(False) GPIO.setmode(GPIO.BCM) GPIO.setup(self.rowsPins, GPIO.OUT, initial=GPIO.LOW) GPIO.setup(self.colsPins, GPIO.IN, pull_up_down=GPIO.PUD_DOWN) def read(self): pressed_keys = [] for i, row in enumerate(self.rowsPins): GPIO.output(row, GPIO.HIGH) for j, col in enumerate(self.colsPins): index = i * len(self.colsPins) + j if (GPIO.input(col) == 1): pressed_keys.append(self.keys[index]) GPIO.output(row, GPIO.LOW) return pressed_keys ################ ESEMPIO DI CODICE INIZIA QUI ################ count = 0 pointValue = 0 upper=99 lower=0 def setup(): global keypad, last_key_pressed,keys rowsPins = [18,23,24,25] colsPins = [10,22,27,17] keys = ["1","2","3","A", "4","5","6","B", "7","8","9","C", "*","0","#","D"] keypad = Keypad(rowsPins, colsPins, keys) last_key_pressed = [] LCD1602.init(0x27, 1) # init(slave address, luce di sfondo) LCD1602.clear() LCD1602.write(0, 0, 'Welcome!') LCD1602.write(0, 1, 'Press A to Start!') def init_new_value(): global pointValue,upper,count,lower pointValue = random.randint(0,99) upper = 99 lower = 0 count = 0 print('point is %d' %(pointValue)) def detect_point(): global count,upper,lower if count > pointValue: if count < upper: upper = count elif count < pointValue: if count > lower: lower = count elif count == pointValue: count = 0 return 1 count = 0 return 0 def lcd_show_input(result): LCD1602.clear() if result == 1: LCD1602.write(0,1,'You have got it!') time.sleep(5) init_new_value() lcd_show_input(0) return LCD1602.write(0,0,'Enter number:') LCD1602.write(13,0,str(count)) LCD1602.write(0,1,str(lower)) LCD1602.write(3,1,' < Point < ') LCD1602.write(13,1,str(upper)) def loop(): global keypad, last_key_pressed,count while(True): result = 0 pressed_keys = keypad.read() if len(pressed_keys) != 0 and last_key_pressed != pressed_keys: if pressed_keys == ["A"]: init_new_value() lcd_show_input(0) elif pressed_keys == ["D"]: result = detect_point() lcd_show_input(result) elif pressed_keys[0] in keys: if pressed_keys[0] in list(["A","B","C","D","#","*"]): continue count = count * 10 count += int(pressed_keys[0]) if count >= 10: result = detect_point() lcd_show_input(result) print(pressed_keys) last_key_pressed = pressed_keys time.sleep(0.1) # Definisci una funzione destroy per ripulire tutto dopo la fine dello script def destroy(): # Rilascia le risorse GPIO.cleanup() LCD1602.clear() if __name__ == '__main__': # Il programma inizia qui try: setup() while True: loop() except KeyboardInterrupt: # Quando viene premuto 'Ctrl+C', il programma destroy() verrà eseguito. destroy() **Spiegazione del Codice** Nella parte iniziale del codice troviamo le funzioni operative di **keypad** e **I2C LCD1602**. Puoi approfondire maggiori dettagli su di esse nelle sezioni :ref:`1.1.7_py` e :ref:`2.1.8_py`. Qui, quello che ci serve sapere è il seguente: .. code-block:: python def init_new_value():     global pointValue,upper,count,lower     pointValue = random.randint(0,99)     upper = 99     lower = 0     count = 0     print('point is %d' %(pointValue)) La funzione genera il numero casuale ‘\ **point**\ ’ e reimposta l'intervallo indicativo del numero. .. code-block:: python def detect_point():     global count,upper,lower     if count > pointValue:         if count < upper:             upper = count      elif count < pointValue:         if count > lower:             lower = count     elif count == pointValue:         count = 0         return 1     count = 0     return 0 ``detect_point()`` confronta il numero inserito (**count**) con il numero generato “\ **point**\ ”. Se il confronto indica che non sono uguali, **count** assegnerà valori a **upper** e **lower** e restituirà ‘\ **0**\ ’; altrimenti, se sono uguali, verrà restituito ‘\ **1**\ ’. .. code-block:: python def lcd_show_input(result):     LCD1602.clear()     if result == 1:         LCD1602.write(0,1,'You have got it!')         time.sleep(5)         init_new_value()         lcd_show_input(0)         return     LCD1602.write(0,0,'Enter number:')     LCD1602.write(13,0,str(count))     LCD1602.write(0,1,str(lower))     LCD1602.write(3,1,' < Point < ')     LCD1602.write(13,1,str(upper)) Questa funzione serve a visualizzare la pagina del gioco. ``str(count)``: Poiché ``write()`` supporta solo il tipo di dati — **string**, è necessario utilizzare ``str()`` per convertire il **numero** in **string**. .. code-block:: python def loop():     global keypad, last_key_pressed,count     while(True):         result = 0         pressed_keys = keypad.read()         if len(pressed_keys) != 0 and last_key_pressed != pressed_keys:             if pressed_keys == ["A"]:                 init_new_value()                 lcd_show_input(0)             elif pressed_keys == ["D"]:                 result = detect_point()                 lcd_show_input(result)             elif pressed_keys[0] in keys:                 if pressed_keys[0] in list(["A","B","C","D","#","*"]):                     continue                 count = count * 10                 count += int(pressed_keys[0])                 if count >= 10:                     result = detect_point()                 lcd_show_input(result)             print(pressed_keys)         last_key_pressed = pressed_keys         time.sleep(0.1)     ``main()`` contiene l'intero processo del programma, come mostrato di seguito: 1) Inizializza **I2C LCD1602** e **Keypad**. 2) Verifica se il pulsante è stato premuto e ottieni la lettura del pulsante. 3) Se viene premuto il pulsante ‘\ **A**\ ’, comparirà un numero casuale **0-99** e il gioco inizierà. 4) Se viene rilevato che il pulsante ‘\ **D**\ ’ è stato premuto, il programma entrerà nella fase di giudizio del risultato. 5) Se viene premuto un pulsante da **0-9**, il valore di **count** cambierà; se **count** è maggiore di **10**, allora inizierà il giudizio. 6) Le variazioni del gioco e dei suoi valori vengono visualizzate su **LCD1602**. Immagine del Fenomeno --------------------------- .. image:: ../img/image274.jpeg :align: center