Tutoriel pour construire une machine à réflexes dont le but est de taper le plus rapidement possible des lumières qui s'allument aléatoirement. Cette machine est utilisée par les pilotes de formule 1 pour améliorer leurs réflexes. Plus modestement nous l'utiliserons pour la kermesse d'une école primaire. Ce tutoriel contient l'explication de la fabrication de ce jeu ainsi que le code en langage arduino utilisé.
Le but était de créer une Batak Machine comme celles que les coureurs de formule 1 utilisent mais qui puisse être adaptée pour l'usage des enfants ainsi que des durées de jeu variables pour jouer plus tranquillement ou se donner à fond. Un menu maintenance est caché afin de pouvoir faire face aux problèmes pouvant survenir permettant de vérifier le bon fonctionnement des lumières, des boutons, du haut parleur, mais aussi pour remettre à zéro les meilleurs scores.
Budget : 120€
On utilise pour le projet des boutons d'arcade lumineux 60mm. (Si vous avez les moyens il existe des boutons de 100mm qui éclairent correctement d'origine mais ils sont très chers) Afin d'avoir une luminosité suffisante des boutons, nous avons utilisé des leds haute puissance automobiles qui s'alimentent entre 12 et 15V car la led fournie avec le bouton n'éclaire pas suffisamment. Nous alimenterons ces leds avec une tension de 15V et une intensité de 60mA. L'arduino ne pouvant sortir cette tension nous devons réaliser une interface à l'aide de transistors mosfet 2N7000.
On réalisera 12 fois le même montage pour les 12 leds sur la plaquette véroboard. On la relie avec un cable en nappe sur les pins de l'arduino.
C'est un montage classique d'anti-rebons des boutons poussoirs. On le réalise 12 fois pour les 12 boutons comme dans la photo de la plaquette. On la relie avec un cable en nappe sur les pins de l'arduino. Sur la photo 3 j'ai mesuré à l’oscilloscope ce qui se passe lors de l'appui sur un bouton, on voit bien les rebonds de l'interrupteur cela peut poser des problèmes car l'arduino reçoit plusieurs appuis du bouton, c'est pour cela que l'on utilise des condensateurs. Sur la photo 4 avec les condensateurs il n'y a plus de rebonds.
Il s'agit de simples régulateurs LM7805 et LM7815 alimentés par un transformateur 14V redressés par un pont d'iode et filté par un condensateur 2200µF.
La taille de la plaque est de 120x120cm. Chacun pourra laisser ses talents de menuisier s'exprimer. Bien respecter l'implantation des boutons comme sur le schéma.
Les interconnections de l'arduino avec le reste:
Mode de fonctionnement : On allume un bouton aléatoirement qu’on doit éteindre en appuyant dessus ; on marque un point à chaque réussite. Si pas d’appui pendant 2 secondes on change de bouton. Le score final est le total de bouton éteint.
Road map :
Plusieurs modes de jeu : - Mode 12 boutons
-Mode 8 boutons (pour les enfants de petite taille)
-2 durées 60 et 30 secondes
Mise en mémoire des meilleurs scores par catégorie même après extinction (EEprom)
Des musiques d’animation a l’allumage et a chaque incrémentation d’un best score
Un menu caché de maintenance pour tester toutes les fonctions (boutons/leds) et RAZ les bestscores
Visualisation du score et des commandes sur un écran LCD
Ceci est mon premier programme arduino, vous noterez une evolution du code au fur et à mesure de mon apprentissage (surtout au niveau du nom des variables et de l'utilisation des fonctions sur la fin du programme).
Ce projet m'a permis de découvrir plusieurs domaines de l'arduino en étant confronté aux problèmes de réalisation comme les tableaux la gestion du temps et les fonctions que l'expliquerai plus en détail dans les prochaines parties.
L'entree est branchée au + par une résistance pullup, et le bouton met cette entréee a la masse lors d'un appui. Ce qui donne un état LOW. Ce qu'il faut savoir pour gérer les boutons, c'est qu'il ne faut pas oublier de les bloquer. En effet si on fait simplement un if(digitalRead(bouton) == LOW) et que l'on met la condition elle se réalisera de nombreuses fois. à la fin de la condition il faut donc introduire un while qui bloquera le programme dans une boucle le temps que le bouton se relâche comme ceci.
boolean x = 0; const byte bouton = 3;//pin du bouton = 3 const byte led = 12;//pin de la led = 12 void setup(){ pinMode(led, OUTPUT);//on initialise la led en tant que sortie pinMode(bouton, INPUT);//on initialise le bouton en tant qu'entrée } void loop(){ if(digitalRead(bouton) == LOW){x=!x;}//Si le bouton est appuyé on switch la variable while(digitalRead(bouton) == LOW){}//on attend que le bouton soit relâché if(x==0){digitalWrite(led, HIGH);}//si la variable vaut 0 on éteint la lumière if(x==1){digitalWrite(led, LOW);}//si elle vaut 1 on l'allume }
Voilà un petit programme pour switch une led allumée et éteinte avec un seul bouton par exemple.
Pour pouvoir choisir un bouton à allumer aléatoirement, il est plus facile d'utiliser les tableaux. Les tableaux sont des variables qui en contiennent plusieurs, et on peut ensuite appeler une variable du tableau en appelant le nom du tableau suivi du numéro de la variable (les numéros commencent par 0). Ainsi pour choisir un bouton aléatoirement on n'a plus qu'a choisir un nombre entre 0 et 11.
Pour déclarer on déclare le type de variables que l'on retrouve dans le tableau et on met des crochets après le nom du tableau et on met les variables du tableau entre crochets et on les sépare par des virgules.
char bouton[] = {53, 51, 49, 47, 45, 43, 42, 44, 46, 48, 50, 52}; // Pins des boutons respectivement de 1 a 12 char led[] = {33, 31, 29, 27, 25, 23, 22, 24, 26, 28, 30, 32}; // Pins des Leds respectivement de 1 a 12
Pour les appeler on fait ensuite comme ceci.
// Initialisation des entree sorties for(int i = 0; i < 12; i ++){ pinMode(led[i], OUTPUT); pinMode(bouton[i], INPUT); digitalWrite(led[i], LOW); }
Pour appeler un bouton aléatoirement on peut donc faire:
Serial.begin(9600); randomSeed(analogRead(0)); // Initialisation de la graine aléatoire utilisée alea = random(0, 12);//on choisi un numéro aléatoire de bouton entre 0 et 11 Serial.print(bouton[alea]);
Parfois, on a besoin d'attendre dans le programme mais on ne peut pas utiliser la fonction delay car on a besoin que quelque chose d'autre s'effectue en arrière plan. On a donc besoin d'utiliser la fonction millis(), cette fonction permet de donner le nombre de millisecondes écoulées depuis le lancement du programme. Ainsi en sauvegardant cette valeur dans une variable on peut calculer la différence entre cette variable et la nouvelle valeur de millis() pour calculer une durée.
temps = millis();//on sauvegarde la référence de temps score = 0; while((millis() - temps) < (1000 * 60)){//on regarde si la durée de la partie est écoulé
Ainsi dans cet extrait du code la partie continue tant que 60 secondes ne sont pas écoulées.
Vous verrez dans le programme final que j'utilise beaucoup de variables pour le temps.
Les fonctions permettent d'appeler une partie de programme plus simplement dans un programme. Cela permet d’améliorer la clarté ou diminuer les répétitions. Par exemple dans ce programme on défini une fonction qui allume tous les boutons ou éteints tous les boutons.
void allumetout(){ testleds=!testleds; if(testleds==1){for(int i = 0; i < 12; i++){ digitalWrite(led[i], HIGH);}} if(testleds==0){for(int i = 0; i < 12; i++){ digitalWrite(led[i], LOW);}} }
On déclare la fonction en utilisant void puis le nom de la fonction des parenthèses et on ouvre l'accolade. Ensuite pour l'appeler on écrit le nom de la fonction avec des parenthèses comme ceci.
allumetout();
Les fonctions ont été utilisées pour la fin du programme principalement dans le menu maintenance.
Nous voulons conserver les meilleurs scores même lorsque la machine est éteinte, il faut donc les stocker dans des mémoires non volatiles de l'arduino. La mémoire EEPROM est une mémoire qui ne s’efface pas lorsque le programme s'arrête on peut donc stocker les meilleurs scores dedans. On ne s'en sert pas souvent car la mémoire EEPROM à un nombre d'écritures limité (25000) et elle n'est pas très rapide, ce qui convient bien pour stocker un meilleur score.
#include <EEPROM.h> // ajout de la librairie EEPROM pour sauvegarder les meilleurs scores
Pour écrire dedans on utilise la commande EEPROM.write(); le premier nombre est le slot de mémoire dans lequel on écrit et le deuxième est la valeur que l'on stocke.
if(score > bestScore){ bestScore = score; if(temps4 == 0 && niveau == 0){EEPROM.write(0, bestScore);} if(temps4 == 1 && niveau == 0){EEPROM.write(1, bestScore);} if(temps4 == 0 && niveau == 1){EEPROM.write(2, bestScore);} if(temps4 == 1 && niveau == 1){EEPROM.write(3, bestScore);}
Et on lit les variables EEPROM avec la commande EEPROM.read(); avec le numéro du slot que l'on souhaite.
// Lecture des meilleurs scores bestScore30lv1 = EEPROM.read(0); bestScore60lv1 = EEPROM.read(1); bestScore30lv2 = EEPROM.read(2); bestScore60lv2 = EEPROM.read(3);
Maintenant vous voilà prêts pour le code je vous le présente ici j'ai commenté presque tout, si vous avez des questions dessus je peux y répondre avec plaisir.
// Declaration des variables char menu = 0; boolean testleds = 0; long temps;//t0 stockage des millisecondes du début de la partie (référence du temps) long temps2;//variable pour vérifier si 2 secondes passent entre chaque appui de bouton long temps3 = 0;//durée de la partie jusqu'a maintenant en secondes boolean temps4 = 0;//0 si 30 secondes 1 si 60 secondes long temps5;//durée de la partie 30 ou 60 secondes long temps6;//3 secondes avant la fin de la partie long temps7;//variable pour tone a chaque secondes quand il en reste moins de 3 boolean x;//inconnue à trouver boolean niveau;//0 Si facile et 1 si difficile char niveau2;//le nombre de boutons (12 ou 8) en fonction de la difficulté (1 ou 0) byte bestScore; byte bestScore30lv1;//Meilleur score 30 secondes 8 boutons byte bestScore60lv1;//Meilleur score 60 secondes 8 boutons byte bestScore30lv2;//Meilleur score 30 secondes 12 boutons byte bestScore60lv2;//Meilleur score 60 secondes 12 boutons char alea;//numéro du bouton aléatoire qui s'allume long score;//score int Son[] = {262, 294, 330, 349, 392, 440, 494, 523, 587, 659, 698, 784}; // notes pour musique de début // Declaration des sorties const int buzzer = 34; //haut parleur à la pin 34 char led[] = {33, 31, 29, 27, 25, 23, 22, 24, 26, 28, 30, 32}; // Pins des Leds respectivement de 1 a 12 char led1 = 33; //led du bouton niveau char led2 = 31; //led du bouton start char led3 = 29; //led du bouton temps // Declaration des entrees char bouton[] = {53, 51, 49, 47, 45, 43, 42, 44, 46, 48, 50, 52}; // Pins des boutons respectivement de 1 a 12 char boutonNiveau = 53; // bouton niveau char boutonStart = 51; // bouton start char boutonTemps = 49; // bouton temps // Declaration des notes pour musique best score unsigned int C6 = 1047; unsigned int Ab5 = 831; unsigned int Bb5 = 932; unsigned int G5 = 784; unsigned int F5 = 698; unsigned int E5 = 659; unsigned int Eb5 = 622; unsigned int D5 = 587; unsigned int Db5 = 554; unsigned int C5 = 523; unsigned int B4 = 494; unsigned int Bb4 = 466; unsigned int nA4 = 440; unsigned int Ab4 = 415; unsigned int G4 = 392; unsigned int Gb4 = 370; unsigned int F4 = 349; unsigned int E4 = 330; unsigned int Eb4 = 311; unsigned int D4 = 294; unsigned int Db4 = 277; unsigned int C4 = 262; unsigned int B3 = 247; unsigned int Bb3 = 233; unsigned int nA3 = 220; unsigned int GS3 = 208; unsigned int G3 = 196; unsigned int Gb3 = 185; unsigned int F3 = 175; unsigned int E3 = 165; char speakerPin = 34; // Inclusion des librairies #include <EEPROM.h> // ajout de la librairie EEPROM pour sauvegarder les meilleurs scores #include <Wire.h> // ajout de la librairie I2C pour communiquer avec le LCD #include <LiquidCrystal_I2C.h> // ajout de la librairie LCD LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE); // Adresse I2C 0x27 a remplacer par la votre si differente void setup(){ // Initialisation des entree sorties for(int i = 0; i < 12; i ++){ pinMode(led[i], OUTPUT); pinMode(bouton[i], INPUT); digitalWrite(led[i], LOW); } lcd.begin(20,4); // Initialisation du LCD randomSeed(analogRead(0)); // Initialisation de la graine aléatoire utilisée niveau = 0; //mode facile (8 boutons) par défaut pinMode(buzzer, OUTPUT); //initialisation du haut parleur en tant que sortie // Animation a l'allumage //on allume toutes les leds une par une avec un bruit for(char i=0; i<sizeof(led); i++) { digitalWrite(led[i], HIGH); tone(buzzer, Son[i]); delay(300); } // on coupe le son et on attend un peu noTone(buzzer); delay(150); // puis on les éteint de même, mais plus rapidement for(char i=sizeof(led); i>0; i--) { tone(buzzer, Son[i-1]); delay(150); digitalWrite(led[i-1], LOW); } // ainsi que le son noTone(buzzer); } void loop(){ x = 0; temps3 = 0; temps6 = 3; // Lecture des meilleurs scores bestScore30lv1 = EEPROM.read(0); bestScore60lv1 = EEPROM.read(1); bestScore30lv2 = EEPROM.read(2); bestScore60lv2 = EEPROM.read(3); // Alumages des 3 boutons du menu digitalWrite(led2, HIGH); digitalWrite(led1, HIGH); digitalWrite(led3, HIGH); //tant que on n'a pas démarré la partie (appuyé sur start) while(digitalRead(boutonStart) == HIGH){ if(digitalRead(bouton[11]) == LOW && digitalRead(bouton[10])==LOW){ modeusine();}// Si 11 et 12 apuyés passer en menu maintenance // Affichage du menu sur LCD lcd.setCursor(0,0); lcd.print("Press Start to begin"); lcd.setCursor(0,1); if(niveau == 0){ lcd.print("Facile 8 boutons"); } else{ lcd.print("Difficile 12 boutons"); } lcd.setCursor(0,2); lcd.print("Duree:"); lcd.print(temps5); lcd.print(" Secondes"); lcd.setCursor(0,3); lcd.print("Score:"); lcd.print(score); lcd.print(" "); lcd.print("Best:"); lcd.print(bestScore); lcd.print(" "); //Changer la Durée if(digitalRead(boutonTemps) == LOW){ temps4 = !temps4; while(digitalRead(boutonTemps) == LOW) {} } //changer la difficulté (nombre de boutons) if(digitalRead(boutonNiveau) == LOW){ lcd.setCursor(0,1); lcd.print(" "); niveau = !niveau; while(digitalRead(boutonNiveau) == LOW){} } //Changer niveau2(nombre de boutons) en fonction de niveau (difficulté) if(niveau == 1){ niveau2 = 12; } else{ niveau2 = 8; } //Changer temps5(durée) en fonction de temps4 (0 si 30 sec et 1 si 60 sec) if(temps4 == 1){ temps5 = 60; } else{ temps5 = 30; } //affichage du Meilleur score en fonction du mode choisi if(temps4 == 0 && niveau == 0){bestScore = bestScore30lv1;} if(temps4 == 1 && niveau == 0){bestScore = bestScore60lv1;} if(temps4 == 0 && niveau == 1){bestScore = bestScore30lv2;} if(temps4 == 1 && niveau == 1){bestScore = bestScore60lv2;} } //La partie commence lcd.clear(); //On éteint les leds du menu digitalWrite(led2, LOW); digitalWrite(led1, LOW); digitalWrite(led3, LOW); //décompte au démarage for(int i = 0; i < 3; i++){ tone(buzzer, 1000); delay(200); for(int i = 0; i < niveau2; i ++){ digitalWrite(led[i], HIGH);} noTone(buzzer); delay(800); for(int i = 0; i < niveau2; i ++){ digitalWrite(led[i], LOW);} } tone(buzzer, 2500); delay(1000); noTone(buzzer); //fin décompte au démarage //initialisation du temps temps = millis();//on sauvegarde la référence de temps temps2 = millis(); x = 0; score = 0; while((millis() - temps) < (1000 * temps5)){//on regarde si la durée de la partie est écoulé alea = random(0, niveau2);//on choisi un numéro aléatoire de bouton à allumer entre 0 et le nombre de boutons total digitalWrite(led[alea], HIGH);//on allume la led correspondant au bouton choisi aléatoirement //tant que l'on à appuyé sur aucun bouton et que 2 secondes ne sont pas passées while(digitalRead(bouton[0]) == HIGH && digitalRead(bouton[1]) == HIGH && digitalRead(bouton[2]) == HIGH && digitalRead(bouton[3]) == HIGH && digitalRead(bouton[4]) == HIGH && digitalRead(bouton[5]) == HIGH && digitalRead(bouton[6]) == HIGH && digitalRead(bouton[7]) == HIGH && digitalRead(bouton[8]) == HIGH && digitalRead(bouton[9]) == HIGH && digitalRead(bouton[10]) == HIGH && digitalRead(bouton[11]) == HIGH && (temps2 + 2000) > millis()){ //Le lcd affiche le score et le temps restant //on affiche le score lcd.setCursor(0,0); lcd.print("Score="); lcd.print(score); //on affiche le temps restant lcd.setCursor(0,1); lcd.print("Temps Restant:"); if(millis() - temps - (1000 * temps3) > 1000){//si une seconde est passé temps3++;//on augmente la durée de la partie jusqu'à maintenant d'une seconde lcd.print(" ");//on clear l'ancienne valeur de temps restant lcd.setCursor(14,1);//on se place derriere les deux points de "Temps Restant:" lcd.print(temps5-temps3);//on affiche la nouvelle valeur du temps restant (temps total - temps écoulé) } //décompte si il reste moins de 3 secondes (buzz toutes les secondes) if((millis() - temps) > (1000 * temps5 - (temps6 * 1000))){ temps6--; tone(buzzer, 1000); temps7 = millis();//variable pour la durée du buzz (300ms) } if(millis() - temps7 > 300){noTone(buzzer);}//au bout de 300ms on arrete le buzz }//fin du temps que l'on à appuyé sur aucun bouton et que 2 secondes ne sont pas passées if(digitalRead(bouton[0]) == LOW || digitalRead(bouton[1]) == LOW || digitalRead(bouton[2]) == LOW || digitalRead(bouton[3]) == LOW || digitalRead(bouton[4]) == LOW || digitalRead(bouton[5]) == LOW || digitalRead(bouton[6]) == LOW || digitalRead(bouton[7]) == LOW || digitalRead(bouton[8]) == LOW || digitalRead(bouton[9]) == LOW || digitalRead(bouton[10]) == LOW || digitalRead(bouton[11]) == LOW){ //Si on a appuyé sur un bouton if(digitalRead(bouton[alea]) == LOW){//et que le bouton appuyé est le bon score++; } } while(digitalRead(bouton[0]) == LOW || digitalRead(bouton[1]) == LOW || digitalRead(bouton[2]) == LOW || digitalRead(bouton[3]) == LOW || digitalRead(bouton[4]) == LOW || digitalRead(bouton[5]) == LOW || digitalRead(bouton[6]) == LOW || digitalRead(bouton[7]) == LOW || digitalRead(bouton[8]) == LOW || digitalRead(bouton[9]) == LOW || digitalRead(bouton[10]) == LOW || digitalRead(bouton[11]) == LOW){ //tant que on n'a pas lâché le bouton (pour ne pas bloquer l'affichage du temps et pour rester coincé dans une boucle pour ne pas faire un score infini) //buzz si 3 secondes restantes if((millis() - temps) > (1000 * temps5 - (temps6 * 1000))){ temps6--; tone(buzzer, 1000); temps7 = millis(); } if(millis() - temps7 > 300){noTone(buzzer);} //affichage du score et du temps restant lcd.setCursor(0,0); lcd.print("Score="); lcd.print(score); lcd.setCursor(0,1); lcd.print("Temps Restant:"); if(millis() - temps - (1000 * temps3) > 1000){ temps3++; lcd.print(" "); lcd.setCursor(14,1); lcd.print(temps5-temps3); } }//quand on a enfin lache le bouton //buzz si 3 secondes restantes if((millis() - temps) > (1000 * temps5 - (temps6 * 1000))){ temps6--; tone(buzzer, 1000); temps7 = millis(); } if(millis() - temps7 > 300){noTone(buzzer);} //affichage du score et du temps restant lcd.setCursor(0,0); lcd.print("Score="); lcd.print(score); lcd.setCursor(0,1); lcd.print("Temps Restant:"); if(millis() - temps - (1000 * temps3) > 1000){ temps3++; lcd.print(" "); lcd.setCursor(14,1); lcd.print(temps5-temps3); } temps2 = millis();//on sauvegarde la référence du temps par rapport aux 2 secondes maximum entre 2 appuis de bouton digitalWrite(led[alea], LOW);//on éteint la led du bouton qu'il fallait appuyer }//fin de la partie //animation fin for(char i=0; i<12; i++) {//on allume toutes les leds digitalWrite(led[i], HIGH); } // puis on les éteint une à une en jouant le son associé for(char i=12; i>0; i--) { tone(buzzer, Son[i-1]); delay(150); digitalWrite(led[i-1], LOW); } noTone(buzzer);// et on coupe le son temps2 = millis(); digitalWrite(led[alea], LOW); if(x == 0){ lcd.clear(); //incrémentation du score si c'est le meilleur if(score > bestScore){ bestScore = score; if(temps4 == 0 && niveau == 0){EEPROM.write(0, bestScore);} if(temps4 == 1 && niveau == 0){EEPROM.write(1, bestScore);} if(temps4 == 0 && niveau == 1){EEPROM.write(2, bestScore);} if(temps4 == 1 && niveau == 1){EEPROM.write(3, bestScore);} musiquebest();//joue la musique du meilleur score } } lcd.print("Score="); lcd.print(score); lcd.setCursor(0,1); lcd.print("Best Score="); lcd.print(bestScore); x = !x; delay(2500); lcd.clear(); }//fin de la boucle loop on revient au menu //fait à la fin et à ce moment là j'ai compris l'utilité des fonctions void modeusine(){ while(digitalRead(bouton[11]) == LOW && digitalRead(bouton[10]) == LOW){} digitalWrite(led[0], LOW);digitalWrite(led[1], LOW);digitalWrite(led[2], LOW); while(digitalRead(bouton[11]) == HIGH || digitalRead(bouton[10]) == HIGH){ if(digitalRead(bouton[2]) == LOW){menu++; while(digitalRead(bouton[2]) == LOW){}} if(menu>=2){menu=0;} if(menu==0){ lcd.setCursor(0,0); lcd.print("Bouton1:On/Off leds "); lcd.setCursor(0,1); lcd.print("Bouton2:test boutons"); lcd.setCursor(0,2); lcd.print("Bouton4:test HP "); lcd.setCursor(0,3); lcd.print("Bouton5:Raz scores "); if(digitalRead(bouton[0]) == LOW){while(digitalRead(bouton[0])==LOW){} allumetout();} if(digitalRead(bouton[1]) == LOW){while(digitalRead(bouton[1])==LOW){} testboutons();} if(digitalRead(bouton[3]) == LOW){while(digitalRead(bouton[3])==LOW){} musiquebest();} if(digitalRead(bouton[4]) == LOW){while(digitalRead(bouton[4])==LOW){} EEPROM.write(0,0); EEPROM.write(1,0); EEPROM.write(2,0); EEPROM.write(3,0);} } if(menu==1){ lcd.setCursor(0,0); lcd.print("Bouton1:Reset 8b30s "); lcd.setCursor(0,1); lcd.print("Bouton2:Reset 8b60s "); lcd.setCursor(0,2); lcd.print("Bouton4:Reset 12b30s"); lcd.setCursor(0,3); lcd.print("Bouton5:Reset 12b60s"); if(digitalRead(bouton[0]) == LOW){while(digitalRead(bouton[0])==LOW){} EEPROM.write(0,0);} if(digitalRead(bouton[1]) == LOW){while(digitalRead(bouton[1])==LOW){} EEPROM.write(1,0);} if(digitalRead(bouton[3]) == LOW){while(digitalRead(bouton[3])==LOW){} EEPROM.write(2,0);} if(digitalRead(bouton[4]) == LOW){while(digitalRead(bouton[4])==LOW){} EEPROM.write(3,0);} } } while(digitalRead(bouton[11]) == LOW && digitalRead(bouton[10]) == LOW){} digitalWrite(led2, HIGH); digitalWrite(led1, HIGH); digitalWrite(led3, HIGH); lcd.clear(); } void testboutons(){ if(testleds==1){for(int i = 0; i < 12; i++){ digitalWrite(led[i], LOW);}testleds=!testleds;} for(int i = 0; i < 12; i++){ digitalWrite(led[i], HIGH); while(digitalRead(bouton[i]) == HIGH){} digitalWrite(led[i], LOW); } } void allumetout(){ testleds=!testleds; if(testleds==1){for(int i = 0; i < 12; i++){ digitalWrite(led[i], HIGH);}} if(testleds==0){for(int i = 0; i < 12; i++){ digitalWrite(led[i], LOW);}} } void musiquebest(){ buzz(speakerPin,G3,166); buzz(speakerPin,C4,166); buzz(speakerPin,E4,166); buzz(speakerPin,G4,166); buzz(speakerPin,C5,166); buzz(speakerPin,E5,166); buzz(speakerPin,G5,500); buzz(speakerPin,E5,500); buzz(speakerPin,E3,166); buzz(speakerPin,C4,166); buzz(speakerPin,Eb4,166); buzz(speakerPin,Ab4,166); buzz(speakerPin,C5,166); buzz(speakerPin,Eb5,166); buzz(speakerPin,Ab5,500); buzz(speakerPin,Eb5,500); buzz(speakerPin,Bb3,166); buzz(speakerPin,D4,166); buzz(speakerPin,F4,166); buzz(speakerPin,Bb4,166); buzz(speakerPin,D5,166); buzz(speakerPin,F5,166); buzz(speakerPin,Bb5,500); delay(50); buzz(speakerPin,Bb5,166); delay(50); buzz(speakerPin,Bb5,166); delay(50); buzz(speakerPin,Bb5,166); buzz(speakerPin,C6,1300); } void buzz(int targetPin, long frequency, long length) { long delayValue = 1000000 / frequency / 2; // calculate the delay value between transitions //// 1 second's worth of microseconds, divided by the frequency, then split in half since //// there are two phases to each cycle long numCycles = frequency * length / 1000; // calculate the number of cycles for proper timing //// multiply frequency, which is really cycles per second, by the number of seconds to //// get the total number of cycles to produce for (long i = 0; i < numCycles; i++) { // for the calculated length of time... digitalWrite(targetPin, HIGH); // write the buzzer pin high to push out the diaphram delayMicroseconds(delayValue); // wait for the calculated delay value digitalWrite(targetPin, LOW); // write the buzzer pin low to pull back the diaphram delayMicroseconds(delayValue); // wait again or the calculated delay value } }
Fichiers :
Le jeu est très apprécié des grands et des petits et rencontre un franc succès dans la kermesse. Félicitations vous avez réussi à amuser la galerie.
Mon meilleur score est 110 en 12 boutons et 60 secondes à vous de jouer.
T'inquiète pas pour ça ... c'est vrai que la partie électronique semble relativement complexe ... je pensais q'avec de simple bouton arcade lumineux , un écran led ca ferait l'affaire ;) ... et bah nan ! Du coup je vais devoir essayer de comprendre les schémas :)
Bonjour, je vais essayer de me lancer dans l'aventure ... avez vous une liste précise du matos a acheter ?
Bonjour Odissine, merci beaucoup pour le projet est excellent, je le construis pour le moment, mais j'ai des doutes avec les connexions sur le tableau de contact des boutons et du led, pouvez-vous s'il vous plaît placer une photo de l'arrière? Désolé, mon français, mais je ne le parle pas, j'utilise la traduction. Je vous remercie d'avance
Bonjour j'ai mis à jour la liste des composants et des photos qui avaient disparu. N'hésitez pas à poser des questions
bonjour, je voulais recréer votre projet. malheureusement, je reçois une erreur dans la ligne LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);: 'POSITIVE' was not declared in this scope Qu'est-ce que j'ai fait de mal Salutations
Bonjour,
un grand merci pour ce tuto, je viens de terminer le miens, les enfants adorent !
Le seul problème c'est que je n'ai pas trouvé la correspondance entre la numérotation BP/LED et la position physique sur le plan de jeux. J'ai pu recaler les boutons START/MODE/DUREE car ils sont facilement identifiable mais pour le mode 8 boutons je ne comprends pas. En effet, les boutons Mode / Duree font a priori partie des boutons à allumer en mode 8 boutons (Ils font parti des 8 qui clignotent au départ), pourtant, les boutons mode et durée sont situés dans la partie haute et donc pas accessible pour les enfants de petites taille. Je ne sais pas si ma question est clair, je suis peut être passé a coté de quelque chose... En tout cas merci encore pour le partage.
Bonjour, merci pour votre contribution, j'ai construit le projet sans problème, mais dans la partie programmation je pense qu'il y a quelque chose qui ne fonctionne pas, dès que la première lumière est allumée et que vous appuyez sur le bouton correspondant, rien ne se passe. Je pense que le problème pourrait être dans la première boucle while où tous les boutons sont en HIGH?
Bonjour, j'ai acheté tous le nécessaire pour la batak, serait il possible d'avoir des photos du dessous des plaques pour voir les pontages ? merci d'avance. Pascal
Super tuto ! Depuis le temps que je cherchais un tuto autour de ce projet ! Je vais pouvoir terminer le mien ... ou investir dans un Mega pour faire un vrai batak ;)
un grand merci !
Hate de voir la partie Code pour m'aider a mieux comprendre !
J'avoue ne pas avoir tout compris sur l'électronique mais je vais lire et relire encore ;)
Encore merci
Cyril