Voyez vous-même:
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/**************************************************************************** | |
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 (Twitter, Facebook)
Aucun commentaire:
Enregistrer un commentaire