ENIB 2024 : Bass Hero : Différence entre versions
(→Code Arduino) |
(→Code Arduino) |
||
Ligne 38 : | Ligne 38 : | ||
===Code Arduino=== | ===Code Arduino=== | ||
<syntaxhighlight lang="Arduino" line> | <syntaxhighlight lang="Arduino" line> | ||
− | |||
#include <Adafruit_GFX.h> | #include <Adafruit_GFX.h> | ||
#include <Adafruit_NeoMatrix.h> | #include <Adafruit_NeoMatrix.h> |
Version du 31 janvier 2024 à 16:00
Titre de la fiche expérience :
Sommaire
Description (résumé)
Notre équipe a décidé pour se Hackathon de créer un jeu de rythme inspiré de la série de jeux vidéos "Guitar Hero" qui consiste à appuyer sur des boutons en fonction du rythme de la musique et des indications à l'écran. Nous l'avons nommé "Bass Hero"
Pour ce faire des carrés lumineux descendront sur un écran LED 16x16 et indiqueront au joueur à quels moments appuyer sur les boutons correspondant
Introduction
Nous sommes 5 à participer à ce projet:
Yassine, Olivier, Antoine, Yann, Rodrigue
Le projet que nous avons choisis n'avait pas de thème précis donc nous avons pu laisser libre cours à notre imagination, et nous avons donc eu l'idée de faire un jeu de rythme simple pour pouvoir utiliser complétement la grille de LED 16x16 qui nous a été donné
Outil et matériel
- Carte Arduino Nano
- 4 Boutons
- Buzzer Piézo-électrique
- Câbles
- BreadBoard
- Écran LCD
- Écran LED 16x16
- Boite en carton
Fichiers joint
Code Arduino
1
2 #include <Adafruit_GFX.h>
3 #include <Adafruit_NeoMatrix.h>
4 #include <Adafruit_NeoPixel.h>
5
6 #define NOTE_B0 31
7 #define NOTE_C1 33
8 #define NOTE_CS1 35
9 #define NOTE_D1 37
10 #define NOTE_DS1 39
11 #define NOTE_E1 41
12 #define NOTE_F1 44
13 #define NOTE_FS1 46
14 #define NOTE_G1 49
15 #define NOTE_GS1 52
16 #define NOTE_A1 55
17 #define NOTE_AS1 58
18 #define NOTE_B1 62
19 #define NOTE_C2 65
20 #define NOTE_CS2 69
21 #define NOTE_D2 73
22 #define NOTE_DS2 78
23 #define NOTE_E2 82
24 #define NOTE_F2 87
25 #define NOTE_FS2 93
26 #define NOTE_G2 98
27 #define NOTE_GS2 104
28 #define NOTE_A2 110
29 #define NOTE_AS2 117
30 #define NOTE_B2 123
31 #define NOTE_C3 131
32 #define NOTE_CS3 139
33 #define NOTE_D3 147
34 #define NOTE_DS3 156
35 #define NOTE_E3 165
36 #define NOTE_F3 175
37 #define NOTE_FS3 185
38 #define NOTE_G3 196
39 #define NOTE_GS3 208
40 #define NOTE_A3 220
41 #define NOTE_AS3 233
42 #define NOTE_B3 247
43 #define NOTE_C4 262
44 #define NOTE_CS4 277
45 #define NOTE_D4 294
46 #define NOTE_DS4 311
47 #define NOTE_E4 330
48 #define NOTE_F4 349
49 #define NOTE_FS4 370
50 #define NOTE_G4 392
51 #define NOTE_GS4 415
52 #define NOTE_A4 440
53 #define NOTE_AS4 466
54 #define NOTE_B4 494
55 #define NOTE_C5 523
56 #define NOTE_CS5 554
57 #define NOTE_D5 587
58 #define NOTE_DS5 622
59 #define NOTE_E5 659
60 #define NOTE_F5 698
61 #define NOTE_FS5 740
62 #define NOTE_G5 784
63 #define NOTE_GS5 831
64 #define NOTE_A5 880
65 #define NOTE_AS5 932
66 #define NOTE_B5 988
67 #define NOTE_C6 1047
68 #define NOTE_CS6 1109
69 #define NOTE_D6 1175
70 #define NOTE_DS6 1245
71 #define NOTE_E6 1319
72 #define NOTE_F6 1397
73 #define NOTE_FS6 1480
74 #define NOTE_G6 1568
75 #define NOTE_GS6 1661
76 #define NOTE_A6 1760
77 #define NOTE_AS6 1865
78 #define NOTE_B6 1976
79 #define NOTE_C7 2093
80 #define NOTE_CS7 2217
81 #define NOTE_D7 2349
82 #define NOTE_DS7 2489
83 #define NOTE_E7 2637
84 #define NOTE_F7 2794
85 #define NOTE_FS7 2960
86 #define NOTE_G7 3136
87 #define NOTE_GS7 3322
88 #define NOTE_A7 3520
89 #define NOTE_AS7 3729
90 #define NOTE_B7 3951
91 #define NOTE_C8 4186
92 #define NOTE_CS8 4435
93 #define NOTE_D8 4699
94 #define NOTE_DS8 4978
95 #define REST 0
96
97 #define PIN 8
98 #define BTN_X 2
99 #define BTN_Y 3
100 #define BTN_Z 4
101 #define BTN_W 5
102 #ifndef PSTR
103 #define PSTR // Make Arduino Due happy
104 #endif
105
106 // change this to whichever pin you want to use
107 int buzzer = 11;
108
109 int music[] = {1,0,3,0,0,2,3,1,1,2,3,1,1,0,2,1,3,1,0,3,0,0,2,3,1,1,2,3,1,1,0,2,1,3,1,0,3,0,0,2,3,1,1,2,3,1,1,
110 0,2,1,3,1,0,3,0,0,2,3,1,1,2,3,1,1,0,2,1,3,1,0,3,0,0,2,3,1,1,2,3,1,1,0,2,1,3,1,0,3,0,0,2,3,1,1,
111 0,2,1,3,1,0,3,0,0,2,3,1,1,2,3,1,1,0,2,1,3,1,0,3,0,0,2,3,1,1,2,3,1,1,0,2,1,3,1,0,3,0,0,2,3,1,1,
112 0,2,1,3,1,0,3,0,0,2,3,1,1,2,3,1,1,0,2,1,3,1,0,3,0,0,2,3,1,1,2,3,1,1,0,2,1,3,1,0,3,0,0,2,3,1,1,};
113 int tempo = 100;
114 //int wholenote = (60000 * 4) / tempo;
115
116 // notes of the moledy followed by the duration.
117 // a 4 means a quarter note, 8 an eighteenth , 16 sixteenth, so on
118 // !!negative numbers are used to represent dotted notes,
119 // so -4 means a dotted quarter note, that is, a quarter plus an eighteenth!!
120 /*int melody[] = {
121
122 // Nokia Ringtone
123 // Score available at https://musescore.com/user/29944637/scores/5266155
124
125 NOTE_E5, 8, NOTE_D5, 8, NOTE_FS4, 4, NOTE_GS4, 4,
126 NOTE_CS5, 8, NOTE_B4, 8, NOTE_D4, 4, NOTE_E4, 4,
127 NOTE_B4, 8, NOTE_A4, 8, NOTE_CS4, 4, NOTE_E4, 4,
128 NOTE_A4, 2,
129 };*/
130 int melody[] = {
131
132 // Song of storms - The Legend of Zelda Ocarina of Time.
133 // Score available at https://musescore.com/user/4957541/scores/1545401
134
135 NOTE_D4,4, NOTE_A4,4, NOTE_A4,4,
136 REST,8, NOTE_E4,8, NOTE_B4,2,
137 NOTE_F4,4, NOTE_C5,4, NOTE_C5,4,
138 REST,8, NOTE_E4,8, NOTE_B4,2,
139 NOTE_D4,4, NOTE_A4,4, NOTE_A4,4,
140 REST,8, NOTE_E4,8, NOTE_B4,2,
141 NOTE_F4,4, NOTE_C5,4, NOTE_C5,4,
142 REST,8, NOTE_E4,8, NOTE_B4,2,
143 NOTE_D4,8, NOTE_F4,8, NOTE_D5,2,
144
145 NOTE_D4,8, NOTE_F4,8, NOTE_D5,2,
146 NOTE_E5,-4, NOTE_F5,8, NOTE_E5,8, NOTE_E5,8,
147 NOTE_E5,8, NOTE_C5,8, NOTE_A4,2,
148 NOTE_A4,4, NOTE_D4,4, NOTE_F4,8, NOTE_G4,8,
149 NOTE_A4,-2,
150 NOTE_A4,4, NOTE_D4,4, NOTE_F4,8, NOTE_G4,8,
151 NOTE_E4,-2,
152 NOTE_D4,8, NOTE_F4,8, NOTE_D5,2,
153 NOTE_D4,8, NOTE_F4,8, NOTE_D5,2,
154
155 NOTE_E5,-4, NOTE_F5,8, NOTE_E5,8, NOTE_E5,8,
156 NOTE_E5,8, NOTE_C5,8, NOTE_A4,2,
157 NOTE_A4,4, NOTE_D4,4, NOTE_F4,8, NOTE_G4,8,
158 NOTE_A4,2, NOTE_A4,4,
159 NOTE_D4,1,
160 };
161
162 // sizeof gives the number of bytes, each int value is composed of two bytes (16 bits)
163 // there are two values per note (pitch and duration), so for each note there are four bytes
164 int notes = sizeof(melody) / sizeof(melody[0]) / 2;
165
166 // this calculates the duration of a whole note in ms
167 int wholenote = (60000 * 4) / tempo;
168
169 int divider = 0, noteDuration = 0;
170
171
172
173 Adafruit_NeoMatrix matrix = Adafruit_NeoMatrix(16, 16, PIN,
174 NEO_MATRIX_BOTTOM + NEO_MATRIX_RIGHT +
175 NEO_MATRIX_COLUMNS + NEO_MATRIX_ZIGZAG,
176 NEO_GRB + NEO_KHZ800);
177
178 const uint16_t colors[] = { matrix.Color(255, 184, 28), matrix.Color(0, 219, 73), matrix.Color(255, 41, 60), matrix.Color(24, 12, 255), matrix.Color(50, 50, 50) };
179
180 int score = 0;
181 int pass = 0;
182 int iterator = 0;
183 int currentState = LOW;
184
185 void setup() {
186 // put your setup code here, to run once:
187 matrix.begin();
188 matrix.setTextWrap(false);
189 matrix.setBrightness(40);
190 matrix.setTextColor(colors[0]);
191
192 pinMode(BTN_X, INPUT_PULLUP);
193 pinMode(BTN_Y, INPUT_PULLUP);
194 pinMode(BTN_Z, INPUT_PULLUP);
195 pinMode(BTN_W, INPUT_PULLUP);
196 }
197
198 bool play_note(int offset, int color, int thisNote) {
199 bool note_played = false;
200 int x=matrix.width();
201 int t_start=millis();
202 int t_loop=millis();
203
204 divider = melody[thisNote + 1];
205 if (divider > 0) {
206 // regular note, just proceed
207 noteDuration = (wholenote) / divider;
208 } else if (divider < 0) {
209 // dotted notes are represented with negative durations!!
210 noteDuration = (wholenote) / abs(divider);
211 noteDuration *= 1.5; // increases the duration in half for dotted notes
212 }
213
214 while (x>1) {
215 x=x-1;
216 matrix.begin();
217 matrix.drawLine(x, 1+offset, x-1, 1+offset, colors[color]);
218 matrix.drawLine(x, 2+offset, x-1, 2+offset, colors[color]);
219 matrix.drawLine(x+1, 1+offset, x+1, 2+offset, matrix.Color(0, 0, 0));
220 matrix.show();
221 while (1) {
222 t_loop=millis();
223
224 if (x<10) {
225 /* IMPLEMENT BUTTON CHECK */
226 /* PLAY NOTE SOUND HERE ? */
227
228 currentState=HIGH;
229 if (color==0) {currentState = digitalRead(BTN_X);}
230 else if (color==1) {currentState = digitalRead(BTN_Y);}
231 else if (color==2) {currentState = digitalRead(BTN_Z);}
232 else if (color==3) {currentState = digitalRead(BTN_W);}
233
234 if (currentState!=HIGH) {
235 note_played=true;
236 }
237 if (note_played==true) {
238 tone(buzzer, melody[thisNote], noteDuration * 0.9);
239 }
240
241 }
242
243 if (t_loop>t_start+15) {
244 t_start=millis();
245 noTone(buzzer);
246 break;
247 }
248 }
249 }
250 return note_played;
251 }
252
253 void loop() {
254 if (play_note(4*music[iterator], music[iterator], iterator*2)==true) {score+=1;}
255 else {/* DO SOMETHING IF MISSED NOTE */}
256
257 ++iterator; if (iterator>(int)(sizeof(melody)/2)) {iterator=0;}
258
259 //delay(100);
260 }
Étapes de fabrication
Voici les différentes étapes que nous avons utilisé pour arriver au projet final:
Étape 1
Pour commencer on a fabriqué un prototype de la boite en partant d'un carton vide, qui contiendra les circuits internes pour avoir une idée de à quoi ressemblera le projet final:
Étape 2
Début de la création du code (connexions à la carte, affichage des lumières):
Étape 3
Préparation des circuits électroniques:
Étape 4
Préparation de la boite du produit final:
Étape 5
Finalisation du code et préparation des interactions avec le joueur:
Étape 6
Installation des composants:
Étape 7
Projet Terminé:
Difficultés rencontrés
Le plus gros problème qui nous a été posé été la presque impossibilité de se connecter à la carte ESP32 et à la carte Arduino qui avait été utilisé pour replacer la carte ESP32 à cause de ce problème. Cette difficulté est celle qui nous a fait perdre la grande majorité de notre temps et qui a dû être compenser par la programmation du jeu en dehors des heures allouées. Nous n'avons pas vraiment réglé ce souci mais nous avons dû faire avec.
Nous n'avons pas pu utiliser la boite du prototype car nous n'avons pas eu le temps de découper les planches de bois bien que les plans soient prêt à être utilisés et des composants été cassés
Nous avons aussi dû abandonner l'idée d'utiliser des haut parleurs pour la musique et le remplacer par un buzzer piézo-électrique de plus l'installation du lecteur LCD n'a pas pu être faites par manque de temps
Projet Complémentaire Bass Hero +
En vue de la possibilité de non réussite du projet Bass Hero, nous avons pu faire en une dizaine de minutes et en nous basant sur les connaissances acquises pendant ce Hackaton, un autre jeu pour pouvoir présenter quelque chose aux enfants.
Ce jeu ce base sur le très célèbre "Dinosaur game" qui apparait quand un utilisateur du navigateur Google n'a pas de connexion.
Bass Hero + ce joue en appuyant sur le bouton central pour pouvoir esquiver les obstacles barrant la route du joueur.