.. note:: Bonjour et bienvenue dans la Communauté Facebook des passionnés de Raspberry Pi, Arduino et ESP32 de SunFounder ! Plongez plus profondément dans l'univers des Raspberry Pi, Arduino et ESP32 avec d'autres passionnés. **Pourquoi rejoindre ?** - **Support d'experts** : Résolvez les problèmes après-vente et les défis techniques avec l'aide de notre communauté et de notre équipe. - **Apprendre et partager** : Échangez des astuces et des tutoriels pour améliorer vos compétences. - **Aperçus exclusifs** : Accédez en avant-première aux annonces de nouveaux produits et aux aperçus. - **Réductions spéciales** : Profitez de réductions exclusives sur nos produits les plus récents. - **Promotions festives et cadeaux** : Participez à des cadeaux et des promotions de vacances. 👉 Prêt à explorer et à créer avec nous ? Cliquez [|link_sf_facebook|] et rejoignez-nous aujourd'hui ! .. _4.1.17_py: 4.1.17 JEU - Devinez le Nombre ============================================== Introduction ------------------ Devinez le Nombre est un jeu amusant pour les fêtes où vous et vos amis tour à tour saisissez un nombre (0~99). La plage de nombres devient plus petite à chaque saisie jusqu'à ce qu'un joueur trouve le bon nombre. Ensuite, le joueur est battu et puni. Par exemple, si le nombre chanceux est 51 que les joueurs ne peuvent pas voir, et que le joueur ① saisit 50, l'intervalle de nombres change à 50~99 ; si le joueur ② saisit 70, l'intervalle de nombres devient 50~70 ; si le joueur ③ saisit 51, ce joueur est le malchanceux. Ici, nous utilisons un pavé numérique pour entrer les nombres et un écran LCD pour afficher les résultats. Composants Requis ------------------------------ Pour ce projet, nous avons besoin des composants suivants. .. image:: ../img/list_GAME_Guess_Number.png :align: center Il est certainement pratique d'acheter un kit complet, voici le lien : .. list-table:: :widths: 20 20 20 :header-rows: 1 * - Nom - ÉLÉMENTS DANS CE KIT - LIEN * - Kit Raphael - 337 - |link_Raphael_kit| Vous pouvez également les acheter séparément à partir des liens ci-dessous. .. list-table:: :widths: 30 20 :header-rows: 1 * - INTRODUCTION DU COMPOSANT - LIEN D'ACHAT * - :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| Schéma de Câblage ----------------------- ============ ======== ======== ======= Nom T-Board physique 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 Procédures Expérimentales ----------------------------- **Étape 1 :** Construisez le circuit. .. image:: ../img/image273.png **Étape 2** : Configurer l'I2C (voir :ref:`i2c_config`.) **Étape 3** : Changez de répertoire. .. raw:: html .. code-block:: cd ~/raphael-kit/python/ **Étape 4** : Exécutez. .. raw:: html .. code-block:: sudo python3 4.1.17_GAME_GuessNumber.py Après l'exécution du programme, la page initiale s'affiche sur le LCD : .. code-block:: Welcome! Press A to go! Appuyez sur ‘A’, et le jeu commencera et la page de jeu apparaîtra sur le LCD. .. code-block:: Enter number: 0 ‹point‹ 99 Un nombre aléatoire ‘\ **point**\ ’ est produit mais non affiché sur le LCD lorsque le jeu commence, et ce que vous devez faire est de le deviner. Le nombre que vous avez tapé apparaît à la fin de la première ligne jusqu'à ce que le calcul final soit terminé. (Appuyez sur ‘D’ pour démarrer la comparaison, et si le nombre saisi est supérieur à **10**, la comparaison automatique commencera.) La plage de nombres de ‘point’ est affichée sur la deuxième ligne. Et vous devez taper le nombre dans la plage. Lorsque vous tapez un nombre, la plage se rétrécit ; si vous avez trouvé le nombre chanceux par chance ou par malchance, il y aura l'affichage “You've got it!” .. note:: * Si vous obtenez l'erreur ``FileNotFoundError: [Errno 2] No such file or directory: '/dev/i2c-1'``, vous devez vous référer à :ref:`i2c_config` pour activer l'I2C. * Si vous obtenez l'erreur ``ModuleNotFoundError: No module named 'smbus2'``, veuillez exécuter ``sudo apt install python3-smbus2``. * Si l'erreur ``OSError: [Errno 121] Remote I/O error`` apparaît, cela signifie que le module est mal câblé ou qu'il est défectueux. * Si le code et le câblage sont corrects, mais que l'écran LCD ne s'affiche toujours pas, vous pouvez tourner le potentiomètre à l'arrière pour augmenter le contraste. **Code** .. note:: Vous pouvez **Modifier/Réinitialiser/Copier/Exécuter/Arrêter** le code ci-dessous. Mais avant cela, vous devez aller dans le chemin du code source comme ``raphael-kit/python``. Après avoir modifié le code, vous pouvez l'exécuter directement pour voir l'effet. .. raw:: html .. code-block:: python #!/usr/bin/env python3 import RPi.GPIO as GPIO import time import LCD1602 import random ##################### HERE IS THE KEYPAD LIBRARY TRANSPLANTED FROM Arduino ############ #class Key:Define some of the properties of 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 ################ EXAMPLE CODE START HERE ################ 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, background light) 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) # Define a destroy function for clean up everything after the script finished def destroy(): # Release resource GPIO.cleanup() LCD1602.clear() if __name__ == '__main__': # Program start from here try: setup() while True: loop() except KeyboardInterrupt: # When 'Ctrl+C' is pressed, the program destroy() will be executed. destroy() **Explication du Code** Au début du code, il y a les fonctions de **keypad** et **I2C LCD1602**. Vous pouvez en apprendre plus sur elles dans :ref:`1.1.7_py` et :ref:`2.1.8_py`. Voici ce que nous devons savoir : .. 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)) Cette fonction génère le nombre aléatoire ‘\ **point**\ ’ et réinitialise l'indication de la plage du point. .. 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()`` compare le nombre entré (**count**) avec le nombre généré “\ **point**\ ”. Si le résultat de la comparaison est différent, **count** attribuera des valeurs à **upper** et **lower** et retournera ‘\ **0**\ ’; sinon, s'ils sont identiques, la fonction retourne ‘\ **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)) Cette fonction sert à afficher la page du jeu. ``str(count)``: Parce que ``write()`` ne supporte que le type de données — **string**, ``str()`` est nécessaire pour convertir le **nombre** en **chaîne**. .. 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()`` contient tout le processus du programme, comme montré ci-dessous : 1) Initialiser **I2C LCD1602** et **Keypad**. 2) Vérifier si un bouton est pressé et obtenir la lecture du bouton. 3) Si le bouton ‘\ **A**\ ’ est pressé, un nombre aléatoire **0-99** apparaîtra et le jeu commence. 4) Si le bouton ‘\ **D**\ ’ est détecté comme étant pressé, le programme passera au jugement du résultat. 5) Si le bouton **0-9** est pressé, la valeur de **count** changera ; si le **count** est supérieur à **10**, le jugement commence. 6) Les changements du jeu et ses valeurs sont affichés sur **LCD1602**. Image du Phénomène ------------------------ .. image:: ../img/image274.jpeg :align: center