ENIB 2024 : Smash The Button
Titre de la fiche expérience :
Sommaire
Description
Notre équipe est composée de 4 membres : Samuel, Mathieu, Loane et Maïa.
Introduction
Le nom de notre jeu est Smash The Button. Il s’agit d’un jeu en un contre un. Le but est de conquérir un maximum de territoire en un minimum de temps. Le vainqueur est celui ayant le plus grand territoire.
Voici un exemple de partie que nous avons filmé.
Outil et matériel
Nous avons utilisé comme matériel un WS2811 LED Strip (permettant d’obtenir un grand nombre de LED), deux boutons poussoirs l’un rouge l’autre jaune, une carte Arduino Nano, un buzzer, une batterie externe , un bouton pour lancer le jeu et un bandeau de six LED afin de pouvoir visualiser les points.
Fichiers pour l'impression 3D
Inclure des fichiers pour le code
Inclure FASTLED pour la gestion des bandes de LED: Il faut faire : en haut à gauche : SKETCH => INCLUDE LIBRARY => MANAGE LIBRARIES Ce qui ouvre un menu. Dans ce menu rechercher : FASTLED Et cliquer sur "installer"
Inclure pitches.zip Fichier:Pitches.zip Une fois téléchargé : Faire : SKETCH => INCLUDE LIBRARY => ADD .ZIP LIBRARY Puis sélectionner Pitches.zip
Code Arduino
1
2 #include <FastLED.h>
3 #include "pitches.h"
4 #define LED_PIN 5
5
6 #define BANDEAU_PIN 4
7
8 #define BUZZER_PIN 7
9
10 #define NUM_LEDS 50
11
12 #define NUM_BANDEAU 6
13
14 #define BUTTON_PIN1 2
15
16 #define BUTTON_PIN2 3
17
18 #define DELAY_MS 50
19
20 #define RED_BUTTON_FREQ 100 // Frequency for the red button sound
21
22 #define GREEN_BUTTON_FREQ 200 // Frequency for the green button sound
23
24 #define MANCHE 2 //nombre de manche avant réinitialisation
25
26 CRGB leds[NUM_LEDS];
27 CRGB bandeau[NUM_BANDEAU];
28
29 //Choisir les musiques pas oublier d'inclure pitches.h
30 int melody[] = {
31 REST, REST, REST, NOTE_DS4,
32 NOTE_E4, REST, NOTE_FS4, NOTE_G4, REST, NOTE_DS4,
33 NOTE_E4, NOTE_FS4, NOTE_G4, NOTE_C5, NOTE_B4, NOTE_E4, NOTE_G4, NOTE_B4,
34 NOTE_AS4, NOTE_A4, NOTE_G4, NOTE_E4, NOTE_D4,
35 NOTE_E4, REST, REST,
36 };
37 int durations[] = {
38 2, 4, 8, 8,
39 4, 8, 8, 4, 8, 8,
40 8, 8, 8, 8, 8, 8, 8, 8,
41 2, 16, 16, 16, 16,
42 2, 4, 8,
43
44 };
45 int melody2[] = {
46 NOTE_E5, NOTE_E5, REST, NOTE_E5, REST, NOTE_C5, NOTE_E5,
47 NOTE_G5, REST, NOTE_G4, REST,
48
49 };
50
51 int durations2[] = {
52 8, 8, 8, 8, 8, 8, 8,
53 4, 4, 8, 4,
54 };
55 //
56
57 int ledCount1 = 0; // Number of red LEDs to light up from one end
58
59 int ledCount2 = 0; // Number of green LEDs to light up from the other end
60
61 bool buttonState1 = false;
62
63 bool lastButtonState1 = false;
64
65 bool buttonState2 = false;
66
67 bool lastButtonState2 = false;
68
69 bool isRedButtonPressed = false;
70
71 bool isGreenButtonPressed = false;
72
73 int point_vert = 0; //nb point vert
74
75 int point_rouge = 0; //nb point rouge
76
77 void setup() {
78
79 FastLED.addLeds<WS2812B, LED_PIN, GRB>(leds, NUM_LEDS);
80
81 FastLED.addLeds<WS2812B, BANDEAU_PIN, GRB>(bandeau, NUM_BANDEAU);
82
83 pinMode(BUTTON_PIN1, INPUT_PULLUP);
84
85 pinMode(BUTTON_PIN2, INPUT_PULLUP);
86
87 pinMode(BUZZER_PIN, OUTPUT);
88
89 }
90
91 void loop() {
92
93 buttonState1 = digitalRead(BUTTON_PIN1) == LOW;
94
95 buttonState2 = digitalRead(BUTTON_PIN2) == LOW;
96
97 for (int i = 0; i <= point_vert; i++) {
98
99 bandeau[NUM_BANDEAU-i-1] = CRGB::Red;
100 FastLED.show();
101
102 }
103 for (int i = 0; i <= point_rouge; i++) {
104 bandeau[i] = CRGB::Green;
105 FastLED.show();
106
107 }
108
109
110
111 if (buttonState1 != lastButtonState1) {
112
113 if (buttonState1) {
114
115 // Button 1 is pressed
116
117 ledCount1++;
118
119 if (ledCount1 > NUM_LEDS) {
120
121 ledCount1 = NUM_LEDS;
122
123 }
124
125 isRedButtonPressed = true;
126
127 tone(BUZZER_PIN, RED_BUTTON_FREQ); // Play the red button sound
128
129 }
130
131 lastButtonState1 = buttonState1;
132
133 }
134
135 if (buttonState2 != lastButtonState2) {
136
137 if (buttonState2) {
138
139 // Button 2 is pressed
140
141 ledCount2++;
142
143 if (ledCount2 > NUM_LEDS) {
144
145 ledCount2 = NUM_LEDS;
146
147 }
148
149 isGreenButtonPressed = true;
150
151 tone(BUZZER_PIN, GREEN_BUTTON_FREQ); // Play the green button sound
152
153 }
154
155 lastButtonState2 = buttonState2;
156
157 }
158
159
160
161 // Turn off all LEDs
162
163 //FastLED.clear();
164
165
166
167 // Light up the specified number of red LEDs from one end
168
169 for (int i = 0; i < ledCount1; i++) {
170
171 leds[i] = CRGB::Green;
172
173 }
174
175
176
177 // Light up the specified number of green LEDs from the other end
178
179 for (int i = NUM_LEDS - 1; i >= NUM_LEDS - ledCount2; i--) {
180
181 leds[i] = CRGB::Red;
182
183 }
184
185
186
187 if ((ledCount1 + ledCount2) >= NUM_LEDS) {
188
189 if (ledCount1 > ledCount2) {
190
191 greenChaserEffect();
192
193 } else if (ledCount2 > ledCount1) {
194
195 redChaserEffect();
196
197 } else {
198
199 // It's a tie
200
201 tieChaserEffect();
202
203
204 }
205
206
207
208 // Reset the LED counts
209
210 ledCount1 = 0;
211
212 ledCount2 = 0;
213
214 }
215
216
217
218 // Show the updated LED strip
219
220 FastLED.show();
221
222
223
224 if (isRedButtonPressed || isGreenButtonPressed) {
225
226 delay(50); // Adjust this delay to control the duration of the buzzer sound
227
228 noTone(BUZZER_PIN); // Stop the buzzer sound
229
230 isRedButtonPressed = false;
231
232 isGreenButtonPressed = false;
233
234 }
235
236
237
238 delay(50); // Adjust this delay to debounce the buttons and control the response speed
239
240 }
241
242
243
244 void tieChaserEffect() {
245
246
247
248 for (int i = 0; i < NUM_LEDS / 2; i++) {
249
250 leds[i] = CRGB::Red; // Set the color of the current LED to red
251
252 FastLED.show(); // Update the LED strip
253
254 delay(DELAY_MS); // Wait for a short period
255
256 }
257
258
259
260 for (int i = NUM_LEDS; i >= NUM_LEDS / 2; i--) {
261
262 leds[i] = CRGB::Green; // Set the color of the current LED to red
263
264 FastLED.show(); // Update the LED strip
265
266 delay(DELAY_MS); // Wait for a short period
267
268 }
269 FastLED.clear();
270
271 }
272
273
274 void addpointgreen() {
275 point_vert++; //vert gagne un point
276 bandeau[point_vert-1] = CRGB::Green; //allume la led verte au bon endroit
277 if (point_vert >= MANCHE) {
278 //reinitialisation de la partie
279 winsong();
280 point_rouge = 0;
281 point_vert = 0;
282 }
283 FastLED.show();
284 }
285
286 void greenChaserEffect() {
287
288 // Set all LEDs to green initially
289
290 for (int i = 0; i < ledCount1; i++) {
291
292 leds[i] = CRGB::Green;
293
294 }
295
296 FastLED.show(); // Update the LED strip with the initial green color
297
298
299
300 for (int i = ledCount1; i < NUM_LEDS; i++) {
301
302 leds[i] = CRGB::Green; // Set the color of the current LED to red
303
304 FastLED.show(); // Update the LED strip
305
306 delay(DELAY_MS); // Wait for a short period
307
308 }
309
310 addpointgreen();
311 FastLED.clear();
312 }
313
314
315 void addpointred() {
316 point_rouge++;//+1 point rouge
317 bandeau[NUM_BANDEAU-point_rouge] = CRGB::Red; //allume la led red au bon endroit
318 if (point_rouge >= MANCHE) {
319 //reinitialiser la partie
320 winsong2();
321 point_rouge = 0;
322 point_vert = 0;
323 }
324 FastLED.show();
325 }
326
327 void redChaserEffect() {
328
329 // Set all LEDs to green initially
330
331 for (int i = NUM_LEDS - 1; i >= NUM_LEDS - ledCount2; i--) {
332
333 leds[i] = CRGB::Red;
334
335 }
336
337 FastLED.show(); // Update the LED strip with the initial green color
338
339
340
341 for (int i = ledCount2; i > 0; i--) {
342
343 leds[i] = CRGB::Red; // Set the color of the current LED to red
344
345 FastLED.show(); // Update the LED strip
346
347 delay(DELAY_MS); // Wait for a short period
348
349 }
350 addpointred();
351 FastLED.clear();
352 }
353
354 void winsong(){
355 int size = sizeof(durations2) / sizeof(int);
356
357 for (int note = 0; note < size; note++) {
358 //to calculate the note duration, take one second divided by the note type.
359 //e.g. quarter note = 1000 / 4, eighth note = 1000/8, etc.
360 int duration = 1000 / durations2[note];
361 tone(BUZZER_PIN, melody2[note], duration);
362
363 //to distinguish the notes, set a minimum time between them.
364 //the note's duration + 30% seems to work well:
365 int pauseBetweenNotes = duration * 1.30;
366 delay(pauseBetweenNotes);
367
368 //stop the tone playing:
369 noTone(BUZZER_PIN);
370 }
371 }
372 void winsong2(){
373 int size = sizeof(durations) / sizeof(int);
374
375 for (int note = 0; note < size; note++) {
376 //to calculate the note duration, take one second divided by the note type.
377 //e.g. quarter note = 1000 / 4, eighth note = 1000/8, etc.
378 int duration = 1000 / durations[note];
379 tone(BUZZER_PIN, melody[note], duration);
380
381 //to distinguish the notes, set a minimum time between them.
382 //the note's duration + 30% seems to work well:
383 int pauseBetweenNotes = duration * 1.30;
384 delay(pauseBetweenNotes);
385
386 //stop the tone playing:
387 noTone(BUZZER_PIN);
388 }
389 }
Étapes de fabrication
Étape 1
Tout d'abord nous avons fait l'inventaire de ce dont nous avions besoin en plus du kit pour la partie électronique. Il nous manquait une alimentation, trois câbles rouges, sept câbles noirs ou gris et quatre câbles de couleurs (vert).
Étape 2
Nous avons commencé avec la partie informatique. Nous avons débuté avec la connexion de la carte à l'ordinateur.
Il faut commencer par brancher la carte à l'ordinateur et ouvrir le logiciel de programmation (IDE) sur l'ordinateur. Puis copier le code donné plus haut dans ce wiki et le coller. Et installer les librairies. Cette étape est expliquée au dessus.
Ensuite, il faudra sélectionné votre carte dans la section TOOLS => PORT et sélectionner votre carte Après, on envoie le programme sur la carte en appuyant sur le bouton en forme de flèche tout en haut à gauche : Upload. Cette étape peut être compliqué et peut créer des erreurs. N'Hésitez pas à vous référez à la partie problèmes rencontrés.
Étape 3
Puis nous avons continué avec la partie électronique, en faisant le câblage à l'aide de ce schéma.
Étape 4
Puis nous avons soudé notre câblage afin d'obtenir un rendu propre.
Étape 5
Nous avons choisi le carton comme matériau pour faire le patron. On a alors dessiné le patron.
Étape 6
Ensuite, nous sommes passés au découpage.
Étape 7
Après, nous sommes passés à l'assemblage. Tout d'abord nous nous sommes occupés des boutons.
On obtient ceci.
Puis on s'occupe de la mise en place des différentes LED sur le support.
Étape 8
On obtient après assemblage, une version éteinte et une version allumée du prototype.
Étape 9
Amélioration du projet :
Nous avons ajouté deux fonctionnalités au jeu de base.
La première est un système de partie avec des points (trois points maximum) et des manches. En lien direct avec cela, nous avons ajouté un bandeau LED qui permet d'afficher les points de chaque joueurs.
Par exemple : Si le joueur vert à 1 point, deux LED de sa couleur s'affichent. (Bizarre le 2 led alors qu'il a 1 point non ??) Si le joueur rouge à 0 point, un LED de sa couleur s'affiche. Ect.
Le premier joueur à gagner trois manches, remporte la partie ! Quand la partie est finie un jingle se joue sur le buzzer. Ce jingle est différent en fonction du joueur qui gagne !
Étape 10
Nous avons alors conçu la version finale du projet, la boîte finale étant en bois nous avons privilégié une découpe laser, les différentes planches ont été dessinées sur Inkscape puis exporté au format .svg, pour être compatible avec la découpeuse laser.
Étape 11
Nous sommes alors passé à l'assemblage de la version finale à l'aide des encoches prévues à cet effet.
Étape 12
Nous obtenons donc la version finale.
Problèmes rencontrés
En utilisant une carte Arduino nano, il se peut que vous ayez une erreur :
"cpp vrdude: stk500_recv(): programmer is not responding "
Vous pouvez alors aller dans : TOOLS => Processor et sélectionner ATmega328p(old bootloader)