ENIB 2025 : Reflex Box
Titre de la fiche expérience :
Sommaire
[masquer]description (résumé)
Photo de l'équipe :
Introduction
Notre projet a pour but de recréer un jeu de reflexe où nous devons appuyé sur des boutons rapidement en fonction de ce que la voix nous dis de faire.
outil et matériel
Lors de la construction de notre Reflexe Box, nous avons utilisé plusieurs composants :
- 5 boutons - Une batterie externe - Une plaque Labdec - Un D1 Mini pour contrôler l'ensemble des composants de notre projet - Un DF Player MP3 pour lire la carte SD - Un ruban de 20 LED permettant d'afficher les scores - Des câbles - Des planches de cartons servant à confectionner l'armature
Nous avons également eu besoin de plusieurs outils :
- Un fer à souder - Une découpeuse laser - Une pince à dénuder
fichiers à joindre
code, ficher d'impression 3D, de découpe laser ou vinyle, ...
1
2 /*
3 BROCHAGE
4 _________________
5 / D1 mini \
6 |[ ]RST TX[ ]|
7 |[ ]A0 -GPIO RX[ ]|
8 |[ ]D0-16 5-D1[X]| - data du ruban de led
9 |[ ]D5-14 4-D2[ ]|
10 |[ ]D6-12 0-D3[ ]|
11 |[ ]D7-13 2-D4[ ]| LED_BUILTIN
12 |[ ]D8-15 GND[X]| - masse du ruban
13 |[ ]3V3 . 5V[X]| - Alim du ruban
14 | +---+ |
15 |_______|USB|_______|
16 */
17 #include <SoftwareSerial.h>
18 #include <DFRobotDFPlayerMini.h>
19
20 SoftwareSerial mySoftwareSerial(14, 12); // TX, RX
21 DFRobotDFPlayerMini myDFPlayer;
22
23 #include <Adafruit_NeoPixel.h>
24
25 #define broche 5 //D1
26 #define nbpixels 20
27
28 Adafruit_NeoPixel pixels(nbpixels, broche, NEO_GRB + NEO_KHZ800);
29 #define delai 30
30
31 const int BPstart = 2; //D4
32 const int BPred1 = 15; //D8
33 const int BPblue1 = 4; //D2
34 const int BPred2 = 13; //D7
35 const int BPblue2 = 0; //D3
36
37 int v_compteur1 = -1;
38 int v_compteur2 = 20;
39 volatile int son = 0; // Utilisez volatile pour indiquer que cette variable peut être modifiée par une ISR
40
41 ICACHE_RAM_ATTR void red1() {
42 if (son == 3 || son == 6) {
43 v_compteur1 += 2;
44 score(v_compteur1);
45 } else {
46 v_compteur2 -= 2;
47 score(v_compteur2);
48 }
49 }
50
51 ICACHE_RAM_ATTR void blue1() {
52 if (son == 5 || son == 4) {
53 v_compteur1 += 1;
54 score(v_compteur1);
55 } else {
56 v_compteur2 -= 1;
57 score(v_compteur2);
58 }
59 }
60
61 ICACHE_RAM_ATTR void red2() {
62 if (son == 3 || son == 6) {
63 v_compteur2 -=2;
64 score(v_compteur2);
65 } else {
66 v_compteur1 += 2;
67 score(v_compteur1);
68 }
69 }
70
71 ICACHE_RAM_ATTR void blue2() {
72 if (son == 5 || son == 4) {
73 v_compteur2 -= 1;
74 score(v_compteur2);
75 } else {
76 v_compteur1 += 1;
77 score(v_compteur1);
78 }
79 }
80
81
82 void victory1() {
83 for (int i = 0; i < 20; i++) {
84 pixels.setPixelColor(i, pixels.Color(255, 0, 100));
85 }
86 pixels.show();
87 delay(10000);
88 }
89
90 void victory2() {
91 for (int i = 0; i < 20; i++) {
92 pixels.setPixelColor(i, pixels.Color(255, 65, 0));
93 }
94 pixels.show();
95 delay(10000);
96 }
97
98 void resetLeds() {
99 v_compteur1 = -1;
100 v_compteur2 = 20;
101 for (int i = 0; i < 20; i++) {
102 pixels.setPixelColor(i, pixels.Color(0, 0, 0));
103 }
104 pixels.show();
105 }
106
107 void score(int compteur) {
108 if (compteur < 10) { // Gestion pour compteur1
109 for (int i = 0; i <= compteur; i++) {
110 pixels.setPixelColor(i, pixels.Color(0, 255, 0));
111 }
112 pixels.show();
113 if (compteur == 9) {
114 victory1(); // Appelle victory1() pour compteur1
115 resetLeds();
116 }
117 } else if (compteur >= 10) { // Gestion pour compteur2
118 for (int j = 19; j >= compteur; j--) {
119 pixels.setPixelColor(j, pixels.Color(0, 255, 0));
120 }
121 pixels.show();
122 if (compteur == 10) {
123 victory2(); // Appelle victory2() pour compteur2
124 resetLeds();
125 }
126 }
127 }
128
129
130 void setup() {
131 pinMode(BPred1, INPUT);
132 attachInterrupt(digitalPinToInterrupt(BPred1), red1, RISING);
133 pinMode(BPblue1, INPUT);
134 attachInterrupt(digitalPinToInterrupt(BPblue1), blue1, RISING);
135 pinMode(BPred2, INPUT);
136 attachInterrupt(digitalPinToInterrupt(BPred2), red2, RISING);
137 pinMode(BPblue2, INPUT);
138 attachInterrupt(digitalPinToInterrupt(BPblue2), blue2, RISING);
139 pixels.begin(); // INITIALISE l'objet ruban NeoPixel
140 pixels.show(); // Éteint tous les pixels aussi vite que possible.
141 pixels.setBrightness(50); // Gère la luminosité (max = 255)
142
143 mySoftwareSerial.begin(9600);
144 myDFPlayer.begin(mySoftwareSerial);
145 }
146
147 void loop() {
148 bool posBPred1 = digitalRead(BPred1);
149 bool posBPblue1 = digitalRead(BPblue1);
150 bool posBPred2 = digitalRead(BPred2);
151 bool posBPblue2 = digitalRead(BPblue2);
152
153 son = random(1, 7); // Génère un nombre aléatoire entre 1 et 6
154 int attente = random(2000, 5000);
155 myDFPlayer.setTimeOut(500);
156
157 myDFPlayer.volume(30); // Fixe le volume à 30 (maximum)
158
159 myDFPlayer.play(son); // Joue le fichier son correspondant
160
161 delay(attente);
162 }
étapes de fabrication
indiquer autant d'étape que nécessaire, chacune illustrée par des images (photo, dessins, ...)
étape 1
Nous avons réfléchi à une idée puis fais un dessin de la future maquette.
étape 2
Après avoir dessiné la maquette, nous l'avons construite pour se faire une idée plus réelle.
étape 3
Nous avons effectuer plusieurs tests afin de nous familiariser avec les composants, de les tester et de verifier quelles utilisations nous pourrons en faire.
étape 4
Nous avons designer notre reflexe box sur Inkscape afin de la réaliser a la découpe laser.
étape 5
Nous avons finalisé la boite finale et avons fait un flyer.
Troubleshouting
Quelles sont les difficultés, les problèmes, les solutions, les trucs et astuces pour que ça marche ? Nous avons rencontré de nombreuses difficultés concernant l'écriture du code. De plus, il reste encore de nombreux bugs qui permettent d'ajouter beaucoup de points. Nous avons également rencontré des problèmes liés à la taille de la boîte. Celle-ci, étant assez volumineuse (50 x 30 x 10 cm), n’a pas pu être fabriquée en bois. Nous avons donc dû nous résoudre à la réaliser en carton, ce qui a malheureusement diminué sa solidité.
1
2 /*
3 BROCHAGE
4 _________________
5 / D1 mini \
6 |[ ]RST TX[ ]|
7 |[ ]A0 -GPIO RX[ ]|
8 |[ ]D0-16 5-D1[X]| - data du ruban de led
9 |[ ]D5-14 4-D2[ ]|
10 |[ ]D6-12 0-D3[ ]|
11 |[ ]D7-13 2-D4[ ]| LED_BUILTIN
12 |[ ]D8-15 GND[X]| - masse du ruban
13 |[ ]3V3 . 5V[X]| - Alim du ruban
14 | +---+ |
15 |_______|USB|_______|
16 */
17 #include <SoftwareSerial.h>
18 #include <DFRobotDFPlayerMini.h>
19
20 SoftwareSerial mySoftwareSerial(14, 12); // TX, RX
21 DFRobotDFPlayerMini myDFPlayer;
22
23 #include <Adafruit_NeoPixel.h>
24
25 #define broche 5 //D1
26 #define nbpixels 20
27
28 Adafruit_NeoPixel pixels(nbpixels, broche, NEO_GRB + NEO_KHZ800);
29 #define delai 30
30
31 const int BPstart = 2; //D4
32 const int BPred1 = 15; //D8
33 const int BPblue1 = 4; //D2
34 const int BPred2 = 13; //D7
35 const int BPblue2 = 0; //D3
36
37 int v_compteur1 = -1;
38 int v_compteur2 = 20;
39 volatile int son = 0; // Utilisez volatile pour indiquer que cette variable peut être modifiée par une ISR
40
41 ICACHE_RAM_ATTR void red1() {
42 if (son == 3 || son == 6) {
43 v_compteur1 += 2;
44 score(v_compteur1);
45 } else {
46 v_compteur2 -= 2;
47 score(v_compteur2);
48 }
49 }
50
51 ICACHE_RAM_ATTR void blue1() {
52 if (son == 5 || son == 4) {
53 v_compteur1 += 1;
54 score(v_compteur1);
55 } else {
56 v_compteur2 -= 1;
57 score(v_compteur2);
58 }
59 }
60
61 ICACHE_RAM_ATTR void red2() {
62 if (son == 3 || son == 6) {
63 v_compteur2 -=2;
64 score(v_compteur2);
65 } else {
66 v_compteur1 += 2;
67 score(v_compteur1);
68 }
69 }
70
71 ICACHE_RAM_ATTR void blue2() {
72 if (son == 5 || son == 4) {
73 v_compteur2 -= 1;
74 score(v_compteur2);
75 } else {
76 v_compteur1 += 1;
77 score(v_compteur1);
78 }
79 }
80
81
82 void victory1() {
83 for (int i = 0; i < 20; i++) {
84 pixels.setPixelColor(i, pixels.Color(255, 0, 100));
85 }
86 pixels.show();
87 delay(10000);
88 }
89
90 void victory2() {
91 for (int i = 0; i < 20; i++) {
92 pixels.setPixelColor(i, pixels.Color(255, 65, 0));
93 }
94 pixels.show();
95 delay(10000);
96 }
97
98 void resetLeds() {
99 v_compteur1 = -1;
100 v_compteur2 = 20;
101 for (int i = 0; i < 20; i++) {
102 pixels.setPixelColor(i, pixels.Color(0, 0, 0));
103 }
104 pixels.show();
105 }
106
107 void score(int compteur) {
108 if (compteur < 10) { // Gestion pour compteur1
109 for (int i = 0; i <= compteur; i++) {
110 pixels.setPixelColor(i, pixels.Color(0, 255, 0));
111 }
112 pixels.show();
113 if (compteur == 9) {
114 victory1(); // Appelle victory1() pour compteur1
115 resetLeds();
116 }
117 } else if (compteur >= 10) { // Gestion pour compteur2
118 for (int j = 19; j >= compteur; j--) {
119 pixels.setPixelColor(j, pixels.Color(0, 255, 0));
120 }
121 pixels.show();
122 if (compteur == 10) {
123 victory2(); // Appelle victory2() pour compteur2
124 resetLeds();
125 }
126 }
127 }
128
129
130 void setup() {
131 pinMode(BPred1, INPUT);
132 attachInterrupt(digitalPinToInterrupt(BPred1), red1, RISING);
133 pinMode(BPblue1, INPUT);
134 attachInterrupt(digitalPinToInterrupt(BPblue1), blue1, RISING);
135 pinMode(BPred2, INPUT);
136 attachInterrupt(digitalPinToInterrupt(BPred2), red2, RISING);
137 pinMode(BPblue2, INPUT);
138 attachInterrupt(digitalPinToInterrupt(BPblue2), blue2, RISING);
139 pixels.begin(); // INITIALISE l'objet ruban NeoPixel
140 pixels.show(); // Éteint tous les pixels aussi vite que possible.
141 pixels.setBrightness(50); // Gère la luminosité (max = 255)
142
143 mySoftwareSerial.begin(9600);
144 myDFPlayer.begin(mySoftwareSerial);
145 }
146
147 void loop() {
148 bool posBPred1 = digitalRead(BPred1);
149 bool posBPblue1 = digitalRead(BPblue1);
150 bool posBPred2 = digitalRead(BPred2);
151 bool posBPblue2 = digitalRead(BPblue2);
152
153 son = random(1, 7); // Génère un nombre aléatoire entre 1 et 6
154 int attente = random(2000, 5000);
155 myDFPlayer.setTimeOut(500);
156
157 myDFPlayer.volume(30); // Fixe le volume à 30 (maximum)
158
159 myDFPlayer.play(son); // Joue le fichier son correspondant
160
161 delay(attente);
162 }
Elément de présentation
je met ici le document de présentation de mon projet