.. 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