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 [Ici] et rejoignez-nous aujourd’hui !

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.

../_images/list_GAME_Guess_Number.png

Il est certainement pratique d’acheter un kit complet, voici le lien :

Nom

ÉLÉMENTS DANS CE KIT

LIEN

Kit Raphael

337

Raphael Kit

Vous pouvez également les acheter séparément à partir des liens ci-dessous.

INTRODUCTION DU COMPOSANT

LIEN D’ACHAT

Carte d’extension GPIO

ACHETER

Plaque d’expérimentation (Breadboard)

ACHETER

Fils de Liaison

ACHETER

Résistance

ACHETER

Clavier

-

LCD1602 I2C

ACHETER

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)

../_images/Schematic_three_one12.png

Procédures Expérimentales

Étape 1 : Construisez le circuit.

../_images/image273.png

Étape 2 : Configurer l’I2C (voir Configuration I²C.)

Étape 3 : Changez de répertoire.

cd ~/raphael-kit/python/

Étape 4 : Exécutez.

sudo python3 4.1.17_GAME_GuessNumber.py

Après l’exécution du programme, la page initiale s’affiche sur le LCD :

Welcome!
Press A to go!

Appuyez sur ‘A’, et le jeu commencera et la page de jeu apparaîtra sur le LCD.

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 à Configuration I²C 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.

#!/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 1.1.7 I2C LCD1602 et 2.1.8 Clavier.

Voici ce que nous devons savoir :

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.

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

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.

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

../_images/image274.jpeg