Vous avez certainement, vous aussi, un vieux chapeau qui traîne chez vous. Le mien, c’était un cadeau publicitaire. Il m’avait été offert (il y a quelques années), pour l’anniversaire d’un camping en Espagne. Pendant la fête tout le monde avait le même. C’était très bien, il y avait de la musique et de la sangria…

Mais depuis je n’ai plus jamais eu l’occasion de le porter…
Alors, pourquoi ne pas lui donner une seconde vie ?

Pour cela, il vous faut :
- 1 Arduino compact (comme le Nano)
- 1 ruban de 30 LED Neopixels (1m)
- 1 boitier de 3 piles 1,5 V (ou de 4 piles rechargeables de 1,2V)
- 1 interrupteur
- Du fil électriques
- 1 fer à souder et de l’étain
- De la colle (pistolet à colle chaude)

Si vous utilisez un clone d’Arduino Nano (commandé en Chine), vous n’aurez pas de scrupules à souder directement les fils dans les connecteurs, puisse qu’il ne coûte que quelques euros. En revanche, s’il s’agit d’un modèle plus coûteux, utilisez des connecteurs afin de pouvoir le réutiliser ensuite pour d’autres projets.
Pour faciliter les branchements, vous pouvez alimenter l’Arduino par les connecteurs du dessus (normalement destinés à flasher le firmware). Sinon, vous pouvez aussi brancher le module de LED directement sur l’alimentation.
Si vous rencontrez des problèmes de rebond (l’Arduino détecte plusieurs appuis, alors que l’on n’a pressé une seule fois le bouton), ajoutez un condensateur de 100 nF environ, entre les pattes du bouton. Je n’ai pas ajouté de résistance de tirage, puisse qu’il est plus simple d’activer la résistance de Pull Up interne de l’Arduino, dans le programme.

Enlevez proprement le ruban publicitaire, placez les éléments…

Et collez-les. Attention, le port mini (ou micro) USB doit absolument rester accessible, pour permettre la programmation (et la mise à jour du code) de l’Arduino.

Programmation
L’idée est de créer plusieurs animations et de passer de l’une à l’autre en appuyant sur le bouton. Comme les animations utilisent des pauses (pour nous laisser le temps de voir les LED), le plus efficace est d’utiliser une interruption. Ainsi, l’appui sur le bouton est détecté en permanence par l’Arduino. L’animation en cours n’est pas interrompue, mais à la fin, c’est l’animation suivante qui est exécutée (jusqu’au prochain appui sur le bouton).
Vous pouvez vous inspirer du code ci-dessous et ajouter, modifier et/ou supprimer les animations proposées. Et si vous avez créé de nouvelles animations, n’hésitez pas à les partager dans les commentaires.
// Chapeau_NeoPixel
// Bibliothèque NeoPixel
#include <Adafruit_NeoPixel.h>
// Constantes
const int PIN_BOUTON = 2;
const int PIN_NEOPIXEL = 3;
const int NB_LED = 30;
const int NB_ANIMATIONS = 11;
// Variables
int animation = 1;
int LEDAleatoires[3][30];
int compteur = 0;
// Création de l'objet "neoPixel"
Adafruit_NeoPixel neoPixel = Adafruit_NeoPixel(NB_LED, PIN_NEOPIXEL, NEO_GRB + NEO_KHZ800);
void setup() {
// Initialise le générateur de nombres pseudo-aléatoires
randomSeed(analogRead(0));
// Déclaration du bouton (résistance Pull-Up interne)
pinMode(PIN_BOUTON, INPUT_PULLUP);
// initialisation du module de LED
neoPixel.begin();
// Intensité lumineuse (de 0 à 100)
neoPixel.setBrightness(20);
// Interuption (si le bouton est appuyé)
attachInterrupt(0, appuiBouton, FALLING);
// Remplissage du tableau
ToutesLEDAleatoires();
}
void loop() {
switch (animation) {
// animation n°0
case 0:
// Extinction des LED
ToutesLED(0,0,0);
break;
// animation n°1
case 1:
tricolore();
break;
// animation n°2
case 2:
extinctionLEDAleatoires();
break;
// animation n°3
case 3:
ToutesLEDAleatoires();
break;
// animation n°4
case 4:
remplacement(random(255),random(255),random(255));
break;
// animation n°5
case 5:
uneLEDSurDeux(LEDAleatoires[0][0],LEDAleatoires[1][0],LEDAleatoires[2][0]);
break;
// animation n°6
case 6:
uneApresLAutre(random(255),random(255),random(255));
break;
// animation n°7
case 7:
ToutesLED(random(255),random(255),random(255));
delay(1000);
break;
// animation n°8
case 8:
ToutesLED(255,0,0);
delay(300);
break;
// animation n°9
case 9:
ToutesLED(0,255,0);
delay(300);
break;
// animation n°10
case 10:
ToutesLED(0,0,255);
delay(300);
break;
// animation n°11
case 11:
ToutesLED(255,255,0);
delay(300);
break;
}
}
void appuiBouton(){
animation = animation + 1;
if (animation > NB_ANIMATIONS) {
animation = 1;
}
}
void uneApresLAutre(int r, int g, int b){
// Extinction des LED
ToutesLED(0,0,0);
// LED en couleur (l'une après l'autre)
for(int i=0;i<=(NB_LED/2);i++){
neoPixel.setPixelColor(i,r,g,b);
neoPixel.setPixelColor((NB_LED-i),r,g,b);
neoPixel.show();
delay(100);
}
delay(500);
}
void remplacement(int r, int g, int b){
for(int i=0;i<NB_LED-14;i++){
neoPixel.setPixelColor(i,r,g,b);
neoPixel.setPixelColor(i+16,r,g,b);
neoPixel.show();
delay(100);
}
delay(300);
}
void ToutesLED(int r, int g, int b){
// Toutes les LED de la meme couleur
for(int i=0;i<NB_LED;i++){
neoPixel.setPixelColor(i,r,g,b);
}
neoPixel.show();
}
void ToutesLEDAleatoires(){
// Remplisage du tableau
for(int i=0;i<NB_LED;i++){
LEDAleatoires[0][i] = random(255);
LEDAleatoires[1][i] = random(255);
LEDAleatoires[2][i] = random(255);
neoPixel.setPixelColor(i,LEDAleatoires[0][i],LEDAleatoires[1][i],LEDAleatoires[2][i]);
}
neoPixel.show();
delay(1000);
}
void extinctionLEDAleatoires(){
ToutesLEDAleatoires();
for(int i=0;i<NB_LED-14;i++){
// Affichage
neoPixel.setPixelColor(i,0,0,0);
neoPixel.setPixelColor(i+16,0,0,0);
neoPixel.show();
delay(100);
}
}
void uneLEDSurDeux(int r, int g, int b){
for(int i=0;i<NB_LED;i++){
if ((i % 2) == 0) {
neoPixel.setPixelColor(i,r,g,b);
neoPixel.setPixelColor((i+1),0,0,0);
neoPixel.show();
}
}
delay(200);
for(int i=0;i<NB_LED;i++){
if ((i % 2) == 0) {
neoPixel.setPixelColor(i,0,0,0);
neoPixel.setPixelColor((i+1),r,g,b);
neoPixel.show();
}
}
delay(200);
if (compteur < 7){
compteur = compteur + 1;
}
else{
ToutesLEDAleatoires();
compteur = 0;
}
}
void tricolore(){
// Toutes les LED de la meme couleur
for(int i=0;i<NB_LED;i++){
if ((i % 4) == 0) {
neoPixel.setPixelColor(i,255,0,00);
neoPixel.setPixelColor((i+1),255,255,255);
neoPixel.setPixelColor((i+2),0,0,255);
neoPixel.setPixelColor((i+3),0,0,0);
neoPixel.show();
}
}
delay(500);
for(int i=0;i<NB_LED;i++){
if ((i % 4) == 0) {
neoPixel.setPixelColor((i),0,0,255);
neoPixel.setPixelColor((i+1),0,0,0);
neoPixel.setPixelColor((i+2),255,0,0);
neoPixel.setPixelColor((i+3),255,255,255);
neoPixel.show();
}
}
delay(500);
for(int i=0;i<NB_LED;i++){
if ((i % 4) == 0) {
neoPixel.setPixelColor((i),255,255,255);
neoPixel.setPixelColor((i+1),0,0,255);
neoPixel.setPixelColor((i+2),0,0,0);
neoPixel.setPixelColor((i+3),255,0,0);
neoPixel.show();
}
}
delay(500);
for(int i=0;i<NB_LED;i++){
if ((i % 4) == 0) {
neoPixel.setPixelColor((i),0,0,0);
neoPixel.setPixelColor((i+1),255,0,0);
neoPixel.setPixelColor((i+2),255,255,255);
neoPixel.setPixelColor((i+3),0,0,255);
neoPixel.show();
}
}
delay(500);
}
