ENIB 2024 : GNOP : Différence entre versions

De Les Fabriques du Ponant
Aller à : navigation, rechercher
(Étape 14)
 
(62 révisions intermédiaires par 2 utilisateurs non affichées)
Ligne 1 : Ligne 1 :
 
Titre de la fiche expérience :
 
Titre de la fiche expérience :
==description (résumé)==
+
==Description==
éventuelle photo de l'équipe  
+
Le projet est de fabriquer un jeu ludique à l'aide d'une carte Arduino, notre jeu est le D1-Pong. Inspiré du sport du tennis de table, il reprend le même principe mais avec des LEDS, la balle se déplace sur les LEDS et dès qu'elle arrive à une extrémité, le joueur en question appuie sur son bouton pour que la balle parte dans l'autre sens et ainsi de suite.
 +
<br/>​
 +
Voici notre équipe :
 +
<br/>
 +
Arthur :
 +
[[Fichier:arthur.jpg|100px]]
 +
Laouen :
 +
[[Fichier:laouen.jpg|100px]]
 +
Ewen 1 :
 +
[[Fichier:ramzi.jpg|100px]]
 +
Ewen 2 : (parti au combat)
 +
[[Fichier:virgule.jpg|100px]]
 +
Alban : (jamais vu)
 +
[[Fichier:alban.jpg|100px]]
  
[[Fichier:Totem-maisonsDesMinerauxCrozon.JPG|200px]]
+
==Outil et matériel==
 +
Pour fabriquer ce jeu, nous avons eut besoin de :
 +
* Carte Arduino Nano
 +
* 2 boutons d'arcade
 +
* Carton
 +
* Fils électriques
 +
* Batterie externe
 +
* Ruban de LEDS
 +
* Haut-parleur
 +
* Bois
 +
<br/>
 +
Nous nous sommes servis de plusieurs outils :
 +
* Fer à souder
 +
* Pistolet à colle
 +
* Cutter
 +
* Scie à bois
 +
* Lime à bois
 +
* Découpeuse Vinyle
 +
 
 +
==Code Arduino==
 +
<syntaxhighlight lang="Arduino" line>
 +
/*
 +
  Code de fonctionnement pour le jeu PONG.
 +
  Par les petits debrouillards.
 +
*/
 +
 
 +
#include <FastLED.h>
 +
 
 +
// Definition des couleurs
 +
const CRGB NOIR  = CRGB(0,  0,  0  ); //Création d'une constante de type CRGB de couleur noire
 +
const CRGB BLANC = CRGB(255, 255, 255); //Création d'une constante de type CRGB de couleur blanche
 +
const CRGB ROUGE = CRGB(255, 0,  0  ); //Création d'une constante de type CRGB de couleur rouge
 +
const CRGB VERT  = CRGB(0,  255, 0  ); //Création d'une constante de type CRGB de couleur verte
 +
const CRGB BLEU  = CRGB(0,  0,  255); //Création d'une constante de type CRGB de couleur bleue
 +
const CRGB JAUNE = CRGB(255, 255, 0  ); //Création d'une constante de type CRGB de couleur jaune
 +
const CRGB ROSE  = CRGB(255, 0,  255); //Création d'une constante de type CRGB de couleur rose
 +
const CRGB CYAN  = CRGB(0,  255, 255); //Création d'une constante de type CRGB de couleur cyan
 +
 
 +
// Definition des notes de musique
 +
const int PONG_SOUND = 250; //380
 +
const int LOOSE_SOUND = 180;
 +
 
 +
 
 +
/******************************
 +
    PARAMETRES DE BRANCHEMENTS
 +
******************************/
 +
 
 +
const int LED_PIN = 8;          // Numero de branchement de la bande de LEDs
 +
const int BUTTON1_PIN = 2;      // Numero de branchement du premier bouton
 +
const int BUTTON2_PIN = 4;      // Numero de branchement du deuxieme bouton
 +
const int HAUT_PARLEUR_PIN = 5; // Numero de branchement du haut parleur (optionnel)
 +
 
 +
 
 +
/***********************
 +
    PARAMETRES GENERAUX
 +
***********************/
 +
const int  NUM_LEDS = 60;            // Nombre de LEDs sur la bande
 +
const CRGB  PLAYER1_COLOR = VERT;    // Couleur Player 1
 +
const CRGB  PLAYER2_COLOR = ROUGE;    // Couleur Player 2
 +
 
 +
 
 +
/***********************
 +
    PARAMETRES PONG
 +
***********************/
 +
const float BALL_SPEED = 0.5;  // Vitesse de la balle
 +
const float ACCELERATION = 9;  // Accélération de la balle a chaque tir, si ACCELERATION = 10 on augmente la vitesse de 10 pourcent a chaque tir
 +
const int  HIT_ZONE = 8;      // Nombre de LED pendant lesquelles on peut renvoyer la balle
 +
const int  MAX_SCORE = 3;      // Score maximum avant la fin du jeu
 +
 
 +
const CRGB  BALL_COLOR = BLANC;      // Couleur de la balle
 +
 
 +
/*******************************
 +
    PARAMETRES TIR A LA CORDE
 +
*******************************/
 +
const float INCREMENT = 0.05;  // De combien avance la corde lorsqu'on appuie sur le bouton
 +
const float ROPE_SMOOTH = 1.0;  // Paramètre servant a lisser la position de la corde
 +
 
 +
const float WAVE_LENGTH = 0.2;  // Taille des ondes
 +
const float WAVE_SPEED =  1.0;  // Vitesse des ondes
 +
 
 +
 
 +
 
 +
/******************************
 +
      VARIABLES GENERALES
 +
******************************/
 +
// Players
 +
enum Player
 +
{
 +
  PERSONNE,
 +
  PLAYER1,
 +
  PLAYER2
 +
};
 +
 
 +
// Etats du jeu
 +
enum GameState
 +
{
 +
  START,
 +
  PONG,  // Mode pong
 +
  TAC    // Mode tir a la corde
 +
};
 +
 
 +
unsigned long lastMillis = 0;
 +
unsigned long beginTimer = 0;
 +
unsigned int counter = 0;
 +
 
 +
Player player = PLAYER1; // Prochain joueur a appuyer sur son bouton
 +
Player lastWinner = PERSONNE;
 +
 
 +
CRGB leds[NUM_LEDS];
 +
GameState gameState = START;
 +
 
 +
 
 +
/**********************************************
 +
      FONCTIONS DE FONCTIONNEMENT GENERALES
 +
**********************************************/
 +
 
 +
// Fonction permettant de changer la couleur d'une LED relativement au player 1 ou 2
 +
void ledColor(Player player, int pos, CRGB color)
 +
{
 +
  if (player == PLAYER1)
 +
  {
 +
    leds[pos] = color;
 +
  }
 +
  else // player == PLAYER2
 +
  {
 +
    leds[NUM_LEDS - pos - 1] = color;
 +
  }
 +
}
 +
 
 +
// Fonction permettant de changer la couleur d'une LED
 +
void ledColor(int pos, CRGB color)
 +
{
 +
  leds[pos] = color;
 +
}
 +
 
 +
/*********************************************
 +
      VARIABLES DE FONCTIONNEMENT DU PONG
 +
*********************************************/
 +
float ballSpeed = BALL_SPEED;  // Vitesse de la balle
 +
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)
 +
int player1Score = 0;  // Score du player 1
 +
int player2Score = 0;  // Score du player 2
 +
 
 +
/**********************************************
 +
      FONCTIONS DE FONCTIONNEMENT DU PONG
 +
**********************************************/
 +
// Fonction servant a afficher les scores
 +
void showScore()
 +
{
 +
  // On commence par effacer toutes les couleurs de led
 +
  FastLED.clear();
 +
 
 +
  // On allume le nombre de led correspondant au score du player 1
 +
  for (int i = 0; i < player1Score; i++)
 +
  {
 +
    ledColor(PLAYER1, NUM_LEDS / 2 - (i + 1), PLAYER1_COLOR);
 +
  }
 +
 
 +
  // On allume le nombre de led correspondant au score du player 2
 +
  for (int i = 0; i < player2Score; i++)
 +
  {
 +
    ledColor(PLAYER2, NUM_LEDS / 2 - (i + 1), PLAYER2_COLOR);
 +
  }
 +
 
 +
  // On envoie les nouvelles couleurs a la bande de led
 +
  FastLED.show();
 +
 
 +
  // On fait clignotter trois fois
 +
  if (lastWinner == PLAYER1)
 +
  {
 +
    for (int i = 0; i < 3; i++)
 +
    {
 +
      // On eteint la derniere LED pendant 0.5s
 +
      delay(500);
 +
      ledColor(PLAYER1, NUM_LEDS / 2 - player1Score, NOIR);
 +
      FastLED.show();
 +
 
 +
      // On allume la derniere LED pendant 0.5s
 +
      delay(500);
 +
      ledColor(PLAYER1, NUM_LEDS / 2 - player1Score, PLAYER1_COLOR);
 +
      FastLED.show();
 +
    }
 +
  }
 +
  else // lastWinner == PLAYER2
 +
  {
 +
    for (int i = 0; i < 3; i++)
 +
    {
 +
      // On eteint la derniere LED pendant 0.5s
 +
      delay(500);
 +
      ledColor(PLAYER2, NUM_LEDS / 2 - player2Score, NOIR);
 +
      FastLED.show();
 +
 
 +
      // On allume la derniere LED pendant 0.5s
 +
      delay(500);
 +
      ledColor(PLAYER2, NUM_LEDS / 2 - player2Score, PLAYER2_COLOR);
 +
      FastLED.show();
 +
    }
 +
  }
 +
 
 +
  // Si la partie est terminee on va a l'affichage de fin
 +
  if (player1Score == MAX_SCORE || player2Score == MAX_SCORE)
 +
  {
 +
    gameState = START;
 +
 
 +
    // On reinitialise les scores
 +
    player1Score = 0;
 +
    player2Score = 0;
 +
 
 +
    // On reinitialise la vitesse
 +
    ballSpeed = BALL_SPEED;
 +
 
 +
    // On reinitialise les leds
 +
    FastLED.clear();
 +
  }
 +
  // Sinon on reprend le jeu
 +
  else
 +
  {
 +
    gameState = PONG;
 +
    ballSpeed = BALL_SPEED;
 +
  }
 +
}
 +
 
 +
 
 +
/***************************************
 +
      FONCTION PRINCIPALE DU PONG
 +
***************************************/
 +
void pong_loop()
 +
{
 +
  // Calcul du temps ecoule entre deux boucles
 +
  unsigned long currentMillis = millis();
 +
 
 +
  // On calcule le numero de la LED allumee
 +
  int ballLed = ballPosition * NUM_LEDS;
 +
 
 +
  // On s'assure que la position de la balle ne depasse pas la taille de la bande de LED
 +
  ballLed = min(ballLed, NUM_LEDS - 1);
 +
 
 +
  // On regarde qui est en train de jouer
 +
  if (player == PLAYER1)
 +
  {
 +
    // On regarde si le player a appuye sur son bouton et si le delai de debut de jeu est passe
 +
    if (digitalRead(BUTTON1_PIN) == LOW && currentMillis - beginTimer > 500)
 +
    {
 +
      // Si la balle est hors de la zone de tir, l'autre player marque un point
 +
      if (ballLed >= HIT_ZONE)
 +
      {
 +
        player2Score += 1;
 +
        lastWinner = PLAYER2;
 +
        ballPosition = 0;
 +
 
 +
        // On joue le son de defaite
 +
        tone(HAUT_PARLEUR_PIN, LOOSE_SOUND, 800);
 +
 
 +
        // On passe en mode affichage des scores
 +
        showScore();
 +
 
 +
        // C'est a l'autre player de jouer
 +
        player = PLAYER2;
 +
 
 +
        // Actualisation de la variable lastMillis
 +
        lastMillis = millis();
 +
      }
 +
      else
 +
      {
 +
        // On accelere la balle
 +
        ballSpeed *= 1.0 + ACCELERATION / 100;
 +
 
 +
        // C'est a l'autre player de jouer
 +
        player = PLAYER2;
 +
 
 +
        // On joue la note de musique
 +
        tone(HAUT_PARLEUR_PIN, PONG_SOUND, 100);
 +
      }
 +
 
 +
      return;
 +
    }
 +
 
 +
    // On fait avancer la balle
 +
    ballPosition -= ballSpeed * (currentMillis - lastMillis) * 0.001f;
 +
 
 +
    // On regarde si la balle est sortie de la zone
 +
    if (ballPosition < 0.0f)
 +
    {
 +
      // Si oui le player 2 marque un point
 +
      player2Score += 1;
 +
      lastWinner = PLAYER2;
 +
      ballPosition = 0;
 +
 
 +
      // On joue le son de defaite
 +
      tone(HAUT_PARLEUR_PIN, LOOSE_SOUND, 800);
 +
 
 +
      // On passe en mode affichage des scores
 +
      showScore();
 +
 
 +
      // C'est a l'autre player de jouer
 +
      player = PLAYER2;
 +
 
 +
      // Actualisation de la variable lastMillis
 +
      lastMillis = millis();
 +
      return;
 +
    }
 +
  }
 +
  else // player == PLAYER2
 +
  {
 +
    // On regarde si le player a appuye sur son bouton et si le delai de debut de jeu est passe
 +
    if (digitalRead(BUTTON2_PIN) == LOW && currentMillis - beginTimer > 500)
 +
    {
 +
      // Si la balle est hors de la zone de tir, l'autre player marque un point
 +
      if (ballLed < NUM_LEDS - HIT_ZONE)
 +
      {
 +
        player1Score += 1;
 +
        lastWinner = PLAYER1;
 +
        ballPosition = 1;
 +
 
 +
        // On joue le son de defaite
 +
        tone(HAUT_PARLEUR_PIN, LOOSE_SOUND, 800);
 +
 
 +
        // On passe en mode affichage des scores
 +
        showScore();
 +
 
 +
        // C'est a l'autre player de jouer
 +
        player = PLAYER1;
 +
 
 +
        // Actualisation de la variable lastMillis
 +
        lastMillis = millis();
 +
      }
 +
      else
 +
      {
 +
        // On accelere la balle
 +
        ballSpeed *= 1.1;
 +
 
 +
        // C'est a l'autre player de jouer
 +
        player = PLAYER1;
 +
 
 +
        // On joue la note de musique
 +
        tone(HAUT_PARLEUR_PIN, PONG_SOUND, 100);
 +
      }
 +
 
 +
      return;
 +
    }
 +
 
 +
    // On fait avancer la balle dans l'autre sens
 +
    ballPosition += ballSpeed * (currentMillis - lastMillis) * 0.001f;
 +
 
 +
    // On regarde si la balle est sortie de la zone
 +
    if (ballPosition >= 1)
 +
    {
 +
      // Si oui le player 1 marque un point
 +
      player1Score += 1;
 +
      lastWinner = PLAYER1;
 +
      ballPosition = 1;
 +
 
 +
      // On joue le son de defaite
 +
      tone(HAUT_PARLEUR_PIN, LOOSE_SOUND, 800);
 +
 
 +
      // On passe en mode affichage des scores
 +
      showScore();
 +
      // C'est a l'autre player de jouer
 +
      player = PLAYER1;
 +
 
 +
      // Actualisation de la variable lastMillis
 +
      lastMillis = millis();
 +
      return;
 +
    }
 +
  }
 +
 
 +
  ///// AFFICHAGE BANDE DE LEDs /////
 +
  // Premierement on efface toutes les couleurs precedentes
 +
  FastLED.clear();
 +
 
 +
  // Ensuite on allume faiblement les LEDs correspondant a la zone de chaque cote
 +
  for (int i = 0; i < HIT_ZONE; i++)
 +
  {
 +
    // On allume de chaque cote
 +
    ledColor(PLAYER1, i, PLAYER1_COLOR / 10);  // On divise la couleur par 10 pour la rendre 10 fois moins puissante
 +
    ledColor(PLAYER2, i, PLAYER2_COLOR / 10);
 +
  }
 +
 
 +
  // Ensuite on allume faiblement les LEDs correspondant aux scores
 +
  // Pour le player 1
 +
  for (int i = 0; i < player1Score; i++)
 +
  {
 +
    ledColor(PLAYER1, NUM_LEDS / 2 - (i + 1), PLAYER1_COLOR / 15);
 +
  }
 +
  // Pour le player 2
 +
  for (int i = 0; i < player2Score; i++)
 +
  {
 +
    ledColor(PLAYER2, NUM_LEDS / 2 - (i + 1), PLAYER2_COLOR / 15);
 +
  }
 +
 
 +
  // Ensuite on actualise la position de la balle
 +
  // On donne la couleur de la led en fonction de si la balle est dans la zone d'un player ou non
 +
 
 +
  // Si la balle est dans le camp d'un des player, elle est rouge.
 +
  if (ballLed < HIT_ZONE || ballLed >= NUM_LEDS - HIT_ZONE)
 +
  {
 +
    ledColor(ballLed, ROUGE);
 +
  }
 +
  // Si elle en est proche, elle est jaune
 +
  else if (ballLed < 2 * HIT_ZONE || ballLed >= NUM_LEDS - 2 * HIT_ZONE)
 +
  {
 +
    ledColor(ballLed, JAUNE);
 +
  }
 +
  // Sinon la balle a sa couleur par defaut
 +
  else
 +
  {
 +
    ledColor(ballLed, BALL_COLOR);
 +
  }
 +
 
 +
  // On envoie la couleur des leds a la bande de leds
 +
  FastLED.show();
 +
 
 +
  // On actualise la variable lastMillis pour la boucle suivante
 +
  lastMillis = currentMillis;
 +
}
 +
 
 +
 
 +
 
 +
/*******************************************************
 +
      VARIABLES DE FONCTIONNEMENT DU TIR A LA CORDE
 +
*******************************************************/
 +
float ropePosition = 0.5;          // Position non lissee de la corde
 +
float displayedRopePosition = 0.5;  // Position lissee de la corde
 +
bool player1Pushed = false;
 +
bool player2Pushed = false;
 +
 
 +
float player1Waves[10] = { 0 };
 +
float player2Waves[10] = { 0 };
 +
 
 +
/***********************************************
 +
      FONCTION PRINCIPALE DU TIR A LA CORDE
 +
***********************************************/
 +
void tac_loop()
 +
 +
  // Calcul des temps
 +
  unsigned long ms = millis();
 +
  float dt = (ms - lastMillis) * 0.001f;
 +
  lastMillis = ms;
 +
 
 +
  // Si moins d'une seconde s'est ecoule depuis le debut, on ne fait rien (pour eviter d'appuyer sans faire expres)
 +
  if (ms - beginTimer < 1000)
 +
    return;
 +
 
 +
  bool player1Push = !digitalRead(BUTTON1_PIN);
 +
  bool player2Push = !digitalRead(BUTTON2_PIN);
 +
 
 +
  if (player1Push && !player1Pushed)
 +
  {
 +
    // On incremente la position de la corde
 +
    ropePosition += INCREMENT;
 +
 
 +
    // On lance une nouvelle onde
 +
    for (int i = 0; i < 10; i++)
 +
    {
 +
      if (player1Waves[i] == 0.0f)
 +
      {
 +
        //player1Waves[i] = WAVE_SPEED * dt;
 +
        player1Waves[i] = 0.01f;
 +
        break;
 +
      }
 +
    }
 +
  }
 +
  if (player2Push && !player2Pushed)
 +
  {
 +
    // On incremente la position de la corde
 +
    ropePosition -= INCREMENT;
 +
 
 +
    // On lance une nouvelle onde
 +
    for (int i = 0; i < 10; i++)
 +
    {
 +
      if (player2Waves[i] == 0.0f)
 +
      {
 +
        player2Waves[i] = 0.99f;
 +
        break;
 +
      }
 +
    }
 +
  }
 +
 
 +
  // Memorisation des etats des boutons
 +
  player1Pushed = player1Push;
 +
  player2Pushed = player2Push;
 +
 
 +
 
 +
 
 +
 
 +
  // On calcule la position lissee de la corde (displayedRopePosition correspond a la variable ropePosition avec un lissage supplementaire)
 +
  displayedRopePosition += (ropePosition - displayedRopePosition) * dt / ROPE_SMOOTH;
 +
 
 +
  // On regarde si player 1 a gagne
 +
  if (displayedRopePosition >= 1.0f)
 +
  {
 +
    lastWinner = PLAYER1;
 +
    gameState = START;
 +
    beginTimer = millis();
 +
 
 +
    ropePosition = 0.5f;
 +
    displayedRopePosition = 0.5f;
 +
 
 +
    FastLED.clear();
 +
    return;
 +
  }
 +
  // On regarde si player 2 a gagne
 +
  else if (displayedRopePosition <= 0.0f)
 +
  {
 +
    lastWinner = PLAYER2;
 +
    gameState = START;
 +
    beginTimer = millis();
 +
 
 +
    ropePosition = 0.5f;
 +
    displayedRopePosition = 0.5f;
 +
 
 +
    FastLED.clear();
 +
    return;
 +
  }
 +
 
 +
  // On propage les ondes
 +
  float dx = WAVE_SPEED * dt;
 +
 
 +
  for (int wave = 0; wave < 10; wave++)
 +
  {
 +
    // Ondes player 1
 +
    if (player1Waves[wave] != 0.0f)
 +
    {
 +
      player1Waves[wave] += dx;
 +
 
 +
      // Si toute l'onde depasse le point de la corde, on l'arrete
 +
      if (player1Waves[wave] - WAVE_LENGTH > displayedRopePosition)
 +
      {
 +
        player1Waves[wave] = 0.0f;
 +
      }
 +
    }
 +
 
 +
    // Ondes player 2
 +
    if (player2Waves[wave] != 0.0f)
 +
    {
 +
      player2Waves[wave] -= dx;
 +
 
 +
      // Si toute l'onde depasse le point de la corde, on l'arrete
 +
      if (player2Waves[wave] + WAVE_LENGTH < displayedRopePosition)
 +
      {
 +
        player2Waves[wave] = 0.0f;
 +
      }
 +
    }
 +
  }
 +
 
 +
  // On actualise la bande de leds
 +
  float ledLuminosity;
 +
  float ledPosition;
 +
 
 +
  FastLED.clear();
 +
 
 +
  // On commence par calculer le numero de la led correspondant a la position de la corde
 +
  int ropeLedPosition = NUM_LEDS * displayedRopePosition;
 +
 
 +
  // On dessine la zone du player 1
 +
  // Pour cela on calcule la luminosite led par led
 +
  for (int led = 0; led < ropeLedPosition; led++)
 +
  {
 +
    // La luminosite minimale d'une led est 10% de la luminosite max
 +
    ledLuminosity = 0.1f;
 +
    ledPosition = float(led) / float(NUM_LEDS);
 +
 
 +
    // Pour chaque onde, on ajoute la luminosite a la led
 +
    for (int wave = 0; wave < 10; wave++)
 +
    {
 +
      // Si l'onde n'est pas active ou si l'onde est avant la led, on n'ajoute aucune luminosite
 +
      if (player1Waves[wave] == 0.0f || player1Waves[wave] < ledPosition)
 +
        continue;
 +
 
 +
      // On ajoute de la luminosite de facon decroissante. plus l'onde est loin, moins on ajoute de luminosite.
 +
      ledLuminosity += max(0.0f, 0.9f - (player1Waves[wave] - ledPosition) / WAVE_LENGTH);
 +
    }
 +
    // La valeur maximale de luminosite est 1.0
 +
    if (ledLuminosity > 2.0f)
 +
      ledLuminosity = 2.0f;
 +
 
 +
    // On actualise la valeur de luminosite de la led
 +
    ledColor(led, PLAYER1_COLOR / int(2.0f / ledLuminosity) / 5);
 +
  }
 +
 
 +
  // On dessine la zone du player 2
 +
  for (int led = ropeLedPosition + 1; led < NUM_LEDS; led++)
 +
  {
 +
    // La luminosite minimale d'une led est 10% de la luminosite max
 +
    ledLuminosity = 0.1f;
 +
    ledPosition = float(led) / float(NUM_LEDS);
 +
 
 +
    // Pour chaque onde, on ajoute la luminosite a la led
 +
    for (int wave = 0; wave < 10; wave++)
 +
    {
 +
      // Si l'onde n'est pas active ou si l'onde est avant la led, on n'ajoute aucune luminosite
 +
      if (player2Waves[wave] == 0.0f || ledPosition > player2Waves[wave])
 +
        continue;
 +
 
 +
      // On ajoute de la luminosite de facon decroissante. plus l'onde est loin, moins on ajoute de luminosite.
 +
      ledLuminosity += max(0.0f, 0.9f - (player2Waves[wave] - ledPosition) / WAVE_LENGTH);
 +
    }
 +
    // La valeur maximale de luminosite est 1.0
 +
    if (ledLuminosity > 2.0f)
 +
      ledLuminosity = 2.0f;
 +
 
 +
    // On actualise la valeur de luminosite de la led
 +
    ledColor(led, PLAYER2_COLOR / int(1.0f / ledLuminosity) / 5);
 +
  }
 +
 
 +
  // On actualise la led correspondant a la position de la corde
 +
  ledColor(ropeLedPosition, BLANC);
 +
  FastLED.show();
 +
}
  
==Introduction==
 
  
éventuelle vidéo
 
==outil et matériel==
 
[[Fichier:AMOGUS.png|2000px]]
 
==fichiers à joindre==
 
code, ficher d'impression 3D, de découpe laser ou vinyle, ...
 
===Mettre du code Arduino===
 
<syntaxhighlight lang="Arduino" line>
 
#define PIN 9
 
#include <Arduino_GFX_Library.h>
 
  
 +
/****************************************************************
 +
  Cette fonction s'execute une fois lorsque la carte s'allume.
 +
****************************************************************/
 
void setup() {
 
void setup() {
   // put your setup code here, to run once:
+
   // Initialisation des LEDs
 +
  FastLED.addLeds<WS2812B, LED_PIN, GRB>(leds, NUM_LEDS);
 +
 
 +
  // Initialisations des boutons
 +
  pinMode(BUTTON1_PIN, INPUT_PULLUP);
 +
  pinMode(BUTTON2_PIN, INPUT_PULLUP);
 +
 
 +
  // Initialisation du haut parleur
 +
  pinMode(HAUT_PARLEUR_PIN, OUTPUT);
  
 +
  // COULEUR DES LEDS EN DEBUT DE PARTIE
 +
  FastLED.clear();
 +
  // Couleurs player 1
 +
  ledColor(PLAYER1, 0, PLAYER1_COLOR);
 +
  ledColor(PLAYER1, 1, PLAYER1_COLOR);
 +
  ledColor(PLAYER1, 2, PLAYER1_COLOR);
 +
  ledColor(PLAYER1, 3, PLAYER1_COLOR);
 +
  ledColor(PLAYER1, 4, PLAYER1_COLOR);
 +
 +
  // Couleurs player 2
 +
  ledColor(PLAYER2, 0, PLAYER2_COLOR);
 +
  ledColor(PLAYER2, 1, PLAYER2_COLOR);
 +
  ledColor(PLAYER2, 2, PLAYER2_COLOR);
 +
  ledColor(PLAYER2, 3, PLAYER2_COLOR);
 +
  ledColor(PLAYER2, 4, PLAYER2_COLOR);
 +
 +
  // On envoie les changements a la bande de leds
 +
  FastLED.show();
 +
 +
  // Initialisation du temps d'allumage
 +
  beginTimer = millis();
 
}
 
}
  
 +
/*************************************************************
 +
  Cette fonction s'execute en continue tout au long du jeu.
 +
*************************************************************/
 
void loop() {
 
void loop() {
  // put your main code here, to run repeatedly:
 
  
 +
  switch (gameState)
 +
  {
 +
    case START:
 +
      // Si un player a gagne, on affiche l'arc en ciel du cote du vainqueur
 +
      if (lastWinner == PLAYER1)
 +
      {
 +
        fill_rainbow(leds, NUM_LEDS / 2, counter++, 7);
 +
        FastLED.show();
 +
      }
 +
      else if (lastWinner == PLAYER2)
 +
      {
 +
        fill_rainbow(leds + NUM_LEDS / 2, NUM_LEDS / 2, counter++, 7);
 +
        FastLED.show();
 +
      }
 +
 +
      // On regarde si un temps minimim s'est ecoule et si un des boutons est appuye
 +
      if (millis() - beginTimer > 1000 && (digitalRead(BUTTON1_PIN) == LOW || digitalRead(BUTTON2_PIN) == LOW))
 +
      {
 +
        unsigned long pushBegin = millis();
 +
 +
        while (digitalRead(BUTTON1_PIN) == LOW || digitalRead(BUTTON2_PIN) == LOW);
 +
 +
        if (millis() - pushBegin < 1000)
 +
        {
 +
          gameState = PONG;
 +
        }
 +
        else
 +
        {
 +
          gameState = TAC;
 +
        }
 +
 +
        // On joue la note de musique
 +
        tone(HAUT_PARLEUR_PIN, PONG_SOUND, 100);
 +
 +
        // Initialisation de la varable lastMillis
 +
        lastMillis = millis();
 +
 +
        // Initialisation du temps de debut de jeu
 +
        beginTimer = millis();
 +
      }
 +
 +
      break;
 +
 +
    case PONG:
 +
      pong_loop();
 +
      break;
 +
 +
    case TAC:
 +
      tac_loop();
 +
      break;
 +
  }
 
}
 
}
 +
</syntaxhighlight>
 +
 +
La biblothèque FastLED est nécéssaire pour pouvoir faire fonctionner le programme.
 +
<br/>
 +
Pour l'installer il faut télécharger FastLED avec ce lien : https://github.com/FastLED/FastLED et le mettre dans le répertoire des bibliothèques d'Arduino. Et sur Arduino IDE avec celui-là : https://www.arduino.cc/en/main/software.
 +
<br/>
 +
Sur le ligociel, il faut chosir la bonne carte, le bon port de sortie et il suffit enfin de téléverser pour pouvoir charger le programme sur la carte.
 +
<br/>
 +
Et maintenant, pour pouvoir utiliser le jeu partout, il faut tout simplement utiliser une batterie (avec piles ou externe) et la brancher à la carte qui à été préalablement chargée avec le programme.
 +
 +
==Étapes de fabrication==
 +
Nous avons fait nos étapes dans cet ordre là car nous avons suivi les étapes dans le [[Wikidabrouillard]]
 +
Voici toutes les étapes de fabrication de notre projet :
 +
===Étape 1===
 +
Tout d'abord on se rend compte du matériel qu'on nous donne et on regarde les différentes étapes à suivre sur le Wikidébrouillard
 +
===Étape 2===
 +
On soude des fils électriques au ruban de LEDS et sur les pattes des interrupteurs
 +
<br/>
 +
[[Fichier:ruban_led.png|200px]]
 +
[[Fichier:bouton.jpg|100px]]
 +
 +
===Étape 2-1===
 +
En même temps, on construit le support sur lequel le jeu va être joué
 +
===Étape 3===
 +
On soude aussi les broches de support sur la carte Arduino
 +
===Étape 4===
 +
On réalise le câblage sur la plaquette qui nous a été fourni pour pouvoir tester le code
 +
<br/>
 +
[[Fichier:Schema.png]]
 +
 +
===Étape 5===
 +
Puis on commence à mettre tous nos composants sur la maquette réelle
 +
<br/>
 +
[[Fichier:board_pres.jpg|200px]]
 +
 +
===Étape 6===
 +
Ensuite, le jeu peut être utilisé !
  
</syntaxhighlight>
+
===Étape 7===
 +
On commence à créer notre produit final qui sera fait tout en bois
 +
 
 +
===Étape 8===
 +
Pour cela, on va venir couper une planche en bois, et les chutes serviront à faire le maintien de la planche.
 +
<br/>
 +
[[Fichier:final.jpg|200px]]
 +
 
 +
===Étape 9===
 +
Ensuite, on fait des trous pour faire passer les boutons d'arcade, vous pouvez le voir sur la photo ci-dessus.
 +
 
 +
===Étape 10===
 +
On en fait un aussi pour faire passer les fils connectés au ruban de LEDS
 +
 
 +
===Étape 11===
 +
On reconnecte tout le système sur notre maquette finale
 +
 
 +
===Étape 12===
 +
On colle notre BreadBoard au dos de notre planche pour qu'elle ne soit pas vue
 +
 
 +
===Étape 13===
 +
On colle aussi les câbles pour ne pas les vois tomber
 +
 
 +
===Étape 14===
 +
Pour ajouter un peu d'esthétique à notre projet, nous avons gravé à la découpeuse vinyle le titre de notre projet.*
 +
<br/>
 +
[[Fichier:GNOP.jpg|200px]]
  
==étapes de fabrication==
+
===Étape 15===
indiquer autant d'étape que nécessaire, chacune illustrée par des images (phot, dessins, ...)
+
Le jeu peut être pleinement apprécié !!
  
===étape 1===
+
==Problèmes rencontrés==
===étape 2===
+
Nous avons confronté un certain nombre de problèmes durant la conception de ce projet.
===étape ...===
+
<br/>
===troubleshouting===
+
Une fois que nous avions fini le projet sur la première maquette, le téléversement ne se faisait pas, sur Arduino IDE, dans l'onglet Tools>Processor il fallait prendre la rubrique "Old Bootloader" et nous étions sur celui de base, mais si l'un ne marche pas c'est que l'autre fonctionne, nous avons donc réussi à résoudre ce problème.
quelles sont difficultés, les problèmes, quelles sont les solutions, les trucs et astuces pour que ça marche ?
+
<br/>
 +
Nous avons aussi également essayé d'incorporer un haut-parleur classique pour faire du son dès qu'un bouton est appuyé, mais le son n'était clairement pas assez fort donc on a voulu utilisé un amplificateur mais nous n'avons pas réussi à bien le brancher. On a donc opter d'utiliser un buzzer pour que le son soit plus fort pour être entendu.
 +
<br/>
 +
Une des broches de notre carte n'a plus été fonctionnel, nous avons mis du temps à comprendre qu'un de nos problèmes venait de là, on a donc tout simplement changer de broche.
 +
<br/>
 +
Nous utilisions au début, une batterie à pile, mais celle-ci ne délivrait pas assez de puissance pour faire fonctionner la carte et le programme, nous avons changé cette batterie et opter pour une batterie externe rechargeable qui, elle, convenait parfaitement avec le système.
  
 
==Sources et documentation complémentaire==
 
==Sources et documentation complémentaire==
 +
[[Catégorie:Enib2024]]

Version actuelle datée du 25 janvier 2024 à 15:25

Titre de la fiche expérience :

Description

Le projet est de fabriquer un jeu ludique à l'aide d'une carte Arduino, notre jeu est le D1-Pong. Inspiré du sport du tennis de table, il reprend le même principe mais avec des LEDS, la balle se déplace sur les LEDS et dès qu'elle arrive à une extrémité, le joueur en question appuie sur son bouton pour que la balle parte dans l'autre sens et ainsi de suite.
​ Voici notre équipe :
Arthur : Arthur.jpg Laouen : Laouen.jpg Ewen 1 : Ramzi.jpg Ewen 2 : (parti au combat) Virgule.jpg Alban : (jamais vu) Alban.jpg

Outil et matériel

Pour fabriquer ce jeu, nous avons eut besoin de :

  • Carte Arduino Nano
  • 2 boutons d'arcade
  • Carton
  • Fils électriques
  • Batterie externe
  • Ruban de LEDS
  • Haut-parleur
  • Bois


Nous nous sommes servis de plusieurs outils :

  • Fer à souder
  • Pistolet à colle
  • Cutter
  • Scie à bois
  • Lime à bois
  • Découpeuse Vinyle

Code Arduino

  1  
  2 /*
  3    Code de fonctionnement pour le jeu PONG.
  4    Par les petits debrouillards.
  5 */
  6 
  7 #include <FastLED.h>
  8 
  9 // Definition des couleurs
 10 const CRGB NOIR  = CRGB(0,   0,   0  ); //Création d'une constante de type CRGB de couleur noire
 11 const CRGB BLANC = CRGB(255, 255, 255); //Création d'une constante de type CRGB de couleur blanche
 12 const CRGB ROUGE = CRGB(255, 0,   0  ); //Création d'une constante de type CRGB de couleur rouge
 13 const CRGB VERT  = CRGB(0,   255, 0  ); //Création d'une constante de type CRGB de couleur verte
 14 const CRGB BLEU  = CRGB(0,   0,   255); //Création d'une constante de type CRGB de couleur bleue
 15 const CRGB JAUNE = CRGB(255, 255, 0  ); //Création d'une constante de type CRGB de couleur jaune
 16 const CRGB ROSE  = CRGB(255, 0,   255); //Création d'une constante de type CRGB de couleur rose
 17 const CRGB CYAN  = CRGB(0,   255, 255); //Création d'une constante de type CRGB de couleur cyan
 18 
 19 // Definition des notes de musique
 20 const int PONG_SOUND = 250; //380
 21 const int LOOSE_SOUND = 180;
 22 
 23 
 24 /******************************
 25     PARAMETRES DE BRANCHEMENTS
 26  ******************************/
 27 
 28 const int LED_PIN = 8;          // Numero de branchement de la bande de LEDs
 29 const int BUTTON1_PIN = 2;      // Numero de branchement du premier bouton
 30 const int BUTTON2_PIN = 4;      // Numero de branchement du deuxieme bouton
 31 const int HAUT_PARLEUR_PIN = 5; // Numero de branchement du haut parleur (optionnel)
 32 
 33 
 34 /***********************
 35     PARAMETRES GENERAUX
 36  ***********************/
 37 const int   NUM_LEDS = 60;            // Nombre de LEDs sur la bande
 38 const CRGB  PLAYER1_COLOR = VERT;     // Couleur Player 1
 39 const CRGB  PLAYER2_COLOR = ROUGE;    // Couleur Player 2
 40 
 41 
 42 /***********************
 43      PARAMETRES PONG
 44  ***********************/
 45 const float BALL_SPEED = 0.5;   // Vitesse de la balle
 46 const float ACCELERATION = 9;   // Accélération de la balle a chaque tir, si ACCELERATION = 10 on augmente la vitesse de 10 pourcent a chaque tir
 47 const int   HIT_ZONE = 8;       // Nombre de LED pendant lesquelles on peut renvoyer la balle
 48 const int   MAX_SCORE = 3;      // Score maximum avant la fin du jeu
 49 
 50 const CRGB  BALL_COLOR = BLANC;      // Couleur de la balle
 51 
 52 /*******************************
 53      PARAMETRES TIR A LA CORDE
 54  *******************************/
 55 const float INCREMENT = 0.05;   // De combien avance la corde lorsqu'on appuie sur le bouton
 56 const float ROPE_SMOOTH = 1.0;  // Paramètre servant a lisser la position de la corde
 57 
 58 const float WAVE_LENGTH = 0.2;  // Taille des ondes
 59 const float WAVE_SPEED =  1.0;  // Vitesse des ondes
 60 
 61 
 62 
 63 /******************************
 64       VARIABLES GENERALES
 65  ******************************/
 66 // Players
 67 enum Player
 68 {
 69   PERSONNE,
 70   PLAYER1,
 71   PLAYER2
 72 };
 73 
 74 // Etats du jeu
 75 enum GameState
 76 {
 77   START,
 78   PONG,   // Mode pong
 79   TAC     // Mode tir a la corde
 80 };
 81 
 82 unsigned long lastMillis = 0;
 83 unsigned long beginTimer = 0;
 84 unsigned int counter = 0;
 85 
 86 Player player = PLAYER1; // Prochain joueur a appuyer sur son bouton
 87 Player lastWinner = PERSONNE;
 88 
 89 CRGB leds[NUM_LEDS];
 90 GameState gameState = START;
 91 
 92 
 93 /**********************************************
 94       FONCTIONS DE FONCTIONNEMENT GENERALES
 95  **********************************************/
 96 
 97 // Fonction permettant de changer la couleur d'une LED relativement au player 1 ou 2
 98 void ledColor(Player player, int pos, CRGB color)
 99 {
100   if (player == PLAYER1)
101   {
102     leds[pos] = color;
103   }
104   else // player == PLAYER2
105   {
106     leds[NUM_LEDS - pos - 1] = color;
107   }
108 }
109 
110 // Fonction permettant de changer la couleur d'une LED
111 void ledColor(int pos, CRGB color)
112 {
113   leds[pos] = color;
114 }
115 
116 /*********************************************
117       VARIABLES DE FONCTIONNEMENT DU PONG
118  *********************************************/
119 float ballSpeed = BALL_SPEED;  // Vitesse de la balle
120 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)
121 int player1Score = 0;   // Score du player 1
122 int player2Score = 0;   // Score du player 2
123 
124 /**********************************************
125       FONCTIONS DE FONCTIONNEMENT DU PONG
126  **********************************************/
127 // Fonction servant a afficher les scores
128 void showScore()
129 {
130   // On commence par effacer toutes les couleurs de led
131   FastLED.clear();
132 
133   // On allume le nombre de led correspondant au score du player 1
134   for (int i = 0; i < player1Score; i++)
135   {
136     ledColor(PLAYER1, NUM_LEDS / 2 - (i + 1), PLAYER1_COLOR);
137   }
138 
139   // On allume le nombre de led correspondant au score du player 2
140   for (int i = 0; i < player2Score; i++)
141   {
142     ledColor(PLAYER2, NUM_LEDS / 2 - (i + 1), PLAYER2_COLOR);
143   }
144 
145   // On envoie les nouvelles couleurs a la bande de led
146   FastLED.show();
147 
148   // On fait clignotter trois fois
149   if (lastWinner == PLAYER1)
150   {
151     for (int i = 0; i < 3; i++)
152     {
153       // On eteint la derniere LED pendant 0.5s
154       delay(500);
155       ledColor(PLAYER1, NUM_LEDS / 2 - player1Score, NOIR);
156       FastLED.show();
157 
158       // On allume la derniere LED pendant 0.5s
159       delay(500);
160       ledColor(PLAYER1, NUM_LEDS / 2 - player1Score, PLAYER1_COLOR);
161       FastLED.show();
162     }
163   }
164   else // lastWinner == PLAYER2
165   {
166     for (int i = 0; i < 3; i++)
167     {
168       // On eteint la derniere LED pendant 0.5s
169       delay(500);
170       ledColor(PLAYER2, NUM_LEDS / 2 - player2Score, NOIR);
171       FastLED.show();
172 
173       // On allume la derniere LED pendant 0.5s
174       delay(500);
175       ledColor(PLAYER2, NUM_LEDS / 2 - player2Score, PLAYER2_COLOR);
176       FastLED.show();
177     }
178   }
179 
180   // Si la partie est terminee on va a l'affichage de fin
181   if (player1Score == MAX_SCORE || player2Score == MAX_SCORE)
182   {
183     gameState = START;
184 
185     // On reinitialise les scores
186     player1Score = 0;
187     player2Score = 0;
188 
189     // On reinitialise la vitesse
190     ballSpeed = BALL_SPEED;
191 
192     // On reinitialise les leds
193     FastLED.clear();
194   }
195   // Sinon on reprend le jeu
196   else
197   {
198     gameState = PONG;
199     ballSpeed = BALL_SPEED;
200   }
201 }
202 
203 
204 /***************************************
205       FONCTION PRINCIPALE DU PONG
206  ***************************************/
207 void pong_loop()
208 {
209   // Calcul du temps ecoule entre deux boucles
210   unsigned long currentMillis = millis();
211 
212   // On calcule le numero de la LED allumee
213   int ballLed = ballPosition * NUM_LEDS;
214 
215   // On s'assure que la position de la balle ne depasse pas la taille de la bande de LED
216   ballLed = min(ballLed, NUM_LEDS - 1);
217 
218   // On regarde qui est en train de jouer
219   if (player == PLAYER1)
220   {
221     // On regarde si le player a appuye sur son bouton et si le delai de debut de jeu est passe
222     if (digitalRead(BUTTON1_PIN) == LOW && currentMillis - beginTimer > 500)
223     {
224       // Si la balle est hors de la zone de tir, l'autre player marque un point
225       if (ballLed >= HIT_ZONE)
226       {
227         player2Score += 1;
228         lastWinner = PLAYER2;
229         ballPosition = 0;
230 
231         // On joue le son de defaite
232         tone(HAUT_PARLEUR_PIN, LOOSE_SOUND, 800);
233 
234         // On passe en mode affichage des scores
235         showScore();
236 
237         // C'est a l'autre player de jouer
238         player = PLAYER2;
239 
240         // Actualisation de la variable lastMillis
241         lastMillis = millis();
242       }
243       else
244       {
245         // On accelere la balle
246         ballSpeed *= 1.0 + ACCELERATION / 100;
247 
248         // C'est a l'autre player de jouer
249         player = PLAYER2;
250 
251         // On joue la note de musique
252         tone(HAUT_PARLEUR_PIN, PONG_SOUND, 100);
253       }
254 
255       return;
256     }
257 
258     // On fait avancer la balle
259     ballPosition -= ballSpeed * (currentMillis - lastMillis) * 0.001f;
260 
261     // On regarde si la balle est sortie de la zone
262     if (ballPosition < 0.0f)
263     {
264       // Si oui le player 2 marque un point
265       player2Score += 1;
266       lastWinner = PLAYER2;
267       ballPosition = 0;
268 
269       // On joue le son de defaite
270       tone(HAUT_PARLEUR_PIN, LOOSE_SOUND, 800);
271 
272       // On passe en mode affichage des scores
273       showScore();
274 
275       // C'est a l'autre player de jouer
276       player = PLAYER2;
277 
278       // Actualisation de la variable lastMillis
279       lastMillis = millis();
280       return;
281     }
282   }
283   else // player == PLAYER2
284   {
285     // On regarde si le player a appuye sur son bouton et si le delai de debut de jeu est passe
286     if (digitalRead(BUTTON2_PIN) == LOW && currentMillis - beginTimer > 500)
287     {
288       // Si la balle est hors de la zone de tir, l'autre player marque un point
289       if (ballLed < NUM_LEDS - HIT_ZONE)
290       {
291         player1Score += 1;
292         lastWinner = PLAYER1;
293         ballPosition = 1;
294 
295         // On joue le son de defaite
296         tone(HAUT_PARLEUR_PIN, LOOSE_SOUND, 800);
297 
298         // On passe en mode affichage des scores
299         showScore();
300 
301         // C'est a l'autre player de jouer
302         player = PLAYER1;
303 
304         // Actualisation de la variable lastMillis
305         lastMillis = millis();
306       }
307       else
308       {
309         // On accelere la balle
310         ballSpeed *= 1.1;
311 
312         // C'est a l'autre player de jouer
313         player = PLAYER1;
314 
315         // On joue la note de musique
316         tone(HAUT_PARLEUR_PIN, PONG_SOUND, 100);
317       }
318 
319       return;
320     }
321 
322     // On fait avancer la balle dans l'autre sens
323     ballPosition += ballSpeed * (currentMillis - lastMillis) * 0.001f;
324 
325     // On regarde si la balle est sortie de la zone
326     if (ballPosition >= 1)
327     {
328       // Si oui le player 1 marque un point
329       player1Score += 1;
330       lastWinner = PLAYER1;
331       ballPosition = 1;
332 
333       // On joue le son de defaite
334       tone(HAUT_PARLEUR_PIN, LOOSE_SOUND, 800);
335 
336       // On passe en mode affichage des scores
337       showScore();
338       // C'est a l'autre player de jouer
339       player = PLAYER1;
340 
341       // Actualisation de la variable lastMillis
342       lastMillis = millis();
343       return;
344     }
345   }
346 
347   ///// AFFICHAGE BANDE DE LEDs /////
348   // Premierement on efface toutes les couleurs precedentes
349   FastLED.clear();
350 
351   // Ensuite on allume faiblement les LEDs correspondant a la zone de chaque cote
352   for (int i = 0; i < HIT_ZONE; i++)
353   {
354     // On allume de chaque cote
355     ledColor(PLAYER1, i, PLAYER1_COLOR / 10);  // On divise la couleur par 10 pour la rendre 10 fois moins puissante
356     ledColor(PLAYER2, i, PLAYER2_COLOR / 10);
357   }
358 
359   // Ensuite on allume faiblement les LEDs correspondant aux scores
360   // Pour le player 1
361   for (int i = 0; i < player1Score; i++)
362   {
363     ledColor(PLAYER1, NUM_LEDS / 2 - (i + 1), PLAYER1_COLOR / 15);
364   }
365   // Pour le player 2
366   for (int i = 0; i < player2Score; i++)
367   {
368     ledColor(PLAYER2, NUM_LEDS / 2 - (i + 1), PLAYER2_COLOR / 15);
369   }
370 
371   // Ensuite on actualise la position de la balle
372   // On donne la couleur de la led en fonction de si la balle est dans la zone d'un player ou non
373 
374   // Si la balle est dans le camp d'un des player, elle est rouge.
375   if (ballLed < HIT_ZONE || ballLed >= NUM_LEDS - HIT_ZONE)
376   {
377     ledColor(ballLed, ROUGE);
378   }
379   // Si elle en est proche, elle est jaune
380   else if (ballLed < 2 * HIT_ZONE || ballLed >= NUM_LEDS - 2 * HIT_ZONE)
381   {
382     ledColor(ballLed, JAUNE);
383   }
384   // Sinon la balle a sa couleur par defaut
385   else
386   {
387     ledColor(ballLed, BALL_COLOR);
388   }
389 
390   // On envoie la couleur des leds a la bande de leds
391   FastLED.show();
392 
393   // On actualise la variable lastMillis pour la boucle suivante
394   lastMillis = currentMillis;
395 }
396 
397 
398 
399 /*******************************************************
400       VARIABLES DE FONCTIONNEMENT DU TIR A LA CORDE
401  *******************************************************/
402 float ropePosition = 0.5;           // Position non lissee de la corde
403 float displayedRopePosition = 0.5;  // Position lissee de la corde
404 bool player1Pushed = false;
405 bool player2Pushed = false;
406 
407 float player1Waves[10] = { 0 };
408 float player2Waves[10] = { 0 };
409 
410 /***********************************************
411       FONCTION PRINCIPALE DU TIR A LA CORDE
412  ***********************************************/
413 void tac_loop()
414 {  
415   // Calcul des temps
416   unsigned long ms = millis();
417   float dt = (ms - lastMillis) * 0.001f;
418   lastMillis = ms;
419 
420   // Si moins d'une seconde s'est ecoule depuis le debut, on ne fait rien (pour eviter d'appuyer sans faire expres)
421   if (ms - beginTimer < 1000)
422     return;
423 
424   bool player1Push = !digitalRead(BUTTON1_PIN);
425   bool player2Push = !digitalRead(BUTTON2_PIN);
426 
427   if (player1Push && !player1Pushed)
428   {
429     // On incremente la position de la corde
430     ropePosition += INCREMENT;
431 
432     // On lance une nouvelle onde
433     for (int i = 0; i < 10; i++)
434     {
435       if (player1Waves[i] == 0.0f)
436       {
437         //player1Waves[i] = WAVE_SPEED * dt;
438         player1Waves[i] = 0.01f;
439         break;
440       }
441     }
442   }
443   if (player2Push && !player2Pushed)
444   {
445     // On incremente la position de la corde
446     ropePosition -= INCREMENT;
447 
448     // On lance une nouvelle onde
449     for (int i = 0; i < 10; i++)
450     {
451       if (player2Waves[i] == 0.0f)
452       {
453         player2Waves[i] = 0.99f;
454         break;
455       }
456     }
457   }
458 
459   // Memorisation des etats des boutons
460   player1Pushed = player1Push;
461   player2Pushed = player2Push;
462 
463 
464 
465 
466   // On calcule la position lissee de la corde (displayedRopePosition correspond a la variable ropePosition avec un lissage supplementaire)
467   displayedRopePosition += (ropePosition - displayedRopePosition) * dt / ROPE_SMOOTH;
468 
469   // On regarde si player 1 a gagne
470   if (displayedRopePosition >= 1.0f)
471   {
472     lastWinner = PLAYER1;
473     gameState = START;
474     beginTimer = millis();
475 
476     ropePosition = 0.5f;
477     displayedRopePosition = 0.5f;
478 
479     FastLED.clear();
480     return;
481   }
482   // On regarde si player 2 a gagne
483   else if (displayedRopePosition <= 0.0f)
484   {
485     lastWinner = PLAYER2;
486     gameState = START;
487     beginTimer = millis();
488 
489     ropePosition = 0.5f;
490     displayedRopePosition = 0.5f;
491 
492     FastLED.clear();
493     return;
494   }
495 
496   // On propage les ondes
497   float dx = WAVE_SPEED * dt;
498 
499   for (int wave = 0; wave < 10; wave++)
500   {
501     // Ondes player 1
502     if (player1Waves[wave] != 0.0f)
503     {
504       player1Waves[wave] += dx;
505 
506       // Si toute l'onde depasse le point de la corde, on l'arrete
507       if (player1Waves[wave] - WAVE_LENGTH > displayedRopePosition)
508       {
509         player1Waves[wave] = 0.0f;
510       }
511     }
512 
513     // Ondes player 2
514     if (player2Waves[wave] != 0.0f)
515     {
516       player2Waves[wave] -= dx;
517 
518       // Si toute l'onde depasse le point de la corde, on l'arrete
519       if (player2Waves[wave] + WAVE_LENGTH < displayedRopePosition)
520       {
521         player2Waves[wave] = 0.0f;
522       }
523     }
524   }
525 
526   // On actualise la bande de leds
527   float ledLuminosity;
528   float ledPosition;
529 
530   FastLED.clear();
531 
532   // On commence par calculer le numero de la led correspondant a la position de la corde
533   int ropeLedPosition = NUM_LEDS * displayedRopePosition;
534 
535   // On dessine la zone du player 1
536   // Pour cela on calcule la luminosite led par led
537   for (int led = 0; led < ropeLedPosition; led++)
538   {
539     // La luminosite minimale d'une led est 10% de la luminosite max
540     ledLuminosity = 0.1f;
541     ledPosition = float(led) / float(NUM_LEDS);
542 
543     // Pour chaque onde, on ajoute la luminosite a la led
544     for (int wave = 0; wave < 10; wave++)
545     {
546       // Si l'onde n'est pas active ou si l'onde est avant la led, on n'ajoute aucune luminosite
547       if (player1Waves[wave] == 0.0f || player1Waves[wave] < ledPosition)
548         continue;
549 
550       // On ajoute de la luminosite de facon decroissante. plus l'onde est loin, moins on ajoute de luminosite.
551       ledLuminosity += max(0.0f, 0.9f - (player1Waves[wave] - ledPosition) / WAVE_LENGTH);
552     }
553     // La valeur maximale de luminosite est 1.0
554     if (ledLuminosity > 2.0f)
555       ledLuminosity = 2.0f;
556 
557     // On actualise la valeur de luminosite de la led
558     ledColor(led, PLAYER1_COLOR / int(2.0f / ledLuminosity) / 5);
559   }
560 
561   // On dessine la zone du player 2
562   for (int led = ropeLedPosition + 1; led < NUM_LEDS; led++)
563   {
564     // La luminosite minimale d'une led est 10% de la luminosite max
565     ledLuminosity = 0.1f;
566     ledPosition = float(led) / float(NUM_LEDS);
567 
568     // Pour chaque onde, on ajoute la luminosite a la led
569     for (int wave = 0; wave < 10; wave++)
570     {
571       // Si l'onde n'est pas active ou si l'onde est avant la led, on n'ajoute aucune luminosite
572       if (player2Waves[wave] == 0.0f || ledPosition > player2Waves[wave])
573         continue;
574 
575       // On ajoute de la luminosite de facon decroissante. plus l'onde est loin, moins on ajoute de luminosite.
576       ledLuminosity += max(0.0f, 0.9f - (player2Waves[wave] - ledPosition) / WAVE_LENGTH);
577     }
578     // La valeur maximale de luminosite est 1.0
579     if (ledLuminosity > 2.0f)
580       ledLuminosity = 2.0f;
581 
582     // On actualise la valeur de luminosite de la led
583     ledColor(led, PLAYER2_COLOR / int(1.0f / ledLuminosity) / 5);
584   }
585 
586   // On actualise la led correspondant a la position de la corde
587   ledColor(ropeLedPosition, BLANC);
588   FastLED.show();
589 }
590 
591 
592 
593 /****************************************************************
594    Cette fonction s'execute une fois lorsque la carte s'allume.
595  ****************************************************************/
596 void setup() {
597   // Initialisation des LEDs
598   FastLED.addLeds<WS2812B, LED_PIN, GRB>(leds, NUM_LEDS);
599 
600   // Initialisations des boutons
601   pinMode(BUTTON1_PIN, INPUT_PULLUP);
602   pinMode(BUTTON2_PIN, INPUT_PULLUP);
603 
604   // Initialisation du haut parleur
605   pinMode(HAUT_PARLEUR_PIN, OUTPUT);
606 
607   // COULEUR DES LEDS EN DEBUT DE PARTIE
608   FastLED.clear();
609   // Couleurs player 1
610   ledColor(PLAYER1, 0, PLAYER1_COLOR);
611   ledColor(PLAYER1, 1, PLAYER1_COLOR);
612   ledColor(PLAYER1, 2, PLAYER1_COLOR);
613   ledColor(PLAYER1, 3, PLAYER1_COLOR);
614   ledColor(PLAYER1, 4, PLAYER1_COLOR);
615 
616   // Couleurs player 2
617   ledColor(PLAYER2, 0, PLAYER2_COLOR);
618   ledColor(PLAYER2, 1, PLAYER2_COLOR);
619   ledColor(PLAYER2, 2, PLAYER2_COLOR);
620   ledColor(PLAYER2, 3, PLAYER2_COLOR);
621   ledColor(PLAYER2, 4, PLAYER2_COLOR);
622 
623   // On envoie les changements a la bande de leds
624   FastLED.show();
625 
626   // Initialisation du temps d'allumage
627   beginTimer = millis();
628 }
629 
630 /*************************************************************
631    Cette fonction s'execute en continue tout au long du jeu.
632  *************************************************************/
633 void loop() {
634 
635   switch (gameState)
636   {
637     case START:
638       // Si un player a gagne, on affiche l'arc en ciel du cote du vainqueur
639       if (lastWinner == PLAYER1)
640       {
641         fill_rainbow(leds, NUM_LEDS / 2, counter++, 7);
642         FastLED.show();
643       }
644       else if (lastWinner == PLAYER2)
645       {
646         fill_rainbow(leds + NUM_LEDS / 2, NUM_LEDS / 2, counter++, 7);
647         FastLED.show();
648       }
649 
650       // On regarde si un temps minimim s'est ecoule et si un des boutons est appuye
651       if (millis() - beginTimer > 1000 && (digitalRead(BUTTON1_PIN) == LOW || digitalRead(BUTTON2_PIN) == LOW))
652       {
653         unsigned long pushBegin = millis();
654 
655         while (digitalRead(BUTTON1_PIN) == LOW || digitalRead(BUTTON2_PIN) == LOW);
656 
657         if (millis() - pushBegin < 1000)
658         {
659           gameState = PONG;
660         }
661         else
662         {
663           gameState = TAC;
664         }
665 
666         // On joue la note de musique
667         tone(HAUT_PARLEUR_PIN, PONG_SOUND, 100);
668 
669         // Initialisation de la varable lastMillis
670         lastMillis = millis();
671 
672         // Initialisation du temps de debut de jeu
673         beginTimer = millis();
674       }
675 
676       break;
677 
678     case PONG:
679       pong_loop();
680       break;
681 
682     case TAC:
683       tac_loop();
684       break;
685   }
686 }

La biblothèque FastLED est nécéssaire pour pouvoir faire fonctionner le programme.
Pour l'installer il faut télécharger FastLED avec ce lien : https://github.com/FastLED/FastLED et le mettre dans le répertoire des bibliothèques d'Arduino. Et sur Arduino IDE avec celui-là : https://www.arduino.cc/en/main/software.
Sur le ligociel, il faut chosir la bonne carte, le bon port de sortie et il suffit enfin de téléverser pour pouvoir charger le programme sur la carte.
Et maintenant, pour pouvoir utiliser le jeu partout, il faut tout simplement utiliser une batterie (avec piles ou externe) et la brancher à la carte qui à été préalablement chargée avec le programme.

Étapes de fabrication

Nous avons fait nos étapes dans cet ordre là car nous avons suivi les étapes dans le Wikidabrouillard Voici toutes les étapes de fabrication de notre projet :

Étape 1

Tout d'abord on se rend compte du matériel qu'on nous donne et on regarde les différentes étapes à suivre sur le Wikidébrouillard

Étape 2

On soude des fils électriques au ruban de LEDS et sur les pattes des interrupteurs
Ruban led.png Bouton.jpg

Étape 2-1

En même temps, on construit le support sur lequel le jeu va être joué

Étape 3

On soude aussi les broches de support sur la carte Arduino

Étape 4

On réalise le câblage sur la plaquette qui nous a été fourni pour pouvoir tester le code
Schema.png

Étape 5

Puis on commence à mettre tous nos composants sur la maquette réelle
Board pres.jpg

Étape 6

Ensuite, le jeu peut être utilisé !

Étape 7

On commence à créer notre produit final qui sera fait tout en bois

Étape 8

Pour cela, on va venir couper une planche en bois, et les chutes serviront à faire le maintien de la planche.
Final.jpg

Étape 9

Ensuite, on fait des trous pour faire passer les boutons d'arcade, vous pouvez le voir sur la photo ci-dessus.

Étape 10

On en fait un aussi pour faire passer les fils connectés au ruban de LEDS

Étape 11

On reconnecte tout le système sur notre maquette finale

Étape 12

On colle notre BreadBoard au dos de notre planche pour qu'elle ne soit pas vue

Étape 13

On colle aussi les câbles pour ne pas les vois tomber

Étape 14

Pour ajouter un peu d'esthétique à notre projet, nous avons gravé à la découpeuse vinyle le titre de notre projet.*
GNOP.jpg

Étape 15

Le jeu peut être pleinement apprécié !!

Problèmes rencontrés

Nous avons confronté un certain nombre de problèmes durant la conception de ce projet.
Une fois que nous avions fini le projet sur la première maquette, le téléversement ne se faisait pas, sur Arduino IDE, dans l'onglet Tools>Processor il fallait prendre la rubrique "Old Bootloader" et nous étions sur celui de base, mais si l'un ne marche pas c'est que l'autre fonctionne, nous avons donc réussi à résoudre ce problème.
Nous avons aussi également essayé d'incorporer un haut-parleur classique pour faire du son dès qu'un bouton est appuyé, mais le son n'était clairement pas assez fort donc on a voulu utilisé un amplificateur mais nous n'avons pas réussi à bien le brancher. On a donc opter d'utiliser un buzzer pour que le son soit plus fort pour être entendu.
Une des broches de notre carte n'a plus été fonctionnel, nous avons mis du temps à comprendre qu'un de nos problèmes venait de là, on a donc tout simplement changer de broche.
Nous utilisions au début, une batterie à pile, mais celle-ci ne délivrait pas assez de puissance pour faire fonctionner la carte et le programme, nous avons changé cette batterie et opter pour une batterie externe rechargeable qui, elle, convenait parfaitement avec le système.

Sources et documentation complémentaire