ENIB 2024 : Le Cyclone Breton : Différence entre versions
(→Code Arduino) |
(→Code Arduino) |
||
Ligne 60 : | Ligne 60 : | ||
#include "FastLED.h" | #include "FastLED.h" | ||
− | #define NUM_LEDS 60 //on utilise 60 | + | #define NUM_LEDS 60 //on utilise 60 LEDs |
#define DATA_PIN A0 | #define DATA_PIN A0 | ||
#define SCORE_PIN 6 | #define SCORE_PIN 6 | ||
#define SCORE_LEDS 6 | #define SCORE_LEDS 6 | ||
− | #define BRIGHTNESS 30 //luminosite de la | + | #define BRIGHTNESS 30 //luminosite de la LED |
− | CRGB leds[NUM_LEDS]; //variable constante | + | CRGB leds[NUM_LEDS]; //variable constante LEDs |
− | CRGB sleds[NUM_LEDS]; //variable constante score | + | CRGB sleds[NUM_LEDS]; //variable constante score LEDs |
bool reachedEnd = false; | bool reachedEnd = false; | ||
Ligne 74 : | Ligne 74 : | ||
int period = 1000; | int period = 1000; | ||
unsigned long time_now = 0; | unsigned long time_now = 0; | ||
− | byte Position = 0; //position de la | + | byte Position = 0; //position de la LED |
byte level = 0; | byte level = 0; | ||
− | const byte ledSpeed[6] = {50, 40, 30, 20, 14, 7}; //differentes vitesses de la | + | const byte ledSpeed[6] = {50, 40, 30, 20, 14, 7}; //differentes vitesses de la LED rouge |
//Debounce | //Debounce | ||
Ligne 88 : | Ligne 88 : | ||
// put your setup code here, to run once: | // put your setup code here, to run once: | ||
FastLED.addLeds<WS2812B, DATA_PIN, GRB>(leds, NUM_LEDS); //configure la bibliothèque FastLED pour utiliser des LEDs de type WS2812B (ou compatibles) avec la broche DATA_PIN. | FastLED.addLeds<WS2812B, DATA_PIN, GRB>(leds, NUM_LEDS); //configure la bibliothèque FastLED pour utiliser des LEDs de type WS2812B (ou compatibles) avec la broche DATA_PIN. | ||
− | //Les LEDs sont déclarées dans le tableau | + | //Les LEDs sont déclarées dans le tableau LEDs et le nombre total de LEDs est spécifié par NUM_LEDS |
FastLED.addLeds<WS2812B, SCORE_PIN, GRB>(sleds, SCORE_LEDS); | FastLED.addLeds<WS2812B, SCORE_PIN, GRB>(sleds, SCORE_LEDS); | ||
Ligne 111 : | Ligne 111 : | ||
delay(500); //fait une pause de 500 millisecondes | delay(500); //fait une pause de 500 millisecondes | ||
for (byte i = 0; i < NUM_LEDS; i++) { | for (byte i = 0; i < NUM_LEDS; i++) { | ||
− | leds[i].setRGB(0, 0, 0); //on eteint toutes les | + | leds[i].setRGB(0, 0, 0); //on eteint toutes les LEDs |
delay(40); | delay(40); | ||
− | FastLED.show(); //Met à jour l'affichage pour refléter les changements sur les | + | FastLED.show(); //Met à jour l'affichage pour refléter les changements sur les LEDs. |
int thisPitch = map (i, 60, 0, 100, 1500); //Utilise la fonction map pour convertir la valeur de i d'une plage de 60 à 0 en une plage de 100 à 1500. Cette valeur est utilisée comme fréquence pour générer un ton. | int thisPitch = map (i, 60, 0, 100, 1500); //Utilise la fonction map pour convertir la valeur de i d'une plage de 60 à 0 en une plage de 100 à 1500. Cette valeur est utilisée comme fréquence pour générer un ton. | ||
//tone(9, thisPitch,120); //Genere une note sur la broche 9, à la frequence thisPitch (en Hz) pendant 120 millisecondes | //tone(9, thisPitch,120); //Genere une note sur la broche 9, à la frequence thisPitch (en Hz) pendant 120 millisecondes | ||
} | } | ||
for (byte i = 0; i < SCORE_LEDS; i++) { | for (byte i = 0; i < SCORE_LEDS; i++) { | ||
− | sleds[i].setRGB(0, 0, 0); //eteindre toutes les | + | sleds[i].setRGB(0, 0, 0); //eteindre toutes les LEDs de score |
delay(100); | delay(100); | ||
FastLED.show(); | FastLED.show(); | ||
Ligne 273 : | Ligne 273 : | ||
for (byte i = 0; i < 3; i++) { | for (byte i = 0; i < 3; i++) { | ||
for (byte j = 0; j < NUM_LEDS; j++) { | for (byte j = 0; j < NUM_LEDS; j++) { | ||
− | leds[j].setRGB(0, 255, 0); //on met toutes les | + | leds[j].setRGB(0, 255, 0); //on met toutes les LEDs en vert |
Ligne 297 : | Ligne 297 : | ||
for (byte i = 0; i < 3; i++) { | for (byte i = 0; i < 3; i++) { | ||
for (byte j = 0; j < NUM_LEDS; j++) { | for (byte j = 0; j < NUM_LEDS; j++) { | ||
− | leds[j].setRGB(255, 0, 0); //on met toutes les | + | leds[j].setRGB(255, 0, 0); //on met toutes les LEDs en rouge |
//tone(9, 200, 250); | //tone(9, 200, 250); | ||
Ligne 367 : | Ligne 367 : | ||
void clearLEDS() { | void clearLEDS() { | ||
for (byte i = 0; i < NUM_LEDS; i++) { | for (byte i = 0; i < NUM_LEDS; i++) { | ||
− | leds[i].setRGB(0, 0, 0); //on eteint les | + | leds[i].setRGB(0, 0, 0); //on eteint les LEDs |
} | } | ||
} | } |
Version du 25 janvier 2024 à 12:07
Titre de la fiche expérience :
Sommaire
description
Nous sommes 5 élèves ingénieurs de 3ème année à l'ENIB : Thomas Mauger, Gregory Jourdain, Benjamin Le Corre, Romaric Hubert, et Martin Candoni
Dans le cadre de l'inter-semestre 3 à l'ENIB, nous avons fait, lors d'un Hackathon, le jeu du cyclone (appelé ici "Le cyclone Breton").
Le but du jeu est d'appuyer sur le bouton quand la led verte (celle qui tourne autour du cercle) est au même endroit que la zone à atteindre (celle en rouge sur le cercle).
Il y a 5 niveaux différents, avec une musique de victoire et une musique de défaite.
Introduction
éventuelle vidéo
outil et matériel
Outils :
- Fer à souder pour l’étain
- Scie
- Pistolet à colle
- Imprimante 3D (facultatif)
- Découpeuse laser (facultatif)
Matériel :
1 Arduino-Nano
1 Anneau WS2812 avec 60 LED
1 Bouton-poussoir
1 Transistor à usage général NPN
1 Plaque labdec*
25 fils électriques
1 Avertisseur sonore
2 Résistance 220 ohms
1 Résistance à trou traversant, 820 ohm
1 Batterie portable (5 Volts, 3 Ampères)
Bobine d'étain
Colle
fichiers à joindre
code, ficher d'impression 3D, de découpe laser ou vinyle, ...
Code Arduino
1
2 //----------------------Variables----------------------
3
4 #include "FastLED.h"
5 #define NUM_LEDS 60 //on utilise 60 LEDs
6 #define DATA_PIN A0
7 #define SCORE_PIN 6
8 #define SCORE_LEDS 6
9 #define BRIGHTNESS 30 //luminosite de la LED
10 CRGB leds[NUM_LEDS]; //variable constante LEDs
11 CRGB sleds[NUM_LEDS]; //variable constante score LEDs
12
13 bool reachedEnd = false;
14
15 byte gameState = 0; //niveau du jeu
16 //byte ledSpeed = 0;
17 int period = 1000;
18 unsigned long time_now = 0;
19 byte Position = 0; //position de la LED
20 byte level = 0;
21
22 const byte ledSpeed[6] = {50, 40, 30, 20, 14, 7}; //differentes vitesses de la LED rouge
23
24 //Debounce
25 bool findRandom = false; //Indique si une nouvelle position aléatoire doit être trouvée
26 byte spot = 0; //On y stocke la position aleatoire
27
28 //-----------------------------------------------------
29
30 void setup() {
31 // put your setup code here, to run once:
32 FastLED.addLeds<WS2812B, DATA_PIN, GRB>(leds, NUM_LEDS); //configure la bibliothèque FastLED pour utiliser des LEDs de type WS2812B (ou compatibles) avec la broche DATA_PIN.
33 //Les LEDs sont déclarées dans le tableau LEDs et le nombre total de LEDs est spécifié par NUM_LEDS
34
35 FastLED.addLeds<WS2812B, SCORE_PIN, GRB>(sleds, SCORE_LEDS);
36 pinMode(A3, INPUT_PULLUP); //Configure la broche A3 en mode d'entrée avec résistance de tirage vers le haut (INPUT_PULLUP)
37 Serial.begin(9600);// Initialise la communication série avec une vitesse de transmission de 9600 bauds.
38 //Cela permet de communiquer avec le moniteur série de l'IDE Arduino pour déboguer et afficher des informations pendant l'exécution du programme.
39 Serial.println("Reset"); //Envoie le message "Reset" via la communication série.
40 //Cela peut être utile pour signaler le redémarrage du microcontrôleur ou pour des fins de débogage.
41 }
42
43 void loop() {
44 // put your main code here, to run repeatedly:
45 FastLED.setBrightness(BRIGHTNESS );
46 if (gameState == 0) {
47
48 fill_rainbow(leds, NUM_LEDS, 0, 20); //2 = longer gradient strip
49 fill_rainbow(sleds, SCORE_LEDS, 0, 40); //2 = longer gradient strip
50
51 if (digitalRead(A3) == LOW) { //on vient lire la broche A3, si c'est en LOW (bas), on exécute le code ci-dessous
52 Position = 0;
53 findRandom = true;
54 delay(500); //fait une pause de 500 millisecondes
55 for (byte i = 0; i < NUM_LEDS; i++) {
56 leds[i].setRGB(0, 0, 0); //on eteint toutes les LEDs
57 delay(40);
58 FastLED.show(); //Met à jour l'affichage pour refléter les changements sur les LEDs.
59 int thisPitch = map (i, 60, 0, 100, 1500); //Utilise la fonction map pour convertir la valeur de i d'une plage de 60 à 0 en une plage de 100 à 1500. Cette valeur est utilisée comme fréquence pour générer un ton.
60 //tone(9, thisPitch,120); //Genere une note sur la broche 9, à la frequence thisPitch (en Hz) pendant 120 millisecondes
61 }
62 for (byte i = 0; i < SCORE_LEDS; i++) {
63 sleds[i].setRGB(0, 0, 0); //eteindre toutes les LEDs de score
64 delay(100);
65 FastLED.show();
66 }
67 gameState = 1; //passer au niveau 1
68 }
69 FastLED.show();
70 }
71 if (gameState == 1) {
72 period = ledSpeed[0];
73 if (millis() > time_now + period) {
74 time_now = millis();
75 if (findRandom) {
76 spot = random(56) + 3;
77 findRandom = false;
78 }
79 leds[spot - 1].setRGB(255, 140, 0);
80 leds[spot].setRGB(0, 255, 0);
81 leds[spot + 1].setRGB(255, 110, 0);
82 sleds[0].setRGB(0, 255, 0);
83 PlayGame(spot - 1, spot + 1);
84 }
85 if (digitalRead(A3) == LOW) {
86 delay(300);
87 findRandom = false;
88 if (Position > spot - 1 && Position < spot + 3) {
89 level = gameState;
90 gameState = 98;
91 } else {
92 gameState = 99;
93 }
94 }
95 }
96 if (gameState == 2) {
97 // period = 320;
98 period = ledSpeed[1];
99 if (millis() > time_now + period) {
100 time_now = millis();
101 if (findRandom) {
102 spot = random(56) + 3;
103 findRandom = false;
104 }
105 leds[spot - 1].setRGB(255, 190, 0);
106 leds[spot].setRGB(0, 255, 0);
107 leds[spot + 1].setRGB(255, 190, 0);
108 sleds[1].setRGB(255, 255, 0);
109 PlayGame(spot - 1, spot + 1);
110 }
111 if (digitalRead(A3) == LOW) {
112 delay(300);
113 if (spot - 1 && Position < spot + 3) {
114 level = gameState;
115 gameState = 98;
116 } else {
117 gameState = 99;
118 }
119 }
120 }
121 if (gameState == 3) {
122 period = ledSpeed[2];
123 if (millis() > time_now + period) {
124 time_now = millis();
125 if (findRandom) {
126 spot = random(56) + 3;
127 findRandom = false;
128 }
129 leds[spot].setRGB(0, 255, 0);
130 sleds[2].setRGB(255, 50, 0);
131 PlayGame(spot, spot);
132 }
133 if (digitalRead(A3) == LOW) {
134 delay(300);
135 if (Position == spot+1) {
136
137 level = gameState;
138 gameState = 98;
139 } else {
140 gameState = 99;
141 }
142 }
143 }
144 if (gameState == 4) {
145 period = ledSpeed[3];
146 if (millis() > time_now + period) {
147 time_now = millis();
148 if (findRandom) {
149 spot = random(56) + 3;
150 findRandom = false;
151 }
152 leds[spot].setRGB(0, 255, 0);
153 sleds[3].setRGB(255, 0, 0);
154 PlayGame(spot, spot);
155 }
156 if (digitalRead(A3) == LOW) {
157 delay(300);
158 if (Position == spot+1) {
159 level = gameState;
160 gameState = 98;
161 } else {
162 gameState = 99;
163 }
164 }
165 }
166
167 if (gameState == 5) {
168 period = ledSpeed[4];
169 if (millis() > time_now + period) {
170 time_now = millis();
171 if (findRandom) {
172 spot = random(56) + 3;
173 findRandom = false;
174 }
175 leds[spot].setRGB(0, 255, 0);
176 sleds[4].setRGB(0, 150, 255);
177 PlayGame(spot , spot);
178 }
179 if (digitalRead(A3) == LOW) {
180 delay(300);
181 if (Position == spot+1) {
182 level = gameState;
183 gameState = 98;
184 } else {
185 gameState = 99;
186 }
187 }
188 }
189
190 if (gameState == 98) {
191 winner();
192 }
193 if (gameState == 99) {
194 loser();
195 }
196 }
197 void PlayGame(byte bound1, byte bound2) {
198 leds[Position].setRGB(255, 0, 0); //Allume la LED à la position actuelle (Position) avec une couleur rouge
199 if (Position < bound1 + 1 || Position > bound2 + 1) { //Cette condition vérifie si la position actuelle est en dehors des limites spécifiées par bound1 et bound2.
200 //Si la position est inférieure à bound1 + 1 ou supérieure à bound2 + 1, cela signifie que la position actuelle est en dehors des limites permises
201 leds[Position - 1].setRGB(0, 0, 0);//Si la condition est vraie, alors cela signifie que la position a dépassé les limites,
202 //et la LED à la position précédente (leds[Position - 1]) est éteinte en la mettant à la couleur noire (0, 0, 0)
203 }
204 FastLED.show();
205 Position++; //Passe à la position suivante
206 if (Position >= NUM_LEDS) { //Cette condition vérifie si la position a dépassé le nombre total de LEDs (NUM_LEDS).
207 //Si c'est le cas, cela signifie que la position a atteint la fin de la séquence de LEDs.
208 leds[Position - 1].setRGB(0, 0, 0); //Si la condition est vraie, alors la LED à la dernière position est éteinte (leds[Position - 1].setRGB(0, 0, 0)) en la mettant à la couleur noire,
209 //et la position est réinitialisée à 0 pour recommencer le jeu
210 Position = 0;
211 }
212 }
213
214 void winner() { //fonction de victoire
215 win_sound(); //Final Fantasy 7 victoire
216 for (byte i = 0; i < 3; i++) {
217 for (byte j = 0; j < NUM_LEDS; j++) {
218 leds[j].setRGB(0, 255, 0); //on met toutes les LEDs en vert
219
220
221 }
222 FastLED.show();
223 delay(500);
224 clearLEDS();
225 FastLED.show();
226 delay(500);
227
228 }
229
230 findRandom = true;
231 Position = 0;
232
233 gameState = level + 1;
234 if (gameState > 5) {
235 gameState = 0;
236 }
237 }
238 void loser() { //fonction de defaite
239 lose_sound(); //imperial march lose
240 for (byte i = 0; i < 3; i++) {
241 for (byte j = 0; j < NUM_LEDS; j++) {
242 leds[j].setRGB(255, 0, 0); //on met toutes les LEDs en rouge
243 //tone(9, 200, 250);
244
245
246 }
247 FastLED.show();
248 delay(500);
249 clearLEDS();
250 FastLED.show();
251 delay(500);
252 }
253
254 gameState = 0;
255 }
256 void win_sound(){ //Final Fantasy 7 victoire
257 for (byte k = 0; k < 3; k++){
258 tone(9, 659, 250);
259 delay(400);}
260 tone(9, 659, 750);
261 delay(400);
262 tone(9, 523, 750);
263 delay(400);
264 tone(9, 587, 750);
265 delay(400);
266 tone(9, 659, 250);
267 delay(400);
268 tone(9, 587, 250);
269 delay(400);
270 tone(9, 659, 250);
271 delay(400);
272 }
273
274 void lose_sound(){ //Marche imperial defaite
275 for (byte k = 0; k < 3; k++){
276 tone(9, 440, 500);
277 delay(500);
278 }
279 tone(9, 349, 350);
280 delay(400);
281 tone(9, 523, 150);
282 delay(150);
283 tone(9, 440, 500);
284 delay(500);
285 tone(9, 349, 350);
286 delay(400);
287 tone(9, 523, 150);
288 delay(150);
289 tone(9, 440, 1000);
290 delay(1000);
291 tone(9, 659, 659);
292 delay(659);
293 tone(9, 659, 659);
294 delay(659);
295 tone(9, 659, 659);
296 delay(659);
297 tone(9, 698, 698);
298 delay(698);
299 tone(9, 523, 523);
300 delay(523);
301 tone(9, 415, 415);
302 delay(415);
303 tone(9, 349, 349);
304 delay(349);
305 tone(9, 523, 523);
306 delay(523);
307 tone(9, 440, 440);
308 delay(440);
309 }
310 void clearLEDS() {
311 for (byte i = 0; i < NUM_LEDS; i++) {
312 leds[i].setRGB(0, 0, 0); //on eteint les LEDs
313 }
314 }
étapes de fabrication
indiquer autant d'étape que nécessaire, chacune illustrée par des images (phot, dessins, ...)
Étape 1 : Electronique
Utilisez le fer à souder pour souder des fils :
- Aux 5 Leds
- Au bouton
- Au bouton
Exemple pour les Leds :
Ensuite, il faut cabler le circuit en suivant le schéma suivant :
ATENTION ! Il ne faut pas cabler la batterie comme sur le schéma, il faut faire comme si elle n'était pas la. Il faut la brancher directement à la carte avec un cable USB-B
Étape 2 : Code
- Télécharger le dossier zip FastLed au lien suivant : https://www.hackster.io/focalintent/fastled-f872e5, le dezipper
- Démarrer le logiciel Arduino
- Copier dans le logiciel le programme ci-dessus, l'enregistrer dans le dossier FastLED-master/src puis aller dans « édition » et cliquer sur « téléversement »
Étape 3 : Montage
Étape 4 : Résultat
Si tout se passe bien, sur le cercle de LEDs, il y aura une LED verte fixe qui est l’objectif, une zone jaune qui est la zone acceptable de réussite (qui se réduira selon les niveaux) et une LED rouge qui parcourt tout le cercle.
Le joueur aura à sa disposition un bouton sur lequel il devra appuyer quand il estime que la LED rouge est au même niveau que la LED verte ou dans la zone acceptable.
S’il réussit, le joueur passera au niveau supérieur et une nouvelle LED sur un bandeau représentant les niveaux s’allumera.
Enfin, s'il passe tous les niveaux, une musique de victoire se lancera et de même en cas de défaite.
Les problèmes possibles
Quelles sont difficultés, les problèmes, quelles sont les solutions, les trucs et astuces pour que ça marche ?