J’adore donner des conseils sur la façon de coder et d’utiliser des gadgets pour créer des projets sympas.
Pas votre tutoriel Hello World ordinaire
Je ne sais pas pour vous, mais depuis que j’apprends à programmer, je tombe sur les mêmes types de tutoriels dans toutes les langues : « Hello World » et « Comment créer un carnet d’adresses ». Bien qu’ils soient tous deux parfaits pour apprendre les bases, je n’aime pas les projets arbitraires, même s’ils m’apprennent.
Quand j’ai eu mon Raspberry Pi 2 l’année dernière, j’ai décidé que j’allais apprendre Python avec et je n’allais certainement pas simplement faire des tutoriels « Hello World ». Le résultat de mon projet est un jeu qui prend l’entrée de l’utilisateur à partir des boutons de ma planche à pain en utilisant les broches GPIO. Dans ce didacticiel, nous allons recréer ce jeu et essayer d’apprendre exactement ce que nous faisons avec chaque ligne de code, au lieu de simplement copier et coller et jouer à un jeu simple à la fin.
L’image
Commençons.
Je fais tout cela sur un Raspberry Pi 2 exécutant Raspbian Jessie. Le Pi est connecté à mon réseau local via un câble Ethernet (si vous avez l’adaptateur WI-FI, cela fonctionnera tout aussi bien) et je suis connecté en ssh depuis mon MacBook Pro. Vous pouvez tout faire localement sur le Pi si vous l’avez connecté à un moniteur, un clavier et une souris.
Le tableau de bord
Mettons en place notre tableau de répartition. Si vous ne savez pas, le tableau va de haut en bas sur le long chemin. Chaque ligne horizontale est la même connexion, donc tout ce qui se trouve à côté horizontalement sera alimenté en même temps.
J’ai inclus une image de mon tableau de répartition actuel et une interprétation numérique de l’idée générale. La conception numérique a été réalisée dans le logiciel Fritzing. Ce n’est pas une interprétation parfaite car elle n’offrait pas la possibilité d’inclure le cordonnier, mais elle fait passer le message.
Les LED sont connectées comme suit. Le rouge est connecté au positif à la broche 27 et au négatif au 3V négatif via une résistance de 220 Ω (code de couleur rouge, rouge, marron, or). Assurez-vous d’utiliser une résistance ou vous risquez d’éteindre votre LED. Le vert est connecté positif à la broche 22 et négatif au négatif 3V via une résistance de 220 Ω. Le bouton du haut est connecté positif à 17 et négatif à la masse. Le bouton du bas est connecté positif à 18 et négatif à la masse.
Le code : vue d’ensemble
Commençons par parler de notre objectif final. Lorsque le jeu est lancé, il affichera un paragraphe sur l’écran du terminal racontant l’histoire de tomber sur une bombe à retardement. En tant que seule personne présente, il appartient au joueur de décider s’il doit couper le fil rouge ou le fil bleu (dans ce cas, les fils sont les boutons du panneau de dérivation). Lorsque l’utilisateur appuie sur un bouton, un voyant rouge ou vert clignote et un message de félicitations ou d’échec s’affiche à l’écran.
Afin de rendre ce jeu vraiment aléatoire, nous utilisons un générateur de nombres aléatoires et quelques mathématiques de base afin de déterminer quel bouton est le bon et lequel entraînera la mort de nombreux passants innocents.
Le Code : Importations
OK, passons aux choses amusantes.
Nous devons d’abord importer les frameworks que nous utiliserons dans ce jeu : random, time et gpio.
#Import frameworks from random import randint import RPi.GPIO as GPIO import time
J’inclus toujours des commentaires pour m’assurer que lorsque je reviendrai plus tard (ou si quelqu’un voit cela), je me souviens de ce que fait chaque bloc.
Faites défiler pour continuer
Afin de limiter la taille et les exigences de calcul, nous n’importons que la partie randint du framework aléatoire. Ce n’est pas si grave dans un programme aussi petit que celui-ci, mais c’est une bonne pratique à adopter.
Pour faciliter l’interaction avec le framework GPIO, nous l’importons en tant que GPIO. GPIO est maintenant une variable qui nous empêche d’écrire RPi.GPIO à chaque fois ; vous pouvez changer le nom de la variable en ce que vous voulez.
Nous avons besoin de quelques secondes où nous retardons ou attendons pendant ce jeu, nous importons donc du temps.
Le code : Configuration GPIO
Nous devons maintenant dire au Pi quelles broches nous utiliserons pour ce projet. N’oubliez pas que pour ce projet, nous ne nous connectons pas directement aux composants, mais le mappons via une carte de dérivation par un cordonnier en forme de T CanaKit à 40 broches.
#GPIO Setup GPIO.setwarnings(False) GPIO.setmode(GPIO.BCM) GPIO.setup(17, GPIO.IN,pull_up_down=GPIO.PUD_UP) #Top Button GPIO.setup(18, GPIO.IN,pull_up_down=GPIO.PUD_UP) #Bottom Button GPIO.setup(27, GPIO.OUT) #Red GPIO.setup(22, GPIO.OUT) #Green
Tout d’abord, nous désactivons les avertissements GPIO. Le code fonctionnera sans cette ligne, mais vous recevrez un avertissement à chaque fois que vous l’exécuterez, il est donc préférable de l’ignorer.
Maintenant, nous devons indiquer au code que nous le mappons sur la carte de dérivation. Je vais être honnête, je ne comprends pas entièrement cette partie, je n’ai juste pas besoin d’inclure cette ligne de code pour aider nos chiffres à s’aligner.
Les 4 dernières lignes font toutes la même chose, elles indiquent au Pi quelles broches nous utilisons et à quelle heure l’appareil se trouve à l’autre extrémité du circuit de la broche : entrée ou sortie.
Le code : fonction de jeu
Nous arrivons maintenant à créer une fonction. Parlons des fonctions pendant une minute. Les fonctions prennent beaucoup d’instructions et les transforment en une seule « variable » (ce n’est pas la bonne terminologie, mais suivez-moi là-dessus) que vous pouvez appeler plus tard. Dans ce cas, nous disons au programme ce qu’est le jeu, mais nous ne le laissons pas s’exécuter tant que nous ne sommes pas prêts. Cela nous permet également d’arrêter le jeu ou d’ajouter des fonctionnalités supplémentaires si nous le souhaitons plus tard.
Comme cette fonction est très longue, je vais diviser les segments de code en segments plus courts. Rappelez-vous fait partie de la fonction de jeu. J’inclurai le code de fonction complet ainsi que le code de programme complet plus tard. Mais je ne veux pas submerger qui que ce soit avec un tas de code à la fois.
def game():
Nous définissons d’abord notre fonction et lui donnons un nom. J’ai choisi d’être vraiment créatif ici et de le nommer jeu.
#Random Number x = randint(0,9) #Determine if number is even or odd y = x%2
Maintenant, nous choisissons un nombre. Parce que nous avons utilisé randint, le nombre sera un entier (ce qui signifie pas de décimales pour ceux d’entre vous qui détestent les maths) et entre parenthèses, nous passons 0, 9 comme arguments. Dans ce cas, cela rend la plage d’entiers 0-9. De manière réaliste, nous pourrions faire (1, 2) et limiter l’entier à 1 ou 2, mais nous faisons cela pour augmenter notre apprentissage, alors allons-y avec 0-9.
Maintenant, nous devons le réduire à une option 50/50. J’ai choisi de le faire en déterminant si le nombre était pair ou impair. Pour ce faire, nous utilisons une fonction appelée modulo, représentée par %. Encore une fois, pour vous les non-mathématiques, modulo renvoie le reste d’un problème de division donc 27/5 = 5 reste 3 et 27 % 5 = 3. Cela peut déterminer impair ou pair parce que nous savons que si un nombre pair divisé par 2 a pas de reste, donc tout nombre pair modulo 2 vaut 0.
Dans ce cas, x est notre entier aléatoire, nous allons donc faire de y notre équation pour déterminer l’impair ou le pair. Donc y est x % 2, ce qui signifie que les seuls résultats possibles que y pourrait donner sont 0 ou 1. Nous avons maintenant notre option 50/50.
#Story print "You are casually walking down the street one day when out of nowhere you notice a ticking time bomb, ready to explode. You immediately remember your bomb squad days and rush into action. You have the bomb nearly defused, but you must now choose: red wire or blue wire. You have 10 seconds." time.sleep(1) print "Choose wisely"
Tout bon jeu a besoin d’une histoire. Ici, nous produisons simplement l’histoire en texte brut dans la fenêtre du terminal. Ensuite, nous attendons 1 seconde, puis disons à l’utilisateur de choisir judicieusement.
#Button Controls while (GPIO.input(17) == True or GPIO.input(18) == True): #Listen for input from buttons topButton = GPIO.input(17) bottomButton = GPIO.input(18) if (topButton == False): #Top Button Pressed if (y == 0): #If the number was even and you pushed the top button, you lose print("You have failed. Countless people have died due to your incompetence and you have been reduced to nothing but a few subatomic particles that are barely visible to the human eye.") GPIO.output(27,GPIO.HIGH) time.sleep(.3) else: #If the number was odd and you pushed the top button, you win. print ("Well done! You have successfully defused the bomb and saved many lives. You are an international hero!") GPIO.output(22,GPIO.HIGH) time.sleep(.3)
Maintenant, le code pour les boutons. Gardez à l’esprit que lorsqu’un bouton est enfoncé, il renvoie false. Lorsqu’il n’est pas poussé, il est vrai. Pour moi, cela semble un peu en arrière, mais il a été conçu par quelqu’un de plus intelligent que moi.
Ce jeu fonctionnera dans une boucle while indiquant que tant que l’un des boutons n’est pas enfoncé, le Pi continuera d’attendre une entrée.
Pour faciliter le code, j’ai déclaré chaque entrée de bouton GPIO comme une variable nommée en anglais afin qu’il n’ait pas à se souvenir de quel numéro correspond à quoi. Les variables ‘topbutton’ et ‘bottombutton’ correspondent à leur emplacement sur le breakout board.
Maintenant, nous utilisons une instruction if/elif. Je l’ai divisé entre deux segments ici pour le rendre plus facile à lire. Le bouton du haut gagnera si l’utilisateur appuie dessus et que le nombre aléatoire précédent est impair. S’ils appuient sur le bouton du haut et que le nombre est pair, ils perdent. Nous disons donc que si l’utilisateur touche le bouton du haut, nous vérifions si y est égal à 0 (le nombre aléatoire était pair), puis il imprime le message perdant et allume le voyant rouge. Sinon (donc y est 1 ou le nombre aléatoire était impair), il affiche le message gagnant et allume le feu vert.
C’est la première fois que nous utilisons la fonction GPIO.output. Dans le cas des LED, nous produisons soit HIGH pour on ou LOW pour off. Puisque nous avons configuré GPIO en tant que variable plus tôt, nous pouvons simplement dire GPIO.output (numéro de broche, HIGH ou LOW) pour allumer ou éteindre la lumière.
Le time.sleep(.3) empêche l’ordinateur de remplir votre écran de milliers de messages de victoire ou d’échec. Cela vous donne suffisamment de temps pour retirer votre doigt du bouton.
elif (bottomButton == False): #Button Button Pressed if (y == 1): #If the number was odd and you pushed the bottom button, you lose. print("You have failed. Countless people have died due to your incompetence and you have been reduced to nothing but a few subatomic particles that are barely visible to the human eye.") GPIO.output(27,GPIO.HIGH) time.sleep(.3) else: #If the number was even and you pushed the bottom button, you win. print ("Well done! You have successfully defused the bomb and saved many lives. You are an international hero!") GPIO.output(22,GPIO.HIGH) time.sleep(.3) time.sleep(.3) #Leave the light on for .3 second GPIO.output(22,GPIO.LOW) #Turn off Green GPIO.output(27,GPIO.LOW) #Turn off Red
Maintenant, nous faisons le même calcul, sauf pour le bouton du bas. Cette section est ignorée si le bouton du haut est enfoncé et la section précédente est ignorée si le bouton du bas est enfoncé. C’est la beauté des déclarations if.
Remarquez que nous utilisons une instruction elif au lieu de just and else. Sinon accepterait n’importe quelle entrée sauf appuyer sur le bouton du haut, donc il fonctionnerait si rien n’était appuyé. Nous voulons cependant qu’il ne s’exécute que si nous avons appuyé sur un bouton ou sur l’autre, nous utilisons donc elif.
Après les calculs pour déterminer si le joueur a gagné ou perdu et le temps d’attente de 0,3 seconde, le Pi éteindra les deux LED. Il ne devrait y avoir qu’une seule LED allumée, rouge ou verte selon que le jeu est gagné ou perdu, mais cela ne fait pas de mal d’en éteindre une qui est déjà éteinte, le Pi ne fera aucun changement. Cela garantit simplement qu’une lumière ne reste pas allumée après la fin du jeu.
print "Exiting Game" return
Rappelez-vous que j’ai dit que c’était une boucle qui fonctionnait tant qu’au moins 1 bouton n’était pas enfoncé? Eh bien, lorsque vous appuyez sur les deux boutons, cela sortira de la boucle et mettra fin au programme. Ici, nous imprimons dans la fenêtre du terminal que le jeu se ferme. La commande return termine en fait le programme.
La fonction de jeu complète
def game(): #Random Number x = randint(0,9) #Determine if number is even or odd y = x%2 #Story print "You are casually walking down the street one day when out of nowhere you notice a ticking time bomb, ready to explode. You immediately remember your bomb squad days and rush into action. You have the bomb nearly defused, but you must now choose: red wire or blue wire. You have 10 seconds." time.sleep(1) print "Choose wisely" #Button Controls while (GPIO.input(17) == True or GPIO.input(18) == True): #Listen for input from buttons topButton = GPIO.input(17) bottomButton = GPIO.input(18) if (topButton == False): #Top Button Pressed if (y == 0): #If the number was even and you pushed the top button, you lose print("You have failed. Countless people have died due to your incompetence and you have been reduced to nothing but a few subatomic particles that are barely visible to the human eye.") GPIO.output(27,GPIO.HIGH) time.sleep(.3) else: #If the number was odd and you pushed the bottom button, you win. print ("Well done! You have successfully defused the bomb and saved many lives. You are an international hero!") GPIO.output(22,GPIO.HIGH) time.sleep(.3) elif (bottomButton == False): #Button Button Pressed if (y == 1): #If the number was odd and you pushed the bottom button, you lose. print("You have failed. Countless people have died due to your incompetence and you have been reduced to nothing but a few subatomic particles that are barely visible to the human eye.") GPIO.output(27,GPIO.HIGH) time.sleep(.3) else: #If the number was even and you pushed the bottom button, you win. print ("Well done! You have successfully defused the bomb and saved many lives. You are an international hero!") GPIO.output(22,GPIO.HIGH) time.sleep(.3) time.sleep(.3) #Leave the light on for .3 second GPIO.output(22,GPIO.LOW) #Turn off Green GPIO.output(27,GPIO.LOW) #Turn off Red print "Exiting Game" return
Le code : appeler la fonction
Maintenant que la fonction est enfin écrite, nous pouvons l’appeler et jouer le jeu. Aucun argument n’est nécessaire pour cette fonction. Nous l’appelons simplement pour que le Pi sache qu’il est temps de jouer.
game()
Le code entier
#Import frameworks from random import randint import RPi.GPIO as GPIO import time #GPIO Setup GPIO.setwarnings(False) GPIO.setmode(GPIO.BCM) GPIO.setup(17, GPIO.IN,pull_up_down=GPIO.PUD_UP) #Top Button GPIO.setup(18, GPIO.IN,pull_up_down=GPIO.PUD_UP) #Bottom Button GPIO.setup(27, GPIO.OUT) #Red GPIO.setup(22, GPIO.OUT) #Green def game(): #Random Number x = randint(0,9) #print(x) #Determine if number is even or odd y = x%2 #Story print "You are casually walking down the street one day when out of nowhere you notice a ticking time bomb, ready to explode. You immediately remember your bomb squad days and rush into action. You have the bomb nearly defused, but you must now choose: red wire or blue wire. You have 10 seconds." time.sleep(1) print "Choose wisely" #Button Controls while (GPIO.input(17) == True or GPIO.input(18) == True): #Listen for input from buttons topButton = GPIO.input(17) bottomButton = GPIO.input(18) if (topButton == False): #Top Button Pressed if (y == 0): #If the number was even and you pushed the top button, you lose print("You have failed. Countless people have died due to your incompetence and you have been reduced to nothing but a few subatomic particles that are barely visible to the human eye.") GPIO.output(27,GPIO.HIGH) time.sleep(.3) else: #If the number was odd and you pushed the bottom button, you win. print ("Well done! You have successfully defused the bomb and saved many lives. You are an international hero!") GPIO.output(22,GPIO.HIGH) time.sleep(.3) elif (bottomButton == False): #Button Button Pressed if (y == 1): #If the number was odd and you pushed the bottom button, you lose. print("You have failed. Countless people have died due to your incompetence and you have been reduced to nothing but a few subatomic particles that are barely visible to the human eye.") GPIO.output(27,GPIO.HIGH) time.sleep(.3) else: #If the number was even and you pushed the bottom button, you win. print ("Well done! You have successfully defused the bomb and saved many lives. You are an international hero!") GPIO.output(22,GPIO.HIGH) time.sleep(.3) time.sleep(.3) #Leave the light on for .3 second GPIO.output(22,GPIO.LOW) #Turn off Green GPIO.output(27,GPIO.LOW) #Turn off Red print "Exiting Game" return game()
Démonstration vidéo
Ci-dessous, j’ai inclus une vidéo qui montre à la fois l’écran du terminal et les voyants et boutons. Il y a une fonctionnalité supplémentaire à ce sujet qui n’est pas couverte dans notre tutoriel. Il y a une lumière clignotante qui est un compte à rebours limitant le temps dont dispose le joueur pour faire un choix. À un moment donné, je ferai peut-être un tutoriel sur la façon d’ajouter cette fonctionnalité, mais comme cela ne fonctionne pas encore parfaitement, je vais simplement laisser cette partie de côté pour le moment.
Cet article est exact et fidèle au meilleur de la connaissance de l’auteur. Le contenu est uniquement à des fins d’information ou de divertissement et ne remplace pas un conseil personnel ou un conseil professionnel en matière commerciale, financière, juridique ou technique.
eembee le 19 septembre 2018 :
Même s’il a été créé pour Jessie, le tutoriel fonctionne toujours bien. Je voulais juste dire à quel point c’est utile et amusant. J’ai référé quelqu’un ici la semaine dernière et ils ont adoré. Merci encore Coton !