ENIB 2024 : Bass Hero

De Les Fabriques du Ponant
Révision datée du 31 janvier 2024 à 17:00 par Olivier25 (discussion | contributions) (Code Arduino)
Aller à : navigation, rechercher

Titre de la fiche expérience :

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"

BassHero.png

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

Yassine.jpg Olivier Riviere.jpg Antoine Vermander.PNG Yann Tissier.jpg Rodrigue Lemaire.jpg

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:

Circuit Bass Hero.png

É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:

Carton vide Bass Hero.jpg Prototype 1 Bass Hero.jpg

Étape 2

Début de la création du code (connexions à la carte, affichage des lumières):

Codage du debut Bass Hero.jpg

Étape 3

Préparation des circuits électroniques:

Electronique Bass Hero.jpg Connexions Electronique Bass Hero.jpg

Étape 4

Préparation de la boite du produit final:

Préparation boite final Bass Hero.jpg

Étape 5

Finalisation du code et préparation des interactions avec le joueur:

Finialisation Bass Hero.gif

Étape 6

Installation des composants:

Installation Bass Hero.jpg

Étape 7

Projet Terminé:

Fin de projet Bass Hero.jpg

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.

Bass Hero plus.jpg

ne pas modifier sous cette ligne