mardi 25 décembre 2018

Boîte cadeau musicale et lumineuse (Arduino)

À l'occasion de Noël, j'ai fabriqué une boîte cadeau qui sort un peu de l'ordinaire: elle comporte une figurine de Père Noël qui danse (animée par un servomoteur), un haut-parleur qui diffuse une mélodie de Noël, une dizaine de LEDs clignotantes de diverses couleurs, et un écran LCD qui affiche des souhaits de circonstance.

Voyez vous-même:


Toute cette électronique pour ... une boîte?

Si on part du principe qu'une fois ouverte, la boîte sera immédiatement mise au recyclage, il semble peu raisonnable d'y placer tout cet appareillage électronique. Par contre, rien ne vous empêche de repartir avec la boîte après avoir offert le cadeau qu'elle contient.  Autre possibilité: il s'agit d'une façon originale d'offrir en cadeau un kit Arduino...

Le circuit



La base du dispositif est un Arduino Uno. Pour que la boîte puisse facilement être transportée, il est alimenté par une pile de 9 V. Un interrupteur marche-arrêt permet de le mettre en marche au moment approprié et, peut-être plus important encore, l'arrêter quand vous en avez ras le bol...  Puisque ma boîte était de grande dimension, je n'ai pas jugé utile de miniaturiser mon circuit avec un Arduino Nano.


La figurine de Père Noël qui danse est attachée à un petit servomoteur qui effectue un mouvement de va-et-vient de 90° d'amplitude.  Il est contrôlé par la broche 9 de l'Arduino.


Le haut-parleur a été branché à la broche 8 de  l'Arduino par l'entremise d'un transistor, tel que recommandé dans un précédent billet.  Des petits trous on été pratiqués dans la boîte, devant le haut-parleur, pour faciliter la diffusion du son.  Personnellement, je préfère les hauts-parleurs, mais vous pouvez aussi utiliser un piézo.



L'afficheur LCD tient lieu d'étiquette et pourrait être utilisé pour écrire à qui est destiné le cadeau, de la part de qui, etc.  L'effet est plus intéressant si le message affiché change périodiquement.  Pour plus d'informations sur l'utilisation d'un afficheur LCD 2 X 16, consultez ce billet.



Les broches A0 à A5 de l'Arduino sont utilisées comme sorties numériques pour contrôler les LEDs.  Les LEDs rouges et les LEDs vertes ont été placées en paires, mais pas les LEDs bleues, puisqu'elles nécessitent une plus grande tension.



Bien entendu, chaque élément de la boîte est facultatif: vous pouvez fabriquer une boîte cadeau très spectaculaire sans afficheur LCD, par exemple.


Le sketch

Puisque chaque élément du circuit avait déjà été utilisé dans d'autres projets, la seule difficulté, lors de la programmation, a été de faire en sorte que tout s'effectue simultanément sans interférer avec les autres parties du circuit.

Il aurait été facile de jouer la mélodie au complet, de faire ensuite bouger le Père Noël une fois la musique terminée, et finalement faire clignoter quelques LEDs, mais il était important que le Père Noël bouge pendant que la musique joue et que les LEDs clignotent, d'où l'utilisation assez intensive de la fonction millis() pour vérifier si c'est le moment de jouer une nouvelle note, de changer l'état d'une LED, ou de bouger le Père Noël, avec interdiction totale d'utiliser la fonction delay()!!!

À noter que chaque groupe de LED a sa propre fréquence de clignotement, ce qui donne un effet pseudo aléatoire qui me plaît bien.

/****************************************************************************
Boite cadeau de Noël Arduino
Une boîte cadeau qui joue une mélodie de Noël, fait clignoter des LEDs,
affiche un message sur un LCD, et fait bouger un père Noël grâce à un
servomoteur.
Pour plus d'informations:
https://electroniqueamateur.blogspot.com/2018/12/boite-cadeau-musicale-et-lumineuse.html
*****************************************************************************/
// inclusion des bibliothèques
#include <Servo.h> // pour le servomoteur
#include <LiquidCrystal.h> // pour l'afficheur LCD
// Définition des broches
#define pinHautParleur 8 // haut-parleur à la broche 8 de l'Arduino
#define pinServo 9 // servo-moteur à la broche 9 de l'Arduino
#define pinRS 12 // pin 4 (RS) de l'afficheur branchée à pin 12 de l'Arduino
#define pinEnable 11 // pin 6 (Enable) de l'afficheur branchée à pin 11 de l'Arduino
#define pinD4 5 // pin 11 (D4) de l'afficheur branchée à pin 5 de l'Arduino
#define pinD5 4 // pin 12 (D5) de l'afficheur branchée à pin 4 de l'Arduino
#define pinD6 3 // pin 13 (D6) de l'afficheur branchée à pin 3 de l'Arduino
#define pinD7 2 // pin 14 (D7) de l'afficheur branchée à pin 2 de l'Arduino
#define LED1Pin 14 // une paire de LEDs est reliée à A0
#define LED2Pin 15 // une paire de LEDs est reliée à A1
#define LED3Pin 16 // une paire de LEDs est reliée à A2
#define LED4Pin 17 // une paire de LEDs est reliée à A3
#define LED5Pin 18 // une paire de LEDs est reliée à A4
#define LED6Pin 19 // une paire de LEDs est reliée à A5
// variables globales associées à l'afficheur LCD
// Initialisation de la bibliothèque LiquidCrystal en utilisant les pins définies ci-dessus:
LiquidCrystal lcd(pinRS, pinEnable, pinD4, pinD5, pinD6, pinD7);
int message = 0; // numéro du message affiché sur le LCD
unsigned long dernierMessage = 0; // moment du plus récent changement de message
const int delaiMessage = 4000; // nombre de millisecondes entre deux messages successifs
// variables globales associées au servomoteur
Servo myservo;
int pos = 0; // position initiale du servomoteur
int sens = 0; // sens de rotation du servomoteur
const int delaiServo = 20; // nombre de millisecondes entre deux changements de position du servomoteur
unsigned long dernierMvtServo = 0; // moment du plus récent changement de position du servomoteur
const int deplacementMax = 90; // déplacement maximum du servomoteur, en degrés
// variables globales associées à la mélodie jouée au haut-parleur
// fréquence associée à chaque note
// do, do#, ré, ré#, mi, fa, fa#, sol, sol#, la, la#, si
const float note[12] = {65.41, 69.30, 73.42, 77.78, 82.41, 87.31, 92.50, 98.00, 103.83, 110.00, 116.54, 123.47 };
const int nombreDeNotes = 49;
int laNote; // numéro de la prochaine note à jouer
int silence = 0; //devient 1 pendant le silence entre deux notes
const int tempo = 150; // delai en millisecondes entre deux notes consécutives
unsigned long derniereNote = 0; // moment du plus recent changement de note
const int melodie[][3] = { {4, 2, 2}, {4, 2, 2}, {4, 2, 4}, {4, 2, 2}, {4, 2, 2}, {4, 2, 4},
{4, 2, 2}, {7, 2, 2}, {0, 2, 3}, {2, 2, 1}, {4, 2, 8},
{5, 2, 2}, {5, 2, 2}, {5, 2, 3}, {5, 2, 1}, {5, 2, 2}, {4, 2, 2}, {4, 2, 3},
{4, 2, 1}, {4, 2, 2}, {2, 2, 2}, {2, 2, 2}, {4, 2, 2}, {2, 2, 4}, {7, 2, 4},
{4, 2, 2}, {4, 2, 2}, {4, 2, 4}, {4, 2, 2}, {4, 2, 2}, {4, 2, 4},
{4, 2, 2}, {7, 2, 2}, {0, 2, 3}, {2, 2, 1}, {4, 2, 8},
{5, 2, 2}, {5, 2, 2}, {5, 2, 3}, {5, 2, 1}, {5, 2, 2}, {4, 2, 2}, {4, 2, 3},
{4, 2, 1}, {7, 2, 2}, {7, 2, 2}, {5, 2, 2}, {2, 2, 2}, {0, 2, 8}
};
// variables globales associées aux LEDs
const int delaiLED1 = 900; // délai en millisecondes avant le changement d'état de la LED
const int delaiLED2 = 1200;
const int delaiLED3 = 1400;
const int delaiLED4 = 1000;
const int delaiLED5 = 1600;
const int delaiLED6 = 1100;
unsigned long dernierLED1 = 0; // moment du plus récent changement d'état de la LED
unsigned long dernierLED2 = 0;
unsigned long dernierLED3 = 0;
unsigned long dernierLED4 = 0;
unsigned long dernierLED5 = 0;
unsigned long dernierLED6 = 0;
void setup() {
pinMode(LED1Pin, OUTPUT);
pinMode(LED2Pin, OUTPUT);
pinMode(LED3Pin, OUTPUT);
pinMode(LED4Pin, OUTPUT);
pinMode(LED5Pin, OUTPUT);
pinMode(LED6Pin, OUTPUT);
myservo.attach(pinServo);
lcd.begin(16, 2);
lcd.setCursor(5, 0);
lcd.print("Joyeux");
// curseur sur la deuxième ligne
lcd.setCursor(4, 1);
lcd.print("Noel !!!");
}
void loop() {
int frequence;
// Contrôle du servomoteur
if ((millis() - dernierMvtServo) > delaiServo) { // c'est le temps de faire bouger le servomoteur
myservo.write(pos);
if (sens == 0) {
pos++;
if (pos > deplacementMax) {
pos = deplacementMax;
sens = 1;
}
}
if (sens == 1) {
pos--;
if (pos < 0) {
pos = 0;
sens = 0;
}
}
dernierMvtServo = millis();
}
// contrôle du haut-parleur
if ((silence == 0) && ((millis() - derniereNote) > 50)) { // c'est le temps de jouer une nouvelle note
frequence = round(note[melodie[laNote][0]] * 2 * (melodie[laNote][1] - 1));
tone(pinHautParleur, frequence);
silence = 1;
derniereNote = millis();
}
else if ((millis() - derniereNote) > ((tempo * melodie[laNote][2] - 50))) { // il faut arrêter une note
noTone(pinHautParleur);
silence = 0;
laNote++;
if (laNote == nombreDeNotes) {
laNote = 0;
}
derniereNote = millis();
}
// contrôle de l'afficheur
if ((millis() - dernierMessage) > delaiMessage) { // c'est le moment de changer le message affiché
lcd.clear();
if (message == 0) {
// curseur sur la première ligne
lcd.setCursor(5, 0);
lcd.print("Joyeux");
// curseur sur la deuxième ligne
lcd.setCursor(4, 1);
lcd.print("Noel !!!");
}
if (message == 1) {
// curseur sur la première ligne
lcd.setCursor(2, 0);
lcd.print("Bonne annee");
// curseur sur la deuxième ligne
lcd.setCursor(4 , 1);
lcd.print("2019 !!!");
}
message++;
if (message > 1) {
message = 0;
}
dernierMessage = millis();
}
//contrôle des LEDs
if ((millis() - dernierLED1) > delaiLED1) {
digitalWrite(LED1Pin, !digitalRead(LED1Pin));
dernierLED1 = millis();
}
if ((millis() - dernierLED2) > delaiLED2) {
digitalWrite(LED2Pin, !digitalRead(LED2Pin));
dernierLED2 = millis();
}
if ((millis() - dernierLED3) > delaiLED3) {
digitalWrite(LED3Pin, !digitalRead(LED3Pin));
dernierLED3 = millis();
}
if ((millis() - dernierLED4) > delaiLED4) {
digitalWrite(LED4Pin, !digitalRead(LED4Pin));
dernierLED4 = millis();
}
if ((millis() - dernierLED5) > delaiLED5) {
digitalWrite(LED5Pin, !digitalRead(LED5Pin));
dernierLED5 = millis();
}
if ((millis() - dernierLED6) > delaiLED6) {
digitalWrite(LED6Pin, !digitalRead(LED6Pin));
dernierLED6 = millis();
}
}

À lire aussi

D'autres projets d'électronique pour Noël: fabrication d'un mini sapin de Noël clignotant et répertoire de mélodies de Noël pour Arduino.

Yves Pelletier   (TwitterFacebook)

Aucun commentaire:

Enregistrer un commentaire