ENIB 2024 : D1 Pong des zinzins : Différence entre versions
(→Fichiers à joindre) |
(→Matériels) |
||
(36 révisions intermédiaires par le même utilisateur non affichées) | |||
Ligne 9 : | Ligne 9 : | ||
|} | |} | ||
− | Ici, pour la conception de ce jeu de pong, nous avons une balle qui se déplace uniquement tout droit et les raquettes ne bougent pas. | + | Ici, pour la conception de ce jeu de pong, nous avons une balle qui se déplace uniquement tout droit et les raquettes ne bougent pas comme on peut voir sur cette vidéo : |
+ | <html> | ||
+ | <iframe width="560" height="315" src="https://www.youtube.com/embed/MIXNCQ7h9m8?si=cf9_0YbpZrBuLgV1" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe> | ||
+ | </html> | ||
==Introduction== | ==Introduction== | ||
− | Nous sommes un groupe de 4 élèves en 3ème année en école d'ingénieurs.<br> | + | Nous sommes un groupe de 4 élèves en 3ème année en école d'ingénieurs à Brest. [[Fichier:Logo-enib.png|100px]]<br> |
− | Nous réalisons ce projet dans le cadre d'un hackathon qui a lieu durant l'intersemestre de notre école avec l'association des petits débrouillards. Le but de ce hackathon était donc de réaliser en 2 jours un jeu à partir de code arduino. | + | Nous réalisons ce projet dans le cadre d'un hackathon qui a lieu durant l'intersemestre de notre école avec l'association des petits débrouillards. Le but de ce hackathon était donc de réaliser en 2 jours un jeu à partir de code arduino et de le présenter à des enfants à la fin. |
{| class="wikitable" | {| class="wikitable" | ||
|- | |- | ||
Ligne 35 : | Ligne 38 : | ||
* 1 carte arduino nano | * 1 carte arduino nano | ||
* 28 LEDs | * 28 LEDs | ||
− | * | + | * câble d'alimentation USB |
+ | * câbles électroniques | ||
* plaque labdec | * plaque labdec | ||
+ | * 1 batterie externe | ||
===Maquette=== | ===Maquette=== | ||
Ligne 47 : | Ligne 52 : | ||
===Prototype=== | ===Prototype=== | ||
+ | {| class="wikitable" | ||
+ | |- | ||
+ | | [[Fichier:Prototype final 1 redimensionner.jpg|400px]] || [[Fichier:Prototype final 4 redimensionner.jpg|400px]] | ||
+ | |- | ||
+ | | ''prototype final'' ||''prototype final'' | ||
+ | |} | ||
==Fichiers à joindre== | ==Fichiers à joindre== | ||
===Code Arduino=== | ===Code Arduino=== | ||
− | Nous avons utilisé un code arduino déjà existant pour réaliser le jeu D1 Pong, présent sur la page en suivant ce lien [https://www.wikidebrouillard.org/wiki/D1-Pong#cs-comments/ code arduino] | + | Nous avons utilisé un code arduino déjà existant pour réaliser le jeu D1 Pong, présent sur la page en suivant ce lien : [https://www.wikidebrouillard.org/wiki/D1-Pong#cs-comments/ code arduino]. |
<syntaxhighlight lang="Arduino" line> /* | <syntaxhighlight lang="Arduino" line> /* | ||
Ligne 742 : | Ligne 753 : | ||
==Étapes de fabrication== | ==Étapes de fabrication== | ||
− | === | + | ===Étape 1 : découper et coller le carton=== |
Ici on utilisera un cutter, un pistolet à colle et du carton afin de réaliser la maquette. Nous avons découpé un rectangle de 60*70 pour pouvoir le plier puis le coller. | Ici on utilisera un cutter, un pistolet à colle et du carton afin de réaliser la maquette. Nous avons découpé un rectangle de 60*70 pour pouvoir le plier puis le coller. | ||
Ligne 760 : | Ligne 771 : | ||
|} | |} | ||
− | === | + | ===Étape 2 : souder les boutons=== |
+ | Dans cette étape-ci, un fer à souder et de l'étain sont nécessaire afin de souder les câbles aux boutons pour les relier au système. Pensez à établir un code couleur pour les câbles pour se retrouver plus facilement dans le câblage. | ||
{| class="wikitable" | {| class="wikitable" | ||
|- | |- | ||
Ligne 768 : | Ligne 780 : | ||
|} | |} | ||
− | === | + | ===Étape 3 : souder les LEDs=== |
− | + | Ici, les recommendations sont les mêmes que pour l'étape précédente, vous aurez besoin d'un fer à souder, d'étain, de câbles et de LEDs. | |
− | + | {| class="wikitable" | |
− | + | |- | |
− | + | | [[Fichier:Momo soude leds redimensionner.jpg|200px]] | |
+ | |- | ||
+ | | ''soudure du ruban LEDs'' | ||
+ | |} | ||
− | === | + | ===Étape 4 : câbler le matériel=== |
− | + | Á partir du schéma suivant, on peut câbler assez facilement le système. | |
+ | {| class="wikitable" | ||
+ | |- | ||
+ | | [[Fichier:Schema cablage redimensionner.jpg|300px]] || [[Fichier:Momo cable redimensionner.jpg|200px]] | ||
+ | |- | ||
+ | | ''schéma de câblage'' || ''câblage sur la carte'' | ||
+ | |} | ||
+ | |||
+ | ===Étape 5 : téléverser le code sur la carte=== | ||
+ | Dans cette étape, il n'y a qu'a copier coller le code qui se trouve plus haut sur la page ou sur la page à l'adresse suivante : [https://www.wikidebrouillard.org/wiki/D1-Pong#cs-comments/ tuto D1 pong] dans l'application arduino puis le téléverser sur la carte. Tu as donc besoin d'un câble d'alimentation USB qui relie ton ordinateur à ta carte afin de pouvoir transférer le programme. | ||
+ | |||
+ | ===Étape 6 : tester sur la maquette=== | ||
+ | Nous testons alors le programme sur la maquette réalisée plus tôt en alimentant la carte. | ||
+ | {| class="wikitable" | ||
+ | |- | ||
+ | | [[Fichier:Maquette fonctionnelle redimensionner.jpg|500px]] | ||
+ | |- | ||
+ | | ''test sur la maquette'' | ||
+ | |} | ||
+ | |||
+ | ===Étape 7 : faire et tester sur le prototype final=== | ||
+ | Pour faire le prototype final, nous avons aussi utilisé du carton mais découpé avec des dimensions différentes de celles de la maquette afin de rendre la structure plus solide, plus compacte et plus jolie. | ||
+ | {| class="wikitable" | ||
+ | |- | ||
+ | | [[Fichier:Mama cut prototype redimensionner.jpg|200px]] | ||
+ | |- | ||
+ | | ''découpage au cutter du prototype final'' | ||
+ | |} | ||
+ | |||
+ | {| class="wikitable" | ||
+ | |- | ||
+ | | [[Fichier:Dos maquette redimensionner.jpg|200px]] || [[Fichier:Face maquette redimensionner.jpg|200px]] || [[Fichier:Prototype presque final redimensionner.jpg|100px]] | ||
+ | |- | ||
+ | | ''intérieur du prototype'' || ''extérieur du prototype'' || ''prototype'' | ||
+ | |} | ||
+ | |||
+ | {| class="wikitable" | ||
+ | |- | ||
+ | | [[Fichier:Prototype final 1 redimensionner.jpg|400px]] || [[Fichier:Prototype final 4 redimensionner.jpg|400px]] | ||
+ | |- | ||
+ | | ''prototype final'' || ''prototype final'' | ||
+ | |} | ||
+ | |||
+ | ===Troubleshouting=== | ||
+ | Nous avons rencontrer un problème majeur lors de la réalisation de ce projet : le code n'était pas compatible avec la carte. Pour le résoudre, nous avons décidé plutôt que de modifier le programme, de prendre la carte qui était compatible avec le code puisque nous l'avions à disposition. | ||
+ | Avant de nous rendre compte de cela, nous nous demandions si ce n'était pas le câble d'alimentation USB qui ne fonctionnait pas. En effet, la carte n'était pas détectée lorsque nous la connections à l'ordinateur. En changeant de câble, nous avons compris que celui que nous utilisions à la base n'était plus fonctionnel. | ||
+ | |||
+ | Pour résumer sur les problèmes rencontrés, nous avons eu un souci de compatibilité et un problème de casse. Pour éviter cela, n’hésitez pas à tester le matériel avant et de vérifier la compatibilité du code avec la carte. | ||
==Sources et documentation complémentaire== | ==Sources et documentation complémentaire== | ||
Ligne 781 : | Ligne 843 : | ||
|- | |- | ||
| tuto suivi || https://www.wikidebrouillard.org/wiki/D1-Pong#cs-comments | | tuto suivi || https://www.wikidebrouillard.org/wiki/D1-Pong#cs-comments | ||
− | |||
− | |||
− | |||
− | |||
|} | |} | ||
==ne pas modifier sous cette ligne== | ==ne pas modifier sous cette ligne== | ||
[[Catégorie:Enib2024]] | [[Catégorie:Enib2024]] |
Version actuelle datée du 25 janvier 2024 à 16:11
Titre de la fiche expérience :
Sommaire
Description
Le jeu du D1 Pong nécessite 2 joueurs qui s'affrontent. Le but est que la balle dépasse la raquette de son adversaire.
![]() |
jeu du pong |
Ici, pour la conception de ce jeu de pong, nous avons une balle qui se déplace uniquement tout droit et les raquettes ne bougent pas comme on peut voir sur cette vidéo :
Introduction
Nous sommes un groupe de 4 élèves en 3ème année en école d'ingénieurs à Brest.
Nous réalisons ce projet dans le cadre d'un hackathon qui a lieu durant l'intersemestre de notre école avec l'association des petits débrouillards. Le but de ce hackathon était donc de réaliser en 2 jours un jeu à partir de code arduino et de le présenter à des enfants à la fin.
![]() |
photo du groupe |
Outils et matériels
Outils
- cutter
- fer à souder
- pistolet à colle
- ordinateur
- logiciel arduino
Matériels
- carton
- 2 boutons poussoirs
- 1 carte arduino nano
- 28 LEDs
- câble d'alimentation USB
- câbles électroniques
- plaque labdec
- 1 batterie externe
Maquette
![]() |
![]() |
maquette en carton | maquette en carton fonctionnelle |
Prototype
![]() |
![]() |
prototype final | prototype final |
Fichiers à joindre
Code Arduino
Nous avons utilisé un code arduino déjà existant pour réaliser le jeu D1 Pong, présent sur la page en suivant ce lien : code arduino.
1 /*
2 Code de fonctionnement pour le jeu PONG.
3 Par les petits debrouillards.
4 */
5
6 #include <FastLED.h>
7
8 // Definition des couleurs
9 const CRGB NOIR = CRGB(0, 0, 0 );
10 const CRGB BLANC = CRGB(255, 255, 255);
11 const CRGB ROUGE = CRGB(255, 0, 0 );
12 const CRGB VERT = CRGB(0, 255, 0 );
13 const CRGB BLEU = CRGB(0, 0, 255);
14 const CRGB JAUNE = CRGB(255, 255, 0 );
15 const CRGB ROSE = CRGB(255, 0, 255);
16 const CRGB CYAN = CRGB(0, 255, 255);
17
18 // Definition des notes de musique
19 const int PONG_SOUND = 250; //380
20 const int LOOSE_SOUND = 180;
21
22
23 /******************************
24 PARAMETRES DE BRANCHEMENTS
25 ******************************/
26
27 const int LED_PIN = 8; // Numero de branchement de la bande de LEDs
28 const int BUTTON1_PIN = 2; // Numero de branchement du premier bouton
29 const int BUTTON2_PIN = 4; // Numero de branchement du deuxieme bouton
30 const int HAUT_PARLEUR_PIN = 6; // Numero de branchement du haut parleur (optionnel)
31
32
33 /***********************
34 PARAMETRES GENERAUX
35 ***********************/
36 const int NUM_LEDS = 28; // Nombre de LEDs sur la bande
37 const CRGB PLAYER1_COLOR = VERT; // Couleur player 1
38 const CRGB PLAYER2_COLOR = ROUGE; // Couleur player 2
39
40
41 /***********************
42 PARAMETRES PONG
43 ***********************/
44 const float BALL_SPEED = 0.5; // Vitesse de la balle
45 const float ACCELERATION = 9; // Accelleration de la balle a chaque tir, si ACCELERATION = 10 on augmente la vitesse de 10 pourcent a chaque tir
46 const int HIT_ZONE = 8; // Nombre de LED pendant lesquelles on peut renvoyer la balle
47 const int MAX_SCORE = 3;
48
49 const CRGB BALL_COLOR = BLANC; // Couleur de la balle
50
51 /*******************************
52 PARAMETRES TIR A LA CORDE
53 *******************************/
54 const float INCREMENT = 0.05; // De combien avance la corde lorsqu'on appuie sur le bouton
55 const float ROPE_SMOOTH = 1.0; // Parametre servant a lisser la position de la corde
56
57 const float WAVE_LENGTH = 0.2; // Taille des ondes
58 const float WAVE_SPEED = 1.0; // Vitesse des ondes
59
60
61
62 /******************************
63 VARIABLES GENERALES
64 ******************************/
65 // Players
66 enum Player
67 {
68 PERSONNE,
69 PLAYER1,
70 PLAYER2
71 };
72
73 // Etats du jeu
74 enum GameState
75 {
76 START,
77 PONG, // Mode pong
78 TAC // Mode tir a la corde
79 };
80
81 unsigned long lastMillis = 0;
82 unsigned long beginTimer = 0;
83 unsigned int counter = 0;
84
85 Player player = PLAYER1; // Prochain joueur a appuyer sur son bouton
86 Player lastWinner = PERSONNE;
87
88 CRGB leds[NUM_LEDS];
89 GameState gameState = START;
90
91
92 /**********************************************
93 FONCTIONS DE FONCTIONNEMENT GENERALES
94 **********************************************/
95
96 // Fonction permettant de changer la couleur d'une LED relativement au player 1 ou 2
97 void ledColor(Player player, int pos, CRGB color)
98 {
99 if (player == PLAYER1)
100 {
101 leds[pos] = color;
102 }
103 else // player == PLAYER2
104 {
105 leds[NUM_LEDS - pos - 1] = color;
106 }
107 }
108
109 // Fonction permettant de changer la couleur d'une LED
110 void ledColor(int pos, CRGB color)
111 {
112 leds[pos] = color;
113 }
114
115 /*********************************************
116 VARIABLES DE FONCTIONNEMENT DU PONG
117 *********************************************/
118 float ballSpeed = BALL_SPEED; // Vitesse de la balle
119 float ballPosition = 1; // Position de la balle sur la bande de led (Si ballPosition = 0, la balle est devant le player 1. Si ballPosition = 1, la balle est devant le player 2)
120 int player1Score = 0; // Score du player 1
121 int player2Score = 0; // Score du player 2
122
123 /**********************************************
124 FONCTIONS DE FONCTIONNEMENT DU PONG
125 **********************************************/
126 // Fonction servant a afficher les scores
127 void showScore()
128 {
129 // On commence par effacer toutes les couleurs de led
130 FastLED.clear();
131
132 // On allume le nombre de led correspondant au score du player 1
133 for (int i = 0; i < player1Score; i++)
134 {
135 ledColor(PLAYER1, NUM_LEDS / 2 - (i + 1), PLAYER1_COLOR);
136 }
137
138 // On allume le nombre de led correspondant au score du player 2
139 for (int i = 0; i < player2Score; i++)
140 {
141 ledColor(PLAYER2, NUM_LEDS / 2 - (i + 1), PLAYER2_COLOR);
142 }
143
144 // On envoie les nouvelles couleurs a la bande de led
145 FastLED.show();
146
147 // On fait clignotter trois fois
148 if (lastWinner == PLAYER1)
149 {
150 for (int i = 0; i < 3; i++)
151 {
152 // On eteint la derniere LED pendant 0.5s
153 delay(500);
154 ledColor(PLAYER1, NUM_LEDS / 2 - player1Score, NOIR);
155 FastLED.show();
156
157 // On allume la derniere LED pendant 0.5s
158 delay(500);
159 ledColor(PLAYER1, NUM_LEDS / 2 - player1Score, PLAYER1_COLOR);
160 FastLED.show();
161 }
162 }
163 else // lastWinner == PLAYER2
164 {
165 for (int i = 0; i < 3; i++)
166 {
167 // On eteint la derniere LED pendant 0.5s
168 delay(500);
169 ledColor(PLAYER2, NUM_LEDS / 2 - player2Score, NOIR);
170 FastLED.show();
171
172 // On allume la derniere LED pendant 0.5s
173 delay(500);
174 ledColor(PLAYER2, NUM_LEDS / 2 - player2Score, PLAYER2_COLOR);
175 FastLED.show();
176 }
177 }
178
179 // Si la partie est terminee on va a l'affichage de fin
180 if (player1Score == MAX_SCORE || player2Score == MAX_SCORE)
181 {
182 gameState = START;
183
184 // On reinitialise les scores
185 player1Score = 0;
186 player2Score = 0;
187
188 // On reinitialise la vitesse
189 ballSpeed = BALL_SPEED;
190
191 // On reinitialise les leds
192 FastLED.clear();
193 }
194 // Sinon on reprend le jeu
195 else
196 {
197 gameState = PONG;
198 ballSpeed = BALL_SPEED;
199 }
200 }
201
202
203 /***************************************
204 FONCTION PRINCIPALE DU PONG
205 ***************************************/
206 void pong_loop()
207 {
208 // Calcul du temps ecoule entre deux boucles
209 unsigned long currentMillis = millis();
210
211 // On calcule le numero de la LED allumee
212 int ballLed = ballPosition * NUM_LEDS;
213
214 // On s'assure que la position de la balle ne depasse pas la taille de la bande de LED
215 ballLed = min(ballLed, NUM_LEDS - 1);
216
217 // On regarde qui est en train de jouer
218 if (player == PLAYER1)
219 {
220 // On regarde si le player a appuye sur son bouton et si le delai de debut de jeu est passe
221 if (digitalRead(BUTTON1_PIN) == LOW && currentMillis - beginTimer > 500)
222 {
223 // Si la balle est hors de la zone de tir, l'autre player marque un point
224 if (ballLed >= HIT_ZONE)
225 {
226 player2Score += 1;
227 lastWinner = PLAYER2;
228 ballPosition = 0;
229
230 // On joue le son de defaite
231 tone(HAUT_PARLEUR_PIN, LOOSE_SOUND, 800);
232
233 // On passe en mode affichage des scores
234 showScore();
235
236 // C'est a l'autre player de jouer
237 player = PLAYER2;
238
239 // Actualisation de la variable lastMillis
240 lastMillis = millis();
241 }
242 else
243 {
244 // On accelere la balle
245 ballSpeed *= 1.0 + ACCELERATION / 100;
246
247 // C'est a l'autre player de jouer
248 player = PLAYER2;
249
250 // On joue la note de musique
251 tone(HAUT_PARLEUR_PIN, PONG_SOUND, 100);
252 }
253
254 return;
255 }
256
257 // On fait avancer la balle
258 ballPosition -= ballSpeed * (currentMillis - lastMillis) * 0.001f;
259
260 // On regarde si la balle est sortie de la zone
261 if (ballPosition < 0.0f)
262 {
263 // Si oui le player 2 marque un point
264 player2Score += 1;
265 lastWinner = PLAYER2;
266 ballPosition = 0;
267
268 // On joue le son de defaite
269 tone(HAUT_PARLEUR_PIN, LOOSE_SOUND, 800);
270
271 // On passe en mode affichage des scores
272 showScore();
273
274 // C'est a l'autre player de jouer
275 player = PLAYER2;
276
277 // Actualisation de la variable lastMillis
278 lastMillis = millis();
279 return;
280 }
281 }
282 else // player == PLAYER2
283 {
284 // On regarde si le player a appuye sur son bouton et si le delai de debut de jeu est passe
285 if (digitalRead(BUTTON2_PIN) == LOW && currentMillis - beginTimer > 500)
286 {
287 // Si la balle est hors de la zone de tir, l'autre player marque un point
288 if (ballLed < NUM_LEDS - HIT_ZONE)
289 {
290 player1Score += 1;
291 lastWinner = PLAYER1;
292 ballPosition = 1;
293
294 // On joue le son de defaite
295 tone(HAUT_PARLEUR_PIN, LOOSE_SOUND, 800);
296
297 // On passe en mode affichage des scores
298 showScore();
299
300 // C'est a l'autre player de jouer
301 player = PLAYER1;
302
303 // Actualisation de la variable lastMillis
304 lastMillis = millis();
305 }
306 else
307 {
308 // On accelere la balle
309 ballSpeed *= 1.1;
310
311 // C'est a l'autre player de jouer
312 player = PLAYER1;
313
314 // On joue la note de musique
315 tone(HAUT_PARLEUR_PIN, PONG_SOUND, 100);
316 }
317
318 return;
319 }
320
321 // On fait avancer la balle dans l'autre sens
322 ballPosition += ballSpeed * (currentMillis - lastMillis) * 0.001f;
323
324 // On regarde si la balle est sortie de la zone
325 if (ballPosition >= 1)
326 {
327 // Si oui le player 1 marque un point
328 player1Score += 1;
329 lastWinner = PLAYER1;
330 ballPosition = 1;
331
332 // On joue le son de defaite
333 tone(HAUT_PARLEUR_PIN, LOOSE_SOUND, 800);
334
335 // On passe en mode affichage des scores
336 showScore();
337 // C'est a l'autre player de jouer
338 player = PLAYER1;
339
340 // Actualisation de la variable lastMillis
341 lastMillis = millis();
342 return;
343 }
344 }
345
346 ///// AFFICHAGE BANDE DE LEDs /////
347 // Premierement on efface toutes les couleurs precedentes
348 FastLED.clear();
349
350 // Ensuite on allume faiblement les LEDs correspondant a la zone de chaque cote
351 for (int i = 0; i < HIT_ZONE; i++)
352 {
353 // On allume de chaque cote
354 ledColor(PLAYER1, i, PLAYER1_COLOR / 10); // On divise la couleur par 10 pour la rendre 10 fois moins puissante
355 ledColor(PLAYER2, i, PLAYER2_COLOR / 10);
356 }
357
358 // Ensuite on allume faiblement les LEDs correspondant aux scores
359 // Pour le player 1
360 for (int i = 0; i < player1Score; i++)
361 {
362 ledColor(PLAYER1, NUM_LEDS / 2 - (i + 1), PLAYER1_COLOR / 15);
363 }
364 // Pour le player 2
365 for (int i = 0; i < player2Score; i++)
366 {
367 ledColor(PLAYER2, NUM_LEDS / 2 - (i + 1), PLAYER2_COLOR / 15);
368 }
369
370 // Ensuite on actualise la position de la balle
371 // On donne la couleur de la led en fonction de si la balle est dans la zone d'un player ou non
372
373 // Si la balle est dans le camp d'un des player, elle est rouge.
374 if (ballLed < HIT_ZONE || ballLed >= NUM_LEDS - HIT_ZONE)
375 {
376 ledColor(ballLed, ROUGE);
377 }
378 // Si elle en est proche, elle est jaune
379 else if (ballLed < 2 * HIT_ZONE || ballLed >= NUM_LEDS - 2 * HIT_ZONE)
380 {
381 ledColor(ballLed, JAUNE);
382 }
383 // Sinon la balle a sa couleur par defaut
384 else
385 {
386 ledColor(ballLed, BALL_COLOR);
387 }
388
389 // On envoie la couleur des leds a la bande de leds
390 FastLED.show();
391
392 // On actualise la variable lastMillis pour la boucle suivante
393 lastMillis = currentMillis;
394 }
395
396
397
398 /*******************************************************
399 VARIABLES DE FONCTIONNEMENT DU TIR A LA CORDE
400 *******************************************************/
401 float ropePosition = 0.5; // Position non lissee de la corde
402 float displayedRopePosition = 0.5; // Position lissee de la corde
403 bool player1Pushed = false;
404 bool player2Pushed = false;
405
406 float player1Waves[10] = { 0 };
407 float player2Waves[10] = { 0 };
408
409 /***********************************************
410 FONCTION PRINCIPALE DU TIR A LA CORDE
411 ***********************************************/
412 void tac_loop()
413 {
414 // Calcul des temps
415 unsigned long ms = millis();
416 float dt = (ms - lastMillis) * 0.001f;
417 lastMillis = ms;
418
419 // Si moins d'une seconde s'est ecoule depuis le debut, on ne fait rien (pour eviter d'appuyer sans faire expres)
420 if (ms - beginTimer < 1000)
421 return;
422
423 bool player1Push = !digitalRead(BUTTON1_PIN);
424 bool player2Push = !digitalRead(BUTTON2_PIN);
425
426 if (player1Push && !player1Pushed)
427 {
428 // On incremente la position de la corde
429 ropePosition += INCREMENT;
430
431 // On lance une nouvelle onde
432 for (int i = 0; i < 10; i++)
433 {
434 if (player1Waves[i] == 0.0f)
435 {
436 //player1Waves[i] = WAVE_SPEED * dt;
437 player1Waves[i] = 0.01f;
438 break;
439 }
440 }
441 }
442 if (player2Push && !player2Pushed)
443 {
444 // On incremente la position de la corde
445 ropePosition -= INCREMENT;
446
447 // On lance une nouvelle onde
448 for (int i = 0; i < 10; i++)
449 {
450 if (player2Waves[i] == 0.0f)
451 {
452 player2Waves[i] = 0.99f;
453 break;
454 }
455 }
456 }
457
458 // Memorisation des etats des boutons
459 player1Pushed = player1Push;
460 player2Pushed = player2Push;
461
462
463
464
465 // On calcule la position lissee de la corde (displayedRopePosition correspond a la variable ropePosition avec un lissage supplementaire)
466 displayedRopePosition += (ropePosition - displayedRopePosition) * dt / ROPE_SMOOTH;
467
468 // On regarde si player 1 a gagne
469 if (displayedRopePosition >= 1.0f)
470 {
471 lastWinner = PLAYER1;
472 gameState = START;
473 beginTimer = millis();
474
475 ropePosition = 0.5f;
476 displayedRopePosition = 0.5f;
477
478 FastLED.clear();
479 return;
480 }
481 // On regarde si player 2 a gagne
482 else if (displayedRopePosition <= 0.0f)
483 {
484 lastWinner = PLAYER2;
485 gameState = START;
486 beginTimer = millis();
487
488 ropePosition = 0.5f;
489 displayedRopePosition = 0.5f;
490
491 FastLED.clear();
492 return;
493 }
494
495 // On propage les ondes
496 float dx = WAVE_SPEED * dt;
497
498 for (int wave = 0; wave < 10; wave++)
499 {
500 // Ondes player 1
501 if (player1Waves[wave] != 0.0f)
502 {
503 player1Waves[wave] += dx;
504
505 // Si toute l'onde depasse le point de la corde, on l'arrete
506 if (player1Waves[wave] - WAVE_LENGTH > displayedRopePosition)
507 {
508 player1Waves[wave] = 0.0f;
509 }
510 }
511
512 // Ondes player 2
513 if (player2Waves[wave] != 0.0f)
514 {
515 player2Waves[wave] -= dx;
516
517 // Si toute l'onde depasse le point de la corde, on l'arrete
518 if (player2Waves[wave] + WAVE_LENGTH < displayedRopePosition)
519 {
520 player2Waves[wave] = 0.0f;
521 }
522 }
523 }
524
525 // On actualise la bande de leds
526 float ledLuminosity;
527 float ledPosition;
528
529 FastLED.clear();
530
531 // On commence par calculer le numero de la led correspondant a la position de la corde
532 int ropeLedPosition = NUM_LEDS * displayedRopePosition;
533
534 // On dessine la zone du player 1
535 // Pour cela on calcule la luminosite led par led
536 for (int led = 0; led < ropeLedPosition; led++)
537 {
538 // La luminosite minimale d'une led est 10% de la luminosite max
539 ledLuminosity = 0.1f;
540 ledPosition = float(led) / float(NUM_LEDS);
541
542 // Pour chaque onde, on ajoute la luminosite a la led
543 for (int wave = 0; wave < 10; wave++)
544 {
545 // Si l'onde n'est pas active ou si l'onde est avant la led, on n'ajoute aucune luminosite
546 if (player1Waves[wave] == 0.0f || player1Waves[wave] < ledPosition)
547 continue;
548
549 // On ajoute de la luminosite de facon decroissante. plus l'onde est loin, moins on ajoute de luminosite.
550 ledLuminosity += max(0.0f, 0.9f - (player1Waves[wave] - ledPosition) / WAVE_LENGTH);
551 }
552 // La valeur maximale de luminosite est 1.0
553 if (ledLuminosity > 2.0f)
554 ledLuminosity = 2.0f;
555
556 // On actualise la valeur de luminosite de la led
557 ledColor(led, PLAYER1_COLOR / int(2.0f / ledLuminosity) / 5);
558 }
559
560 // On dessine la zone du player 2
561 for (int led = ropeLedPosition + 1; led < NUM_LEDS; led++)
562 {
563 // La luminosite minimale d'une led est 10% de la luminosite max
564 ledLuminosity = 0.1f;
565 ledPosition = float(led) / float(NUM_LEDS);
566
567 // Pour chaque onde, on ajoute la luminosite a la led
568 for (int wave = 0; wave < 10; wave++)
569 {
570 // Si l'onde n'est pas active ou si l'onde est avant la led, on n'ajoute aucune luminosite
571 if (player2Waves[wave] == 0.0f || ledPosition > player2Waves[wave])
572 continue;
573
574 // On ajoute de la luminosite de facon decroissante. plus l'onde est loin, moins on ajoute de luminosite.
575 ledLuminosity += max(0.0f, 0.9f - (player2Waves[wave] - ledPosition) / WAVE_LENGTH);
576 }
577 // La valeur maximale de luminosite est 1.0
578 if (ledLuminosity > 2.0f)
579 ledLuminosity = 2.0f;
580
581 // On actualise la valeur de luminosite de la led
582 ledColor(led, PLAYER2_COLOR / int(1.0f / ledLuminosity) / 5);
583 }
584
585 // On actualise la led correspondant a la position de la corde
586 ledColor(ropeLedPosition, BLANC);
587 FastLED.show();
588 }
589
590
591
592 /****************************************************************
593 Cette fonction s'execute une fois lorsque la carte s'allume.
594 ****************************************************************/
595 void setup() {
596 // Initialisation des LEDs
597 FastLED.addLeds<WS2812B, LED_PIN, GRB>(leds, NUM_LEDS);
598
599 // Initialisations des boutons
600 pinMode(BUTTON1_PIN, INPUT_PULLUP);
601 pinMode(BUTTON2_PIN, INPUT_PULLUP);
602
603 // Initialisation du haut parleur
604 pinMode(HAUT_PARLEUR_PIN, OUTPUT);
605
606 // COULEUR DES LEDS EN DEBUT DE PARTIE
607 FastLED.clear();
608 // Couleurs player 1
609 ledColor(PLAYER1, 0, PLAYER1_COLOR);
610 ledColor(PLAYER1, 1, PLAYER1_COLOR);
611 ledColor(PLAYER1, 2, PLAYER1_COLOR);
612 ledColor(PLAYER1, 3, PLAYER1_COLOR);
613 ledColor(PLAYER1, 4, PLAYER1_COLOR);
614
615 // Couleurs player 2
616 ledColor(PLAYER2, 0, PLAYER2_COLOR);
617 ledColor(PLAYER2, 1, PLAYER2_COLOR);
618 ledColor(PLAYER2, 2, PLAYER2_COLOR);
619 ledColor(PLAYER2, 3, PLAYER2_COLOR);
620 ledColor(PLAYER2, 4, PLAYER2_COLOR);
621
622 // On envoie les changements a la bande de leds
623 FastLED.show();
624
625 // Initialisation du temps d'allumage
626 beginTimer = millis();
627 }
628
629 /*************************************************************
630 Cette fonction s'execute en continue tout au long du jeu.
631 *************************************************************/
632 void loop() {
633
634 switch (gameState)
635 {
636 case START:
637 // Si un player a gagne, on affiche l'arc en ciel du cote du vainqueur
638 if (lastWinner == PLAYER1)
639 {
640 fill_rainbow(leds, NUM_LEDS / 2, counter++, 7);
641 FastLED.show();
642 }
643 else if (lastWinner == PLAYER2)
644 {
645 fill_rainbow(leds + NUM_LEDS / 2, NUM_LEDS / 2, counter++, 7);
646 FastLED.show();
647 }
648
649 // On regarde si un temps minimim s'est ecoule et si un des boutons est appuye
650 if (millis() - beginTimer > 1000 && (digitalRead(BUTTON1_PIN) == LOW || digitalRead(BUTTON2_PIN) == LOW))
651 {
652 unsigned long pushBegin = millis();
653
654 while (digitalRead(BUTTON1_PIN) == LOW || digitalRead(BUTTON2_PIN) == LOW);
655
656 if (millis() - pushBegin < 1000)
657 {
658 gameState = PONG;
659 }
660 else
661 {
662 gameState = TAC;
663 }
664
665 // On joue la note de musique
666 tone(HAUT_PARLEUR_PIN, PONG_SOUND, 100);
667
668 // Initialisation de la varable lastMillis
669 lastMillis = millis();
670
671 // Initialisation du temps de debut de jeu
672 beginTimer = millis();
673 }
674
675 break;
676
677 case PONG:
678 pong_loop();
679 break;
680
681 case TAC:
682 tac_loop();
683 break;
684 }
685 }
Étapes de fabrication
Étape 1 : découper et coller le carton
Ici on utilisera un cutter, un pistolet à colle et du carton afin de réaliser la maquette. Nous avons découpé un rectangle de 60*70 pour pouvoir le plier puis le coller.
Pour découpé le carton, nous avons établi au préalable un plan avec des dimensions :
![]() |
schéma avec dimensions |
![]() |
![]() |
découpage au cutter dans le carton pour faire le trou pour les boutons poussoirs | maquette finale |
Étape 2 : souder les boutons
Dans cette étape-ci, un fer à souder et de l'étain sont nécessaire afin de souder les câbles aux boutons pour les relier au système. Pensez à établir un code couleur pour les câbles pour se retrouver plus facilement dans le câblage.
![]() |
soudure des câbles sur les boutons |
Étape 3 : souder les LEDs
Ici, les recommendations sont les mêmes que pour l'étape précédente, vous aurez besoin d'un fer à souder, d'étain, de câbles et de LEDs.
![]() |
soudure du ruban LEDs |
Étape 4 : câbler le matériel
Á partir du schéma suivant, on peut câbler assez facilement le système.
![]() |
![]() |
schéma de câblage | câblage sur la carte |
Étape 5 : téléverser le code sur la carte
Dans cette étape, il n'y a qu'a copier coller le code qui se trouve plus haut sur la page ou sur la page à l'adresse suivante : tuto D1 pong dans l'application arduino puis le téléverser sur la carte. Tu as donc besoin d'un câble d'alimentation USB qui relie ton ordinateur à ta carte afin de pouvoir transférer le programme.
Étape 6 : tester sur la maquette
Nous testons alors le programme sur la maquette réalisée plus tôt en alimentant la carte.
![]() |
test sur la maquette |
Étape 7 : faire et tester sur le prototype final
Pour faire le prototype final, nous avons aussi utilisé du carton mais découpé avec des dimensions différentes de celles de la maquette afin de rendre la structure plus solide, plus compacte et plus jolie.
![]() |
découpage au cutter du prototype final |
![]() |
![]() |
![]() |
intérieur du prototype | extérieur du prototype | prototype |
![]() |
![]() |
prototype final | prototype final |
Troubleshouting
Nous avons rencontrer un problème majeur lors de la réalisation de ce projet : le code n'était pas compatible avec la carte. Pour le résoudre, nous avons décidé plutôt que de modifier le programme, de prendre la carte qui était compatible avec le code puisque nous l'avions à disposition. Avant de nous rendre compte de cela, nous nous demandions si ce n'était pas le câble d'alimentation USB qui ne fonctionnait pas. En effet, la carte n'était pas détectée lorsque nous la connections à l'ordinateur. En changeant de câble, nous avons compris que celui que nous utilisions à la base n'était plus fonctionnel.
Pour résumer sur les problèmes rencontrés, nous avons eu un souci de compatibilité et un problème de casse. Pour éviter cela, n’hésitez pas à tester le matériel avant et de vérifier la compatibilité du code avec la carte.
Sources et documentation complémentaire
tuto suivi | https://www.wikidebrouillard.org/wiki/D1-Pong#cs-comments |