Simon dit, joyeux anniversaire Raspberry Pi Pico ! Sortie le 21 janvier 2021, la première puce de Raspberry Pi, le RP2040 est devenu le microcontrôleur incontournable pour 2021. La puce à 0,70 $ alimente des projets à travers le monde. De simples LED clignotantes aux cartes de contrôle des imprimantes 3D, le RP2040 est une puce polyvalente. Annoncé via le Framboise Pi Pico, une carte de développement de microcontrôleur à 4 $ qui ressemble au package DIL utilisé sur les cartes Arduino modernes, le Pico est un matériel de première partie à faible coût avec un excellent support de première et de tierce partie.
Nous aimons le Pico, c’est le bon mélange de faible coût et de facilité d’utilisation que de nombreux fabricants recherchent. La possibilité de réutiliser Compléments Raspberry Pi et composants électroniques généraux signifie que nous n’avons pas à sortir et à acheter plus d’accessoires. Non pas que le Pico manque dans ce département. Des entreprises telles que Pimoroni, Adafruit et Kitronik ont lancé des accessoires impressionnants conçus pour améliorer votre expérience Pico.
Pour fêter le premier anniversaire de Raspberry Pi Pico, nous avons créé un jeu. Ce n’est pas n’importe quel jeu, mais notre propre version de Simon, le jeu de mémoire rendu célèbre à la fin des années 1970. Le but du jeu est de faire correspondre la séquence de couleurs choisie au hasard. Si nous réussissons, nous obtenons un spectacle de lumière. Mais si vous vous trompez, nous verrons rouge.
La construction matérielle de ce projet est entièrement basée sur une planche à pain, un clin d’œil à la simplicité offerte par le Raspberry Pi Pico. Le câblage est simple : nous avons une sortie, un stick NeoPixel à huit LED, et quatre entrées sous forme de boutons à code couleur. Le Pico est programmé à l’aide de CircuitPython, l’excellent fork de MicroPython d’Adafruit avec des bibliothèques matérielles faciles à utiliser.
Alors commençons cette fête !
Pour ce projet, vous aurez besoin
Construire Simon Jeu avec Raspberry Pi Pico
Il y a deux parties dans la construction. Les quatre boutons-poussoirs forment l’interface utilisateur et le stick NeoPixel est notre sortie.
Le NeoPixel est connecté au GPIO 28 (GP28 dans CircuitPython) pour les données et utilise la broche 5V (VBUS) pour l’alimentation directement à partir du bus USB. GND se connecte à n’importe quel GND sur le Pico.
Les quatre boutons se connectent à quatre broches GPIO sur le Pico.
Couleur du bouton | Framboise Pi Pico GPIO |
rouge | GPIO 27 |
Vert | GPIO 26 |
Bleu | GPIO 22 |
Jaune | GPIO 21 |
Et en utilisant le rail négatif (marqué d’un -) sur la planche à pain, nous prenons une connexion GND (fil noir) du Pico et créons un rail GND. À partir de là, nous établissons quatre connexions GND aux boutons. Cela signifie que nos boutons tireront vers GND (Ground) lorsqu’ils seront pressés.
Le circuit final ressemble à celui ci-dessus. Vérifiez votre câblage avant de continuer.
Installer CircuitPython et les bibliothèques
L’installation de CircuitPython est extrêmement simple et Adafruit a un guide fantastique sur la façon de procéder. Suivre Instructions d’Adafruit pour installer la dernière version.
Notre Raspberry Pi Pico apparaît maintenant comme un lecteur dans le gestionnaire de fichiers. Le lecteur s’appelle CIRCUITPY et nous y trouvons une série de fichiers et de dossiers. En ce moment, nous devons nous concentrer sur lib. Nous devons télécharger un fichier ZIP plein de bibliothèques et installer les fichiers corrects pour nos projets.
1. Téléchargez le dernier ensemble de bibliothèques du site CircuitPython.
2. Extraire les fichiers sur votre bureau.
3. Copiez adafruit_pixelbuf.mpy et neopixel.mpy à partir des fichiers extraits dans le dossier lib sur votre lecteur CIRCUITPY.
Écrire le code pour Simon Game sur Raspberry Pi Pico
1. Ouvrez le fichier code.py trouvé à la racine du lecteur CIRCUITPY dans votre éditeur préféré.
2. Supprimer n’importe quel code dans le fichier.
3. Importez des bibliothèques pour contrôler la vitesse du jeu et pour accéder au GPIO. Time et Board sont des bibliothèques CircuitPython communes utilisées. Time contient des fonctions pour mettre le code en pause, tandis que Board fournit un accès GPIO de base.
import time
import board
4. Importez deux bibliothèques supplémentaires pour un contrôle avancé des NeoPixels. Colorwheel est un outil d’animation que nous utiliserons pour créer un effet de cycle arc-en-ciel. NeoPixel est la bibliothèque utilisée pour contrôler les huit LED RVB.
from rainbowio import colorwheel
import neopixel
5. Importez deux bibliothèques finales. Du choix d’importation aléatoire et uniforme, et de l’importation de digitailio DigitalInOut, Direction et Pull pour gérer les entrées/sorties, la direction des broches et la prise en charge des résistances de rappel. Random a de nombreuses fonctions, mais le choix nous permet de choisir « au hasard » dans des listes, des tuples, des dictionnaires, etc. Uniform est un générateur de nombres aléatoires pour les nombres flottants. DigitalIO travaille avec la bibliothèque Board pour affiner la façon dont nous utilisons le GPIO. Dans ce cas, nous voulons utiliser des entrées (boutons) et régler la résistance interne des broches GPIO de sorte qu’elle tire vers le haut (3,3 V).
from random import choice, uniform
from digitalio import DigitalInOut, Direction, Pull
6. Configurez GPIO 28 comme broche utilisée pour contrôler nos NeoPixels, ensuite créer une variable appelée num_pixels pour mémoriser le nombre de LED NeoPixel.
pixel_pin = board.GP28
num_pixels = 8
sept. Créez un objet, « pixels » et utilisez-le pour vous connecter aux NeoPixels en utilisant les deux variables qui identifient la broche GPIO et le nombre de pixels. Nous avons également réglé la luminosité sur 0,3 (30 %) pour réduire la fatigue oculaire.
pixels = neopixel.NeoPixel(pixel_pin, num_pixels, brightness=0.3, auto_write=False)
8. Créez un objet, rouge, qui représente le bouton rouge connecté au GPIO 27.
red = DigitalInOut(board.GP27)
9. Définissez la broche GPIO du bouton rouge comme entrée.
red.direction = Direction.INPUT
dix. Réglez la broche GPIO pour le bouton rouge afin qu’il tire vers le haut. À l’aide d’une résistance de rappel, nous tirons GPIO 27 haut à 3,3 V. La façon dont nous avons connecté le bouton au Pico tirera cette broche vers GND (bas) lorsque le bouton rouge est enfoncé.
red.pull = Pull.UP
11. Répétez le processus pour le bouton vert.
green = DigitalInOut(board.GP26)
green.direction = Direction.INPUT
green.pull = Pull.UP
12. Répétez l’opération pour le bleu.
blue = DigitalInOut(board.GP22)
blue.direction = Direction.INPUT
blue.pull = Pull.UP
13. Répétez l’opération pour le jaune.
yellow = DigitalInOut(board.GP21)
yellow.direction = Direction.INPUT
yellow.pull = Pull.UP
14. Créez cinq tuples (objets de stockage de données) pour stocker les valeurs de couleur RVB des boutons et pour éteindre les LED.
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
YELLOW = (255, 150, 0)
OFF = (0, 0, 0)
15. Créez une fonction, rainbow_cycle qui parcourra tous les NeoPixels, affichant un effet arc-en-ciel. Cette fonction fait partie de la démo standard « strand test » d’Adafruit.
def rainbow_cycle(wait):
for j in range(255):
for i in range(num_pixels):
rc_index = (i * 256 // num_pixels) + j
pixels[i] = colorwheel(rc_index & 255)
pixels.show()
time.sleep(wait)
16. Créez une liste appelée « couleurs » et utilisez-la pour stocker les tuples de couleur nous avons créé plus tôt.
colors = [RED, GREEN, BLUE, YELLOW]
17. Créez une boucle for qui se répétera 10 fois. Chaque fois que la boucle itère, elle utilise la fonction rainbow_cycle pour créer un spectacle de lumière au démarrage du jeu.
for i in range(10):
rainbow_cycle(0)
18. Le corps principal du projet est un while True, qui exécutera le code du jeu. Créez une boucle while True et appelez l’objet pixels pour éteindre les LED.
while True:
pixels.fill(OFF)
pixels.show()
19. Créez deux listes vierges pour stocker la séquence de couleurs choisie au hasard, et pour stocker les suppositions des joueurs.
rnd_colors = []
player = []
20. Créez un test conditionnel if pour déclencher le démarrage du jeu. Pour démarrer le jeu, nous devons appuyer sur le bouton vert. Comme cette broche est tirée vers le haut à l’aide d’une résistance de rappel, nous devons déclencher le jeu pour démarrer lorsque la broche est basse (Faux). Les boutons sont connectés aux broches GPIO tirées vers le haut et à GND. Ainsi, lorsque le bouton est enfoncé, les broches sont tirées vers le bas.
if green.value == False:
21. Créez une variable, « delay », pour stocker une valeur flottante choisie au hasard entre 0,3 et 1,0. Enveloppez la fonction round() autour de cela pour formater la sortie à une décimale. Imprimez la sortie dans le shell Python pour le débogage. Cela générera un nombre aléatoire entre 0,3 et 1, utilisé pour créer une pause entre la séquence de couleurs montrée au joueur.
delay = round(uniform(0.3,1.0),1)
print(delay)
22. Utilisez une boucle for pour ajouter quatre couleurs choisies au hasard à la liste rnd_colors et imprimez-les dans le shell Python pour le débogage. Ce seront les couleurs que le joueur devra deviner.
for i in range(4):
rnd_colors.append(choice(colors))
print(rnd_colors)
23. Montrez la séquence de couleurs au joueur. Cette boucle for itère sur les quatre couleurs stockées dans la liste rnd_colors. Chaque fois que la boucle itère, la valeur RVB est utilisée avec pixels.fill() pour afficher cette couleur.
for color in rnd_colors:
print(color)
pixels.fill(color)
pixels.show()
24. Utilisez le délai choisi au hasard pour afficher la couleur, puis éteignez les LED en utilisant le même délai.
time.sleep(delay)
pixels.fill(OFF)
pixels.show()
time.sleep(delay)
25. Utilisez une boucle while pour vérifier la longueur de la liste des joueurs et ajoutez un délai de 0,3 seconde à cette boucle pour réduire le risque d’appuyer deux fois sur un bouton (anti-rebond) Le code en retrait ne fonctionnera que s’il y a moins de quatre suppositions par le joueur.
while len(player) <4:
time.sleep(0
26. Créez une instruction if pour lire l’état de chaque bouton, stocker la couleur pressée et afficher la valeur pour le débogage. Le premier est le bouton rouge. Lorsqu’il est pressé, il ajoutera la valeur de couleur RVB à la liste des joueurs. Imprimez ensuite la valeur dans le shell Python pour le débogage.
if red.value == False:
player.append((255,0,0))
print(player)
27. Pour donner un retour au joueur, réglez les NeoPixels sur la couleur choisie pendant 0,1 seconde avant d’éteindre les pixels.
time.sleep(0.1)
pixels.fill(OFF)
pixels.show()
28. Répétez le processus pour le bouton vert. Utilisez un elif (else if) pour vérifier si cette condition est vraie.
elif green.value == False:
player.append((0,255,0))
print(player)
pixels.fill(GREEN)
pixels.show()
time.sleep(0.1)
pixels.fill(OFF)
pixels.show()
29. Répétez l’opération pour le bouton bleu.
elif blue.value == False:
player.append((0,0,255))
print(player)
pixels.fill(BLUE)
pixels.show()
time.sleep(0.1)
pixels.fill(OFF)
pixels.show()
30. Répétez l’opération pour le bouton jaune.
elif yellow.value == False:
player.append((255, 150, 0))
print(player)
pixels.fill(YELLOW)
pixels.show()
time.sleep(0.1)
pixels.fill(OFF)
pixels.show()
31. Utilisez un test conditionnel if pour vérifier les suppositions des joueurs par rapport aux valeurs choisies au hasard. Une fois que le joueur a entré ses quatre suppositions, celles-ci sont comparées aux valeurs choisies au début de la partie.
if player == rnd_colors:
32. Utilisez une boucle for et réglez-la pour itérer 10 fois pour exécuter le rainbow_cycle() signifiant que le joueur a gagné.
for i in range(10):
rainbow_cycle(0)
33. Créez une autre condition qui fera clignoter les NeoPixels trois fois. Le joueur verra les NeoPixels clignoter en rouge s’il devine mal.
else:
for i in range(3):
pixels.fill(RED)
pixels.show()
time.sleep(0.2)
pixels.fill(OFF)
pixels.show()
time.sleep(0.1)
34. Enregistrez le code sur votre Raspberry Pi Pico en tant que code.py et le jeu démarrera en exécutant la fonction rainbow_cycle().
35. Lancez le jeu en appuyant sur le bouton vert.
Liste complète des codes pour Simon Game sur Raspberry Pi Pico
import time
import board
from rainbowio import colorwheel
import neopixel
from random import choice, uniform
from digitalio import DigitalInOut, Direction, Pull
#NeoPixel setup
pixel_pin = board.GP28
num_pixels = 8
pixels = neopixel.NeoPixel(pixel_pin, num_pixels, brightness=0.3, auto_write=False)
#Button Setup
red = DigitalInOut(board.GP27)
red.direction = Direction.INPUT
red.pull = Pull.UP
green = DigitalInOut(board.GP26)
green.direction = Direction.INPUT
green.pull = Pull.UP
blue = DigitalInOut(board.GP22)
blue.direction = Direction.INPUT
blue.pull = Pull.UP
yellow = DigitalInOut(board.GP21)
yellow.direction = Direction.INPUT
yellow.pull = Pull.UP
# RGB Color Codes
RED = (255, 0, 0)
GREEN = (0, 255, 0)
BLUE = (0, 0, 255)
YELLOW = (255, 150, 0)
OFF = (0, 0, 0)
#Rainbow Animation
def rainbow_cycle(wait):
for j in range(255):
for i in range(num_pixels):
rc_index = (i * 256 // num_pixels) + j
pixels[i] = colorwheel(rc_index & 255)
pixels.show()
time.sleep(wait)
#List of colors
colors = [RED, GREEN, BLUE, YELLOW]
#The "attract sequence to entice people to play
for i in range(10):
rainbow_cycle(0)
while True:
pixels.fill(OFF)
pixels.show()
rnd_colors = []
player = []
#Wait for the green button start the game
if green.value == False:
delay = round(uniform(0.3,1.0),1)
print(delay)
for i in range(4):
rnd_colors.append(choice(colors))
print(rnd_colors)
for color in rnd_colors:
print(color)
pixels.fill(color)
pixels.show()
time.sleep(delay)
pixels.fill(OFF)
pixels.show()
time.sleep(delay)
#Player has four guesses, each guess saves the color choice to player list
while len(player) <4:
time.sleep(0.3)
if red.value == False:
player.append((255,0,0))
print(player)
pixels.fill(RED)
pixels.show()
time.sleep(0.1)
pixels.fill(OFF)
pixels.show()
elif green.value == False:
player.append((0,255,0))
print(player)
pixels.fill(GREEN)
pixels.show()
time.sleep(0.1)
pixels.fill(OFF)
pixels.show()
elif blue.value == False:
player.append((0,0,255))
print(player)
pixels.fill(BLUE)
pixels.show()
time.sleep(0.1)
pixels.fill(OFF)
pixels.show()
elif yellow.value == False:
player.append((255, 150, 0))
print(player)
pixels.fill(YELLOW)
pixels.show()
time.sleep(0.1)
pixels.fill(OFF)
pixels.show()
#If the player guesses correctly they get a nice rainbow
if player == rnd_colors:
for i in range(10):
rainbow_cycle(0)
#If you lose, you see red!
else:
for i in range(3):
pixels.fill(RED)
pixels.show()
time.sleep(0.2)
pixels.fill(OFF)
pixels.show()
time.sleep(0.1)