Apprendre à créer un jeu « Mix-Max » avec des cartes RFID

Jouer et créer son robot avec des cartes RFID

Mike Cook

Traducteur

f-leb

Il existe un nombre croissant de livres d'illustrations pour la jeunesse utilisant le principe du « Mix-Max ». Le principe consiste à constituer un personnage ou, ce qui nous concerne ici, un robot en mixant ses différentes parties : tête, corps et jambes. En tournant des fractions de pages séparément, on compose son personnage avec différents vêtements ou son robot avec une grande quantité de combinaisons possibles. (NDLR : vous avez un magnifique exemple illustrant ce principe sur http://www.bibliotheque.toulouse.fr//PELE-MELE-livresPopup.html).

L'idée consiste à utiliser des cartes RFID avec une illustration complète de robot dessinée dessus, mais seulement un tiers de l'illustration, la tête, le corps ou les jambes du robot sera retenu et affiché à l'écran en fonction du lecteur de carte (parmi les trois) où la carte sera présentée. Ce jeu a toujours fait sensation quand nous le présentions dans des salons et nous allons en présenter une version à bas coût à base de Raspberry Pi. Vous pouvez profiter des œuvres d'illustrateurs ou d'un projet scolaire dans une classe en faisant dessiner les illustrations aux élèves de façon à ce qu'elles puissent se combiner. Vous pouvez également ajouter des décors en arrière-plan avec des cartes dédiées, chaque carte pouvant faire afficher une des trois images possibles en arrière-plan dépendant du lecteur où la carte est présentée.

Commentez

- Titre : Apprendre à créer un jeu « Mix-Max » avec des cartes RFID

- Auteur : Mike Cook

- Traducteur : f-leb

- Parution : 16 juillet 2016

- Public visé :

- Licence : Le contenu de cet article est rédigé par Mike Cook et est mis à disposition selon les termes de la Licence Creative Commons Attribution - Pas d'Utilisation Commerciale - Partage dans les Mêmes Conditions 3.0 non transposé. Les logos Developpez.com, en-tête, pied de page, css, et look & feel de l'article sont Copyright ® 2013 Developpez.com.

Voir également :

- Raspberry Pi - Déballage et installation

- Raspberry Pi - Python et le port GPIO

Sommaire

- I. Configuration matérielle

- II. Réunir les ressources

- III. Le programme

- IV. Conception du système de lecture de cartes

- IV-A. Étape 1 : circuit de sélection du lecteur

- IV-B. Étape 2 : connexion des lecteurs

- IV-C. Étape 3 : réalisation du boîtier

- IV-D. Étape 4 : finition du boîtier

- V. Aller plus loin

- VI. Notes de la Rédaction de Developpez.com

I - Configuration matérielle

Animation en format "vimeo" non supportée.
Contenu uniquement consultable en ligne à cette adresse :
https://player.vimeo.com/video/172555808

(*) Une carte RFID avec un robot complet, tête, corps et jambes. (**) Sous chaque autocollant, un lecteur de cartes RFID.

Matériel nécessaire

- 3 lecteurs de cartes RFID Mifare RC522

- Un jeu de 10 cartes Mifare RFID

- Un multiplexeur/démultiplexeur analogique 74HC4051 (boîtier DIL)

- Un support DIL à 16 broches

- Une plaque de Veroboard (24 x 11 trous)

- Un jeu de trois connecteurs coudés « Right Angle Pin Headers » à 8 broches

- Un connecteur 26 broches GPIO (GPIO header socket)
(NDLR : ou 40 broches à partir du Pi 2)

- NDLR : les photos plus loin dans le tutoriel montrent des connecteurs femelles 8 broches Dupont

- Un assortiment de résistances, condensateurs et fils de câblage

Le lecteur RFID à bas coût RC522 est maintenant largement répandu. On peut en trouver trois pour moins d'une dizaine d'euros sur eBay. Bien que le chipset lui-même de ce lecteur supporte de nombreuses interfaces, ce genre de cartes peu coûteuses est configuré pour ne supporter qu'une seule interface série de type SPI (Serial Protocol Interface). C'est un peu compliqué sur le Pi qui ne dispose que de deux broches Chip Enable pour gérer deux périphériques sur un bus SPI. Mais si nous ajoutons un démultiplexeur analogique, nous pouvons piloter jusqu'à 16 lecteurs RFID, bien que seulement trois lecteurs soient nécessaires pour ce projet.

Le schéma électrique du dispositif est décrit plus bas dans l'article. Toutes les broches MOSI, MISO, SCK et RST des lecteurs sont reliées entre elles pour former un bus. Chacune des broches Chip Select, curieusement nommées SDA, est reliée à part au démultiplexeur. Tous les détails de la réalisation du circuit sont donnés dans le chapitre IV.

II - Réunir les ressources

La première chose dont vous aurez besoin est le dessin des cartes. Il peut être réalisé en travail scolaire, en reprenant les illustrations d'un livre ou d'Internet, ou alors vous usez de vos propres œuvres artistiques. En fait, ce projet a profité du concours d'un ami artiste, Adam Farra. Vous pouvez voir son travail ci-dessous et télécharger les images à partir du dépôt GitHub de ce projet. Si vous dessinez les illustrations vous-même, elles doivent être sauvegardées au format PNG, 406 pixels en largeur et 615 pixels en hauteur. Il est important que la hauteur en pixels soit divisible par trois. Elles devront également avoir un arrière-plan transparent, de façon à ce qu'on puisse en ajouter un avec des cartes RFID spécifiques. Chaque carte dédiée peut permettre d'obtenir trois images d'arrière-plan selon le lecteur où elle sera présentée.

Nous aurons également besoin d'une bibliothèque pour gérer le lecteur RFID. Nous en avons utilisé une à cette adresse. Les exemples de code fournis sont pratiques pour tester chaque lecteur séparément. Quand tout sera prêt, déplacez le fichier MFRC522.pyc dans le répertoire contenant le programme mixUp.py. Ce répertoire devra également contenir un sous-répertoire nommé Cards comprenant les fichiers des illustrations.

III - Le programme

Le programme fonctionne avec le framework Pygame et débute en initialisant le dispositif. À chaque carte est associée une illustration à afficher à l'écran, mais à travers un masque différent selon le lecteur où est présentée la carte. De cette façon, seuls la tête, le corps ou les jambes du robot seront affichés selon le lecteur. La ligne qui définit la liste tokens sera à modifier en fonction des numéros d'identifiants des cartes dont vous disposez. Exécutez le code et présentez une carte devant n'importe quel lecteur pour récupérer son identifiant et faites des copier-coller des identifiants pour compléter la liste Token. Faites la même chose avec les cartes dédiées aux illustrations en arrière-plan et modifiez la liste backToken en conséquence. Lancez ensuite à nouveau le programme et observez quelle carte génère quelle image, puis collez une impression de cette image sur la carte.

mixUp.py

1. #!/usr/bin/env python

2. # All Mixup by Mike Cook June 2016

4. import RPi.GPIO as GPIO

5. import MFRC522

6. import time, pygame, os, sys

8. pygame.init() # initialise graphics interface

9. os.environ['SDL_VIDEO_WINDOW_POS'] = 'center'

10. pygame.display.set_caption("All Mixed Up")

11. pygame.event.set_allowed(None)

12. pygame.event.set_allowed([pygame.KEYDOWN,pygame.QUIT])

14. screenWidth = 406

15. screenHeight = 615

16. screen = pygame.display.set_mode([screenWidth,screenHeight],0,32)

18. numberOfCards = 10 # picture cards

19. numberOfBacks = 3  # background cards

20. card = [ pygame.image.load("Cards/R"+str(cardNumber)+".png").convert_alpha()

21. for cardNumber in range(0,numberOfCards+1)]

22. # three background images for each card

23. backImage = [ pygame.image.load("Cards/B"+str(backNumber)+".jpg")

24. for backNumber in range(0,numberOfBacks*3)]

25. # number of entries to match numberOfCards variable + 1

26. tokens = [0,0x96e2acd5,0xaa01a910,0xbd51192b,0xccb419de, 0xec9f19de,

27. 0x5c6ccadd, 0x1c0201de, 0xcc0101de,0x1c88fadd, 0xccba19de]

28. # number of entries to match numberOfBacks variable

29. backToken = [0x9c3131de,0xbcc8eedd,0xdc54e6dd]

31. headRect = pygame.Rect(0,0,screenWidth,164)

32. bodyRect = pygame.Rect(0,165,screenWidth,224)

33. feetRect = pygame.Rect(0,384,screenWidth,231)

34. headReader = 0; bodyReader = 1; feetReader = 2

36. GPIO.setmode(GPIO.BOARD)

37. GPIO.setwarnings(False)

38. muxPins = [16,18,7]

39. cardPresent = [False,False,False]

40. cardID = [0,0,0]

41. needRedraw = True

42. background = 0

44. def main():

45. print "All mixed up"

46. init()

47. while 1:

48. checkForEvent()

49. if needRedraw :

50. drawScreen()

51. scanReaders()

53. def scanReaders():

54. global cardPresent, cardID, needRedraw, background

55. for reader in range(0,3):

56. setMux(reader)

57. (status,TagType) = mfRaeder[reader].MFRC522_Request(mfRaeder[reader].PICC_REQIDL)

58. if status == mfRaeder[reader].MI_OK:

59. (status,uid) = mfRaeder[reader].MFRC522_Anticoll()

60. if status == mfRaeder[reader].MI_OK and cardPresent[reader] == False :

61. cardPresent[reader] = True

62. needRedraw = True

63. token  = (uid[0] << 24) | (uid[1] << 16) | (uid[2] << 8) | uid[3]

64. if getImageNumber(token) != 0 :

65. cardID[reader] = getImageNumber(token)

66. else:

67. setBackground(token,reader)

68. print "Card reader",reader,hex(token).rstrip("L")

69. else :

70. cardPresent[reader] = False # no card present

72. def drawScreen():

73. global needRedraw

74. screen.blit(backImage[background],(0,0))

75. screen.set_clip(headRect)

76. screen.blit(card[cardID[headReader]],(0,0)) # change 0 to 2 for inverse

77. screen.set_clip(bodyRect)

78. screen.blit(card[cardID[bodyReader]],(0,0))

79. screen.set_clip(feetRect)

80. screen.blit(card[cardID[feetReader]],(0,0)) # change 2 to 0 for inverse

81. screen.set_clip(None)

82. pygame.display.update()

83. needRedraw = False

85. def getImageNumber(number):

86. image = 0

87. for i in range(0,numberOfCards+1) :

88. if tokens[i] == number:

89. image = i

90. return image

92. def setBackground(token, reader):

93. global background

94. background = 0

95. for i in range(0,numberOfBacks):

96. if token == backToken[i]:

97. background = reader + (i*3)

99. def init():

100. global mfRaeder

101. for pin in range (0,3):

102. GPIO.setup(muxPins[pin],GPIO.OUT) # mux pin to output

103. setMux(0)

104. reader1 = MFRC522.MFRC522()

105. setMux(1)

106. reader2 = MFRC522.MFRC522()

107. setMux(2)

108. reader3 = MFRC522.MFRC522()

109. mfRaeder = [reader1,reader2,reader3]

111. def setMux(n):

112. mask = 1;

113. for pin in range(0,3):

114. if (mask & n) != 0 :

115. GPIO.output(muxPins[pin], True)

116. else :

117. GPIO.output(muxPins[pin], False)

118. mask = mask << 1

120. def terminate(): # close down the program

121. print ("Closing down")

122. GPIO.cleanup()

123. pygame.quit() # close pygame

124. os._exit(1)

126. def checkForEvent(): # see if we need to quit

127. global nextF, background, needRedraw, cardID

128. event = pygame.event.poll()

129. if event.type == pygame.QUIT :

130. terminate()

131. if event.type == pygame.KEYDOWN :

132. if event.key == pygame.K_ESCAPE :

133. terminate()

134. if event.key == pygame.K_SPACE : # reset display

135. background = 0

136. needRedraw = True

137. for i in range(0,3):

138. cardID[i] = 0

140. # Main program logic:

141. if __name__ == '__main__':

142. main()

Vous pouvez permuter les variables headReader et feetReader pour inverser l'association tête et jambes du premier et dernier lecteur, au cas où vous auriez inversé leur position dans le boîtier. Si les illustrations que vous avez dessinées ne s'alignent pas, un programme que vous trouverez dans le dépôt GitHub du projet a été écrit afin de les décaler et les remettre en bonne place.

IV - Conception du système de lecture de cartes

IV-A - Étape 1 : circuit de sélection du lecteur

NDLR : une petite explication sur le fonctionnement du circuit schématisé ci-dessus avant de jouer du fer à souder n'est pas inutile…

La communication série de type SPI entre le Pi et chaque lecteur RFID se fait via les lignes unidirectionnelles MISO (Master In Slave Out) et MOSI (Master Out Slave In). Les échanges de données sont synchronisés avec une horloge générée par le maître (le Pi) sur la ligne SCK. Les lignes d'échange de données et l'horloge sont communes aux trois lecteurs, mais il n'y a qu'un seul lecteur à la fois qui doit échanger des données avec le Raspberry Pi. Pour notre jeu, la stratégie consiste à scruter la présence d'une carte en activant les lecteurs chacun leur tour et en boucle. Dans le protocole SPI, la sélection du lecteur sur le bus avec qui le Pi échangera les données est obtenue en abaissant au potentiel 0 V sa broche Chip Enable, curieusement nommée SDA sur le lecteur (par défaut, amenée au +3,3 V avec des résistances de tirage de 10k).

Du côté du Pi, les broches dédiées au SPI sont les GPIO 9, 10 et 11 ainsi que les deux broches GPIO 7 et 8 pour la sélection (Chip Enable 0 et 1). Et il manque donc une broche Chip Enable pour le troisième lecteur, d'où le choix du 74HC4051 en démultiplexeur analogique qui peut écrire l'état de son entrée (la GPIO 8, Chip Enable 0) vers une des huit sorties possibles au choix (seules trois d'entre elles serviront ici). Ce sont les signaux numériques PB0, PB1 et PB2 envoyés par le Pi (codage en binaire naturel sur 3 bits, soit 2^3 = 8 possibilités) qui permettent de sélectionner la sortie et donc d'orienter l'état de la broche Chip Enable 0 du Pi vers le lecteur souhaité.

Le circuit de sélection du lecteur sera réalisé sur une plaque de veroboard, 24 par 11 trous. Pensez à couper les pistes du veroboard situées sous la puce 74HC4051, ainsi qu'aux endroits visibles sur la figure ci-dessus. La puce sera insérée sur un support DIL soudé sur la carte. Positionnez les connecteurs coudés « Right Angle Pin Headers » et soudez-les également. Puis, soudez les fils de connexion sur la carte suivant le schéma.

Enfin, soudez les dix extrémités d'un câble plat multibrin sur la carte d'une part, pour la réception des signaux en provenance du Pi. À l'autre extrémité du câble, on soudera un connecteur qui pourra s'enficher directement sur le port GPIO du Pi.

IV-B - Étape 2 : connexion des lecteurs

Premièrement, soudez un connecteur coudé sur le circuit du lecteur. Il faut maintenant préparer un câble plat comprenant huit brins et des connecteurs femelles pour relier les lecteurs à la carte. Il est bien de faire une petite marque à chaque extrémité du câble pour s'orienter et ne pas câbler à l'envers. À ce stade, vous devriez pouvoir tester chaque lecteur et voir s'ils fonctionnent tous correctement.

Comme les lecteurs interfèrent avec le métal, il est important d'employer le moins de parties métalliques possible dans la construction du boîtier. À noter que les lecteurs peuvent aussi interférer entre eux, réduisant ainsi leur portée de détection. En conséquence, maintenez un écart d'au moins 70 mm entre chaque lecteur.

IV-C - Étape 3 : réalisation du boîtier

Nous avons utilisé des panneaux MDF pour réaliser la base du boîtier et son couvercle, avec des bandes en pin de 12 mm d'épaisseur pour les côtés du boîtier. La base et le couvercle font 280 x 105 mm, et des entretoises hexagonales de hauteur 10 mm sont prévues pour visser le couvercle sur la base. Les côtés sont assemblés entre eux par collage et collés ensuite sur la base. De petits trous borgnes ont été percés dans la planche pour avoir une réserve de colle supplémentaire et améliorer la prise. De la colle à bois polyuréthane a été employée et les différentes parties sont maintenues avec des serre-joints pendant le séchage. Pour obtenir le bon alignement des entretoises, maintenez le couvercle et la base du boîtier avec des serre-joints tandis que vous percez les trous dans les deux parties en même temps. Notez que les colles polyuréthane requièrent des joints humides, d'où la pulvérisation d'eau.

IV-D - Étape 4 : finition du boîtier

Le boîtier a été assemblé et les coins ont été légèrement arrondis pour supprimer les angles vifs.

Les lecteurs ont été positionnés sur des plots en pin collés sur la base du boîtier, l'antenne du lecteur tourné vers la base, et fixés avec des vis autotaraudeuses. Faites en sorte que la façade du lecteur soit aussi proche que possible de la paroi du couvercle afin d'avoir la meilleure portée de lecture. On applique une première couche d'apprêt, puis deux couches de peinture laquée sur le boîtier. Enfin, des autocollants du logo Raspberry Pi sont placés sur le couvercle, au-dessus de chaque lecteur. Imprimez les illustrations de robot et collez-les sur les cartes RFID. Nous y avons également ajouté une feuille de plastique transparente adhésive pour une longévité supplémentaire.

V - Aller plus loin

Une évolution sensible serait d'émettre un son lorsqu'une carte est présentée devant un lecteur. Vous pourriez aussi ajouter une LED à proximité de chaque lecteur qui s'illuminerait lorsqu'une carte se présente. Pourquoi pas encore ajouter la possibilité d'imprimer l'illustration finale du robot, pour en garder une trace ? Votre œuvre artistique est dessinée au crayon ? Que diriez-vous d'utiliser un logiciel de dessin pour la colorier ? N'importe lequel avec un simple outil de remplissage conviendrait. Respectez seulement le choix de quelques couleurs pour chaque robot, cela rendra votre œuvre plus attrayante lorsque les différentes parties des robots seront mélangées.

Cependant, le plus amusant vient si vous changez complètement d'illustrations. Nous avons fait une version utilisant des images de dinosaures provenant d'un livre d'illustrations de type Mix-Max. Elle mélange aussi les syllabes dans des noms afin d'en créer de nouveaux et les enfants adorent cela. Cette version n'implique pas seulement un nouveau travail d'illustration, mais aussi un passage du format portrait au format paysage pour l'affichage à l'écran.

Êtes-vous prêts à relever ce défi ?

VI - Notes de la Rédaction de Developpez.com

Cet article est une traduction de l'article écrit par Mike Cook et paru dans le n° 47 du magazine TheMagPi, sous le titre Mixed Up - An RFID picture making game.

Retrouvez les projets de l'auteur publiés dans le magazine TheMagPi sur la plateforme GitHub.

Nous remercions les membres de la Rédaction de Developpez pour le travail de traduction et de relecture qu'ils ont effectué, en particulier :

- f-leb

- lolo78

Merci également à Claude Leloup pour sa relecture orthographique.