Piano Tiles est un projet interactif qui combine musique, électronique et éléments de jeu. L’objectif est de créer une expérience inspirée des jeux de rythme, dans laquelle l’utilisateur choisit une musique et doit appuyer sur les bonnes touches au bon moment.
Contenus de la Page
Objectifs
- Créer un jeu musical interactif inspiré de jeux de rythme;
- Permettre à l’utilisateur de sélectionner une musique et de jouer en suivant les notes;
- Utiliser des touches capacitives comme interface utilisateur;
- Afficher les informations du jeu sur une matrice de LEDs;
- Générer un retour sonore à l’aide d’un haut-parleur;
- Concevoir une structure physique adaptée à l’intégration des composants électroniques.
Liste des Matériaux
Composants électroniques:
- Résistance – 100Ω;
- Condensateurs – 100µF et 4700µF;
- ESP 32 – Microcontrôleur principal du système;
- MPR121 – Capteur capacitif utilisé pour détecter les touches;
- Matrice LED 32 × 8 – Affichage du menu, des notes, du score et des animations;
- Haut-parleur / speaker– Reproduction des sons et des mélodies;
- LM386 – Amplificateur audio;
- Breadboard – Réalisation des premiers tests du circuit;
- PCB board – Réalisation du circuit final soudé;
- Alimentation externe 5V – Alimentation du système;
- Fils de connexion – Connexions entre les différents composants.
Composants mécaniques:
- Scotch de cuivre – Réalisation des touches capacitives;
- 2 charnières papillon — Ouverture de la boîte;
- MDF 3 mm – Structure du piano;
- PMMA 3 mm – Écran placé devant la grille de diffusion pour améliorer l’esthétique et la diffusion de la lumière.
Le tableau suivant présente une estimation du coût des principaux composants utilisés dans le projet. Les prix indiqués sont approximatifs et peuvent varier selon le fournisseur.
| Composant | Quantité | Prix unitaire estimé |
| Résistance | 1 | ~ 0,40 € |
| Condensateur | 2 | ~ 5,00 € |
| ESP32 dev kit | 1 | ~ 8,00 € |
| MPR121 | 1 | ~ 5,00 € |
| Matrice LED 32 × 8 | 1 | ~ 15,00 € |
| LM386 | 1 | ~ 2,00 € |
| Haut-parleur | 1 | ~ 1,50 € |
| Breadboard | 1 | ~ 3,00 € |
| PCB Board | 1 | ~ 0,80 € |
| Scotch de cuivre | 1 | ~ 7,00 € |
| Charnières papillon | 2 | ~ 9,00 € |
| MDF 3 mm (332×120 mm) | 2 | ~ 7,00 € |
| PMMA 3 mm (350×350 mm) | 1 | ~ 9,60 € |
Technologies de Fabrication
- Découpe laser – utilisée pour découper la structure du piano en MDF ainsi que l’écran en PMMA;
- Impression 3D – utilisée pour fabriquer une grille de diffusion de la lumière de la matrice LED;
- Soudure électronique – utilisée pour réaliser les connexions électriques définitives;
- Assemblage manuel – utilisé pour intégrer les composants électroniques dans la structure finale.
Conception Electronique
Le circuit électronique du projet est organisé autour de l’ESP32, qui joue le rôle d’unité centrale de contrôle. Il communique avec le capteur capacitif MPR121 via le protocole I2C, contrôle la matrice de LEDs 32×8 et génère le signal sonore envoyé vers le haut-parleur à travers de l’amplificateur LM386.

La matrice LED est alimentée en 5 V et reliée au GND. Un condensateur est placé entre l’alimentation et la masse afin de stabiliser la tension et de protéger la matrice contre les variations brusques de courant.
Le capteur MPR121 est utilisé pour détecter les touches du clavier capacitif. Lorsqu’une touche en scotch de cuivre est touchée, une variation de capacité est détectée par le capteur, puis l’information est envoyée à l’ESP32.
La partie audio est composée d’un amplificateur LM386 connecté au haut-parleur. Le signal sonore généré par l’ESP32 est envoyé à l’entrée de l’amplificateur, puis amplifié avant d’être reproduit par le haut-parleur. Un condensateur est également utilisé dans cette partie du circuit afin de stabiliser le signal d’alimentation.

Connexion du capteur MPR121
Le capteur MPR121 est utilisé pour détecter les touches capacitives du piano. Il est alimenté par l’ESP32, avec la broche 3,3 V et la broche GND. La communication entre le MPR121 et l’ESP32 se fait par le bus I2C, avec la broche SDA connectée au pin 21 et la broche SCL connectée au pin 22.
Les entrées du MPR121 sont reliées, à l’aide de fils de connexion, aux touches capacitives réalisées avec du scotch de cuivre. Lorsqu’un utilisateur touche une de ces zones conductrices, le capteur détecte la variation de capacité et envoie l’information à l’ESP32.

Connexion du système audio
Le signal sonore est généré par l’ESP32 à partir du pin 18. Ce signal est ensuite envoyé vers l’entrée VIN de l’amplificateur LM386. Le module LM386 est alimenté par les broches VCC et GND.
En sortie, la broche OUT+ du LM386 est connectée à la borne positive du haut-parleur, tandis que la borne négative du haut-parleur est reliée au GND. L’amplificateur permet ainsi d’augmenter le volume du signal avant sa reproduction par le haut-parleur.

Modélisation 3D
La modélisation 3D du projet a été entièrement réalisée sur Onshape. La conception du piano repose sur une structure en deux parties, avec une ouverture similaire à celle d’un livre. Cette solution permet de faciliter l’accès aux composants électroniques tout en séparant clairement la partie d’affichage et la partie d’interaction avec l’utilisateur.
La structure est donc composée d’une partie inférieure, destinée aux touches capacitives et aux composants électroniques, et d’une partie supérieure, destinée à l’affichage avec la matrice LED, la grille de diffusion imprimée en 3D et l’écran.
Partie supérieure du piano
La partie supérieure du piano, de dimensions 332 × 120 mm, est destinée à accueillir le système d’affichage. Comme cette pièce est fabriquée par découpe laser, elle a été conçue avec une épaisseur de 3 mm, adaptée au MDF utilisé. Les faces de la boîte comportent également des emboîtements permettant l’assemblage des différentes pièces.
Un trou a été prévu sur l’une des faces latérales afin de permettre le passage des câbles de la matrice LED.
À l’intérieur, plusieurs cloisons servent de support pour positionner la matrice LED, qui vient se placer au-dessus de ces séparations afin d’être correctement maintenue.


Un espace est également prévu pour la grille de diffusion imprimée en 3D. Sur les deux grandes faces latérales, des rainures permettent de maintenir l’écran en PMMA devant la grille, afin d’améliorer la diffusion de la lumière et l’aspect visuel du piano.
Deux supports ont également été conçus pour maintenir la partie supérieure ouverte, de manière similaire à un ordinateur portable. Ils se placent à l’arrière de la boîte et évitent une ouverture complète à 180°, ce qui rend l’utilisation du jeu plus confortable. Leur taille réduite permet de les ranger facilement à l’intérieur de la boîte.

Partie inférieure du piano
La partie inférieure du piano possède également des dimensions de 332 × 120 mm et a été conçue avec une épaisseur de 3 mm, adaptée au MDF utilisé pour la découpe laser. Elle constitue la base de la structure et accueille la partie électronique du projet.
À l’arrière, une ouverture rectangulaire a été prévue pour permettre la sortie du son du haut-parleur.
Des trous similaires à ceux de la partie supérieure permettent également le passage des fils nécessaires à la connexion de la matrice LED.


Sur l’une des faces latérales, un trou permet le passage du connecteur d’alimentation externe. Un support est aussi prévu pour le clavier capacitif, avec une fente permettant de faire passer les fils vers l’intérieur de la boîte. L’intérieur est laissé vide afin d’accueillir les composants électroniques.
Conception Mécanique
La conception mécanique du projet a été réalisée à partir des modèles 3D créés sur Onshape.
Les différentes plaques constituant la structure ont été séparées et organisées dans un même plan, afin de préparer les pièces pour la découpe laser.


Ensuite, ces pièces ont été placées dans un drawing, ce qui permet d’obtenir les contours 2D nécessaires à la fabrication. Le fichier est ensuite exporté au format .SVG.
Le fichier SVG est ouvert dans Inkscape, où les contours sont préparés pour la découpe.
Enfin, le fichier est exporté vers le logiciel de la machine de découpe laser. Dans ce logiciel, il faut sélectionner le matériau utilisé, par exemple le MDF ou le PMMA, ainsi que son épaisseur.
Après le réglage et la calibration de la machine, les pièces peuvent être découpées puis assemblées pour former la structure finale du piano.

Fonctionnement du Jeu
Au démarrage, le jeu affiche une animation d’accueil sur la matrice LED, suivie du nom du projet accompagné d’une musique d’introduction. Ensuite, l’utilisateur accède au menu de sélection des musiques, affiché avec les numéros 1, 2, 3, 4 et 5. Chaque numéro correspond à une touche capacitive et à une musique différente.

Les musiques proposées sont :
- 1 – Canon in D
- 2 – Star Wars
- 3 – Harry Potter
- 4 – Super Mario Bros
- 5 – Für Elise
Une fois la musique sélectionnée, la partie commence. Les notes sont jouées par le haut-parleur et, au début, la musique est jouée lentement afin de faciliter le démarrage. Ensuite, la vitesse augmente progressivement, ce qui rend le jeu plus difficile et plus dynamique.
Les notes sont représentées visuellement sur la matrice LED. Lorsque la note atteint la partie inférieure de l’écran, elle devient rouge : cela indique que le joueur doit appuyer sur la touche correspondante. Il doit maintenir la touche appuyée jusqu’à la fin de la note, c’est-à-dire jusqu’à ce qu’elle disparaisse de l’écran. Ainsi, une note courte nécessite une pression courte, tandis qu’une note plus longue demande de maintenir le doigt appuyé plus longtemps.

Si la touche est correcte, le score augmente. Si le joueur appuie sur une mauvaise touche ou ne respecte pas le bon moment, la partie se termine immédiatement. Une musique de Game Over est alors jouée, le score final est affiché sur la matrice LED, puis le jeu revient automatiquement au menu principal afin de permettre à l’utilisateur de choisir une nouvelle musique.
Organisation du Code
Le programme du projet est organisé en plusieurs parties afin de séparer la gestion du matériel, des musiques, de l’affichage et de la logique du jeu. Le code principal est écrit en Arduino/C++ pour l’ESP32.
Bibliothèques utilisées
- Arduino.h – fonctions principales de l’environnement Arduino;
- Wire.h – communication I2C avec le capteur MPR121;
- Adafruit_GFX.h – fonctions graphiques de base;
- Adafruit_NeoMatrix.h et Adafruit_NeoPixel.h – contrôle de la matrice LED 32 × 8;
- Adafruit_MPR121.h – lecture des touches capacitives avec le capteur MPR121.
Fichiers des musiques
Les musiques sont séparées dans des fichiers .h, ce qui permet de garder le code principal plus clair. Chaque fichier contient une mélodie sous forme de tableau, avec une succession de notes et de durées.
#ifndef GAMEOVER_H
#define GAMEOVER_H
#define NOTE_D4 294
#define NOTE_E4 330
#define NOTE_G4 392
#define NOTE_GS4 415
#define NOTE_A4 440
#define NOTE_AS4 466
#define NOTE_B4 494
#define NOTE_C5 523
#define REST 0
int melodyGO[] = {
//game over sound
NOTE_C5,-4, NOTE_G4,-4, NOTE_E4,4, //45
NOTE_A4,-8, NOTE_B4,-8, NOTE_A4,-8, NOTE_GS4,-8, NOTE_AS4,-8, NOTE_GS4,-8,
NOTE_G4,8, NOTE_D4,8, NOTE_E4,-2,
};
int notesGO = sizeof(melodyGO) / sizeof(melodyGO[0]) / 2;
#endif
Chaque note est associée à une fréquence, et chaque durée est définie par un diviseur. Le programme utilise ensuite ces informations pour jouer la mélodie avec le haut-parleur et afficher les notes sur la matrice LED.
Structure générale du jeu
Le fonctionnement du jeu est basé sur une machine à états, appelée Phase. Elle permet de gérer les différentes étapes du programme:
enum Phase {
PHASE_NOTES,
PHASE_TITLE,
PHASE_MENU,
PHASE_PLAYING,
PHASE_GAME_OVER
};
- PHASE_NOTES – animation d’accueil avec des notes;
- PHASE_TITLE – affichage du titre du projet;
- PHASE_MENU – menu de sélection des musiques;
- PHASE_PLAYING – déroulement de la partie;
- PHASE_GAME_OVER – affichage du score final et musique de fin.
Cette organisation permet de rendre le programme plus lisible et d’éviter que toutes les actions soient mélangées dans la boucle principale.
Synchronisation du jeu
Un des points les plus importants du code est la synchronisation entre la musique, l’affichage des notes et la détection des touches. Pour que le jeu fonctionne correctement, il faut que les notes soient jouées au bon moment, qu’elles apparaissent sur la matrice LED de manière cohérente et que les appuis du joueur soient détectés sans retard.
Pour cette raison, l’utilisation de la fonction delay() a été évitée. En effet, delay() bloque l’exécution du programme pendant un certain temps. Pendant ce blocage, l’ESP32 ne peut pas lire correctement les touches, mettre à jour l’affichage ou gérer les autres événements du jeu. Cela rendrait le système moins réactif et pourrait provoquer des erreurs dans la détection des touches.
À la place, le programme utilise la fonction millis(), qui permet de mesurer le temps écoulé sans bloquer le reste du code. Grâce à cette méthode, le jeu peut gérer plusieurs actions en même temps : faire descendre les notes, jouer la musique, lire les touches capacitives, mettre à jour le score et contrôler les changements de phase.
Fonctions principales
La fonction setup() initialise les composants du système : la matrice LED, le buzzer, le capteur MPR121 et les paramètres de temps. Elle prépare aussi l’écran d’accueil et lance la musique d’introduction.
La fonction loop() est la boucle principale du programme. Elle vérifie en permanence l’état du jeu, lit les touches capacitives, met à jour l’affichage et exécute les actions correspondant à la phase actuelle.
init_mpr121()– initialise le capteur capacitif MPR121;drawMenu()– affiche le menu avec les numéros 1 à 5;startMusic()– démarre une nouvelle partie avec la musique sélectionnée;getSong()– sélectionne le tableau de notes correspondant à la musique choisie;upFallingMusic()– gère le déplacement des notes sur la matrice LED;drawFallingScene()– affiche les notes descendantes pendant le jeu ;checkPlayerInput()– vérifie si le joueur appuie sur la bonne touche;upSpeedByTime()– augmente progressivement la vitesse du jeu;enterGameOver()– arrête la partie et lance l’écran de fin;returnMenu()– retourne au menu principal après le Game Over.
Gestion des touches capacitives
Les touches sont lues à partir du capteur MPR121. Le programme utilise un système de debounce afin d’éviter les fausses détections lorsque l’utilisateur touche ou relâche une touche. Cela permet de rendre le jeu plus stable et plus agréable à utiliser.
Le code utilise aussi une petite tolérance temporelle : si le joueur appuie légèrement avant ou après le moment exact, l’action peut encore être prise en compte. Cela rend le jeu plus jouable, surtout lorsque la vitesse augmente.
Gestion du son
Le son est généré par l’ESP32 à l’aide d’un signal PWM. Ce signal est ensuite envoyé à l’entrée de l’amplificateur LM386, qui amplifie le signal avant de le transmettre au haut-parleur. Cela permet de reproduire les notes des différentes musiques avec un volume plus élevé.
Les fonctions playToneESP32() et stopToneESP32() permettent respectivement de générer une note ou d’arrêter le signal sonore.
Fin de partie
Lorsqu’une erreur est détectée, la fonction enterGameOver() est appelée. La musique s’arrête, une mélodie de Game Over est jouée, puis le score final est affiché sur la matrice LED. Après quelques secondes, le programme revient automatiquement au menu principal.
Résultat Final


Améliorations Possibles
- Ajouter plus de musiques, afin de proposer un choix plus varié à l’utilisateur ;
- Améliorer le code, notamment pour rendre certaines parties plus simples, plus lisibles et plus faciles à modifier;
- Améliorer l’affichage sur la matrice LED, avec des animations plus fluides et une meilleure représentation des notes;
- Ajouter plus de touches capacitives, pour rendre le jeu plus proche d’un vrai piano et permettre plus de possibilités musicales;
- Ajouter davantage d’effets visuels, par exemple lors du choix d’une musique, d’un bon appui ou d’un Game Over;
- Améliorer le système de score, avec par exemple des bonus, des combos ou différents niveaux de précision;
- Remplacer éventuellement la matrice LED par un écran LCD, afin d’avoir un affichage plus détaillé;
- Améliorer l’esthétique de la boîte, par exemple en la peignant, en fermant certains trous, en cachant mieux les fils ou en ajoutant des dessins sur la structure;
- Améliorer les supports arrière, afin de maintenir plus solidement la partie supérieure ouverte.
Contact des auteurs:
Camila Fernanda Pasko | cpasko@bordeaux-inp.fr
Maria Eduarda Negrelli de Araujo | maria.negrelli_de_araujo@bordeaux-inp.fr