Jeu de pong 1D #
Ce TP est basé sur un Arduino Nano, et une bande de 72 LEDs RGB pilotées individuellement (WS2812B). Le montage contient également 2 boutons type borne d’arcade.
Les deux boutons permettent de relier les broches 2 et 3 à la masse.
La bande de LEDs est pilotable à l’aide du module FastLED
. La broche qui
permet le pilotage est la broche 9.
Objectifs #
On pourra librement se fixer des objectifs utilisant le matériel à disposition. Une proposition est un jeu type Pong. Une navette est renvoyée par une pression sur le bouton, vers le joueur adverse. Pour renvoyer la navette, le bouton doit être pressé précisément lorsque la navette est suffisamment proche du joueur, sans toutefois avoir atteint sa cible. On peut matérialiser ce moment par un changement de couleur de la navette. La vitesse de la navette pourra augmenter au fur et à mesure de la partie.
Éléments techniques #
Utilisation de l’Arduino Nano #
On peut détecter le port sur lequel est connecté l’Arduino Nano (sous Windows) avec le gestionnaire de périphériques :
Pour uploader le code, utilisez ces réglages (avec le port approprié) :
Pilotage du ruban de LEDs #
- Homepage du module FastLED
- Doc WS2812B
Le pilotage du ruban de LEDs se fait avec le module FastLED
. Pour utiliser ce
module, on déclare un tableau contenant autant d’éléments qu’il y a de LEDs.
Chaque élément de ce tableau contiendra la couleur de la LED associée. Une fois
le tableau prêt, on demande au module de mettre à jour l’état des LEDs.
Veillez à ce que la bibliothèque FastLED soit bien installée :
Le code suivant permet d’allumer une LED au hasard, dans uen couleur aléatoire.
#include "FastLED.h"
// Nombre de LEDs sur la bande
#define NUM_LEDS 72
// broche de données du ruban de leds
#define DATA_PIN 9
// Tableau contenant l'état des LEDs
CRGB leds[NUM_LEDS];
// ========================================================
void setup() {
Serial.begin(115200);
// Association du tableau au ruban de LEDs
LEDS.addLeds<WS2812B, DATA_PIN, GRB>(leds, NUM_LEDS);
// Mise à 0 de tout le tableau
memset(leds, 0, NUM_LEDS * sizeof(struct CRGB));
Serial.println("Go");
}
int random_led() {
int num;
// mise à 0 du tableau (pas toujours nécessaire)
memset(leds, 0, NUM_LEDS * sizeof(struct CRGB));
// choix d'un numéro de LED
num = rand() % NUM_LEDS;
// chaque composante est un entier sur un octet
leds[num].r = rand() % 206 + 50;
leds[num].g = rand() % 206 + 50;
leds[num].b = rand() % 206 + 50;
// Mise à jour des leds
LEDS.show();
return num;
}
void loop()
{
int num;
num = random_led();
Serial.print("LED : ");
Serial.println(num);
delay(200);
}
Gestion des interruptions #
Gestion des interruptions sur le site officiel Arduino.
Si on souhaite que l’appui sur le bouton puisse interrompre tout calcul en cours, il faudra gérer les interruptions. On peut par exemple provoquer l’exécution d’une fonction d’interruption sur frond descendant de la broche 2 ainsi :
volatile int compteur = 0;
void setup() {
Serial.begin(115200);
// Activation de la résistance de PULLUP
// => niveau haut si le bouton est relaché, bas s'il est pressé
pinMode(2,INPUT_PULLUP);
// Interruption sur front descendant de la broche 2
attachInterrupt(digitalPinToInterrupt(2), clic_bouton, FALLING);
Serial.println("Go...");
}
void clic_bouton() {
// Serial.println("*");
compteur++;
}
void loop()
{
Serial.println("Waiting 10 s");
delay(10000);
Serial.print("Compteur : ");
Serial.println(compteur);
}
Attention, dans une fonction d’interruption, tout n’est pas permis :
- le traitement doit être le plus court possible
- les fonctions horaires ne sont pas disponibles
- les variables accédées et modifiées doivent être déclarées
volatile
Au passage, le code vous permettra d’expérimenter sur les problèmes de rebond (un seul appui souhaité sur le bouton, mais plusieurs appuis détectés).