Nota

¡Hola! Bienvenido a la Comunidad de Entusiastas de SunFounder Raspberry Pi & Arduino & ESP32 en Facebook. Sumérgete más en Raspberry Pi, Arduino y ESP32 con otros entusiastas.

¿Por qué unirse?

  • Soporte experto: Resuelve problemas postventa y desafíos técnicos con la ayuda de nuestra comunidad y equipo.

  • Aprende y comparte: Intercambia consejos y tutoriales para mejorar tus habilidades.

  • Previsualizaciones exclusivas: Obtén acceso anticipado a nuevos anuncios de productos y adelantos.

  • Descuentos especiales: Disfruta de descuentos exclusivos en nuestros productos más nuevos.

  • Promociones y sorteos festivos: Participa en sorteos y promociones navideñas.

👉 ¿Listo para explorar y crear con nosotros? Haz clic en [Aquí] y únete hoy mismo.

4.1.17 JUEGO – Adivina el Número

Introducción

Adivinar Números es un divertido juego de fiesta donde tú y tus amigos toman turnos para ingresar un número (0~99). El rango será más pequeño con la entrada del número hasta que un jugador responda el acertijo correctamente. Entonces el jugador es derrotado y castigado. Por ejemplo, si el número de la suerte es 51, que los jugadores no pueden ver, y el jugador ① ingresa 50, el rango de números cambia a 50~99; si el jugador ② ingresa 70, el rango de números puede ser 50~70; si el jugador ③ ingresa 51, este jugador es el desafortunado. Aquí, usamos un teclado para ingresar números y una pantalla LCD para mostrar los resultados.

Componentes necesarios

En este proyecto, necesitamos los siguientes componentes.

../_images/list_GAME_Guess_Number.png

Es definitivamente conveniente comprar un kit completo, aquí está el enlace:

Nombre

ARTÍCULOS EN ESTE KIT

ENLACE

Kit Raphael

337

Raphael Kit

También puedes comprarlos por separado en los enlaces a continuación.

INTRODUCCIÓN DEL COMPONENTE

ENLACE DE COMPRA

Placa de Extensión GPIO

COMPRAR

Protoboard

COMPRAR

Cables de Puente

COMPRAR

Resistor

COMPRAR

Teclado

-

I2C LCD1602

COMPRAR

Diagrama esquemático

Nombre T-Board

Pin físico

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

Procedimientos Experimentales

Paso 1: Construye el circuito.

../_images/image273.png

Paso 2: Configura I2C (ver Configuración de I²C).

Paso 3: Cambia de directorio.

cd ~/raphael-kit/python/

Paso 4: Ejecuta.

sudo python3 4.1.17_GAME_GuessNumber.py

Después de que el programa se ejecute, se muestra la página inicial en la LCD:

Welcome!
Press A to go!

Presiona “A” y el juego comenzará y la página del juego aparecerá en la LCD.

Enter number:
0 ‹punto‹ 99

Se produce un número aleatorio “punto” pero no se muestra en la LCD cuando el juego comienza, y lo que necesitas hacer es adivinarlo. El número que has escrito aparece al final de la primera línea hasta que se finaliza el cálculo. (Presiona “D” para iniciar la comparación, y si el número ingresado es mayor que 10, la comparación automática comenzará).

El rango de números de “punto” se muestra en la segunda línea. Y debes escribir el número dentro del rango. Cuando escribes un número, el rango se reduce; si adivinaste el número de la suerte afortunada o desafortunadamente, aparecerá «¡Lo conseguiste!».

Nota

  • Si obtienes el error FileNotFoundError: [Errno 2] No such file or directory: '/dev/i2c-1', necesitas consultar Configuración de I²C para habilitar el I2C.

  • Si obtienes el error ModuleNotFoundError: No module named 'smbus2', por favor ejecuta sudo apt install python3-smbus2.

  • Si aparece el error OSError: [Errno 121] Remote I/O error, significa que el módulo está mal conectado o está dañado.

  • Si el código y las conexiones están bien, pero la LCD aún no muestra contenido, puedes girar el potenciómetro en la parte posterior para aumentar el contraste.

Código

Nota

Puedes Modificar/Restablecer/Copiar/Ejecutar/Detener el código a continuación. Pero antes de eso, necesitas ir a la ruta del código fuente como raphael-kit/python. Después de modificar el código, puedes ejecutarlo directamente para ver el efecto.

#!/usr/bin/env python3

import RPi.GPIO as GPIO
import time
import LCD1602
import random

##################### AQUÍ ESTÁ LA LIBRERÍA DE TECLADO TRANSPLANTADA DESDE Arduino ############
#class Key: Define algunas propiedades de 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

################ EL CÓDIGO DE EJEMPLO EMPIEZA AQUÍ ################

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 una función destroy para limpiar todo después de que el script termine
def destroy():
   # Liberar recursos
   GPIO.cleanup()
   LCD1602.clear()

if __name__ == '__main__':     # Program start from here
   try:
      setup()
      while True:
            loop()
   except KeyboardInterrupt:   # Cuando se presiona 'Ctrl+C', se ejecutará la función destroy().
      destroy()

Explicación del Código

En la parte inicial del código se encuentran las funciones funcionales del teclado y del I2C LCD1602. Puedes aprender más detalles sobre ellas en 1.1.7 I2C LCD1602 y 2.1.8 Teclado.

Aquí, lo que necesitamos saber es lo siguiente:

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 función produce el número aleatorio ‘point’ y restablece el rango de pistas del punto.

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() compara el número ingresado (count) con el número producido “point”. Si el resultado de la comparación indica que no son iguales, count asignará valores a upper y lower y devolverá ‘0’; de lo contrario, si el resultado indica que son iguales, se devolverá ‘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))

Esta función se utiliza para mostrar la página del juego.

str(count): Debido a que write() solo puede soportar el tipo de dato — cadena , se necesita str() para convertir el número en cadena.

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 todo el proceso del programa, como se muestra a continuación:

  1. Inicializa I2C LCD1602 y Keypad.

  2. Juzga si se ha presionado el botón y obtiene la lectura del botón.

  3. Si se presiona el botón ‘A’, aparecerá un número aleatorio 0-99 y luego comenzará el juego.

  4. Si se detecta que el botón ‘D’ ha sido presionado, el programa entrará en el juicio del resultado.

  5. Si se presiona el botón 0-9, el valor de count cambiará; si count es mayor que 10, entonces comenzará el juicio.

  6. Los cambios del juego y sus valores se muestran en LCD1602.

Imagen del Fenómeno

../_images/image274.jpeg