Construire une boîte à énigme IoT sécurisée avec Arduino MKR Bundle – Guide étape par étape
Composants et fournitures
| Arduino MKR IoT Bundle | 1 |
Applications et services en ligne
| Blynk |
À propos de ce projet
Note : Ce tutoriel pourrait être obsolète, consultez ici pour une version plus récente.
Garder ses objets de valeur à l'abri des regards n'est pas facile, sauf à utiliser un gros coffre... mais qui a la place ?
Créez plutôt votre propre boîte à énigme (puzzle box) avec les composants du MKR IoT Bundle et du carton ! Nous ne garantissons pas la sécurité de vos biens, mais ce sera un dissuasif amusant pour les voleurs potentiels.
Bien sûr, on vous conseille d'y cacher vos bonbons... pas vos vrais objets de valeur !
En résumé
Pour ouvrir la boîte, maintenue fermée par un servomoteur, il faut tourner les potentiomètres jusqu'à trouver la bonne combinaison. La combinaison est définie via l'application en ligne Blynk. Une LED RGB aide : plus vous êtes proche, plus la couleur est "chaude" (bleu → cyan → jaune → rouge).
Quand la bonne combinaison est trouvée, le buzzer joue une mélodie pendant que le servo ouvre la boîte.
Composants nécessaires :
- Buzzer
- LED RGB
- 3 potentiomètres
- Écran LCD
- Servomoteur

Objectifs d'apprentissage
- Découverte de la plateforme IoT Blynk
- Câblage et utilisation de l'écran LCD
- Jouer le thème Star Wars au buzzer
En savoir plus
Ce tutoriel fait partie d'une série d'expériences pour se familiariser avec le MKR1000 et l'IoT. Toutes peuvent être réalisées avec les composants du MKR IoT Bundle.
- Coussin "I Love You"
- Boîte à énigme (Puzzle Box)
- Chat de Pavlov
- The Nerd
- Communicateur de plantes
Présentation de Blynk
Blynk est une application mobile populaire pour l'IoT, permettant de contrôler facilement son Arduino connecté à Internet depuis n'importe où, n'importe quand.
Née sur Kickstarter, elle est devenue l'une des apps les plus utilisées dans le domaine, grâce à sa documentation excellente et sa simplicité.
Démarrer avec Blynk
Créer un nouveau projet est facile, suivez ces étapes ou consultez le guide officiel de Blynk.









Après création, vous recevez par email l'Auth Token : identifiant unique pour connecter votre matériel au smartphone. Chaque nouveau projet a son propre token.
Pour connecter l'Arduino à l'app, installez la bibliothèque Blynk. Avec l'Arduino Web Editor, elle se télécharge automatiquement à l'inclusion dans le sketch, sinon via le gestionnaire de bibliothèques.
Prêts à partir. Téléversez ce sketch et jouez avec les curseurs :
#include <WiFi101.h>
#include <BlynkSimpleWiFiShield101.h>
const char* ssid = SECRET_SSID;
const char* password = SECRET_PSWD;
char auth[] = SECRET_TOKEN;
int SliderValueOne = 1;
int SliderValueTwo = 1;
int SliderValueThree = 1;
BLYNK_WRITE(V1) { SliderValueOne = param.asInt(); }
BLYNK_WRITE(V2) { SliderValueTwo = param.asInt(); }
BLYNK_WRITE(V3) { SliderValueThree = param.asInt(); }
void setup() {
Serial.begin(9600);
Blynk.begin(auth, ssid, password);
}
void loop() {
int Temp_Slider_One_value = SliderValueOne;
int Temp_Slider_Two_value = SliderValueTwo;
int Temp_Slider_Three_value = SliderValueThree;
Blynk.run();
if(Temp_Slider_One_value != SliderValueOne || Temp_Slider_Two_value != SliderValueTwo || Temp_Slider_Three_value != SliderValueThree){
Serial.print("New combination: ");
Serial.print(SliderValueOne); Serial.print(" "); Serial.print(SliderValueTwo); Serial.print(" "); Serial.println(SliderValueThree);
}
}

Utilisation de l'écran LCD
Branchez l'écran ! Facile mais beaucoup de fils, patience requise.

Note : alimentation 5V et résistance 220 Ω. Luminosité réglable via sortie analogique broche A3 (0-255, 0 = maximum).
analogWrite(A3, 0);
Téléversez l'exemple pour tester :
#include <LiquidCrystal.h>
const int rs = 12, en = 11, d4 = 2, d5 = 3, d6 = 4, d7 = 5;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
void setup() {
analogWrite(A3, 0);
lcd.begin(16, 2);
lcd.print("hello, world!");
}
void loop() {
lcd.setCursor(0, 1);
lcd.print(millis() / 1000);
}
Ajouter les potentiomètres
Lecture via analogRead() sur broches A0, A1, A2.

Valeurs 0-1023, impossible à deviner. On les mappe 0-9 avec map() :
int PotOne = map(analogRead(A0), 0, 1023, 0, 9);
Exemple affichage valeurs sur LCD :
#include <LiquidCrystal.h>
const int rs = 12, en = 11, d4 = 2, d5 = 3, d6 = 4, d7 = 5;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
void setup() {
analogWrite(A3, 0);
Serial.begin(9600);
lcd.begin(16, 2);
}
void loop() {
int PotOne = map(analogRead(A0), 0, 1023, 0, 9);
int PotTwo = map(analogRead(A1), 0, 1023, 0, 9);
int PotThree = map(analogRead(A2), 0, 1023, 0, 9);
lcd.setCursor(0, 0); lcd.print(PotOne);
lcd.setCursor(2, 0); lcd.print(PotTwo);
lcd.setCursor(4, 0); lcd.print(PotThree);
}
Ajouter la LED RGB
La LED RGB donne un retour visuel : plus on approche de la bonne valeur, plus la couleur chauffe (bleu → cyan → jaune → rouge).


Sketch exemple pour tester :
int redPin = 6; int greenPin = 8; int bluePin = 7;
void setup() {
pinMode(redPin, OUTPUT); pinMode(greenPin, OUTPUT); pinMode(bluePin, OUTPUT);
Serial.begin(9600);
}
void loop() {
setColor(0, 0, 255); delay(1000); // bleu
setColor(0, 255, 255); delay(1000); // cyan
setColor(255, 255, 0); delay(1000); // jaune
setColor(255, 0, 0); delay(1000); // rouge
}
void setColor(int red, int green, int blue){
analogWrite(redPin, red); analogWrite(greenPin, green); analogWrite(bluePin, blue);
}
Connecter à Blynk
Assemblons : connexion Blynk, potentiomètres sur LCD, LED verte clignotante si combinaison correcte.
- Fonction
giveColorFeedback()pour couleur LED selon proximité de chaque potentiomètre à la combinaison (seuil absolu). - Variables stockant valeurs envoyées par l'app = combinaison.
int SliderValueOne = 1; int SliderValueTwo = 1; int SliderValueThree = 1;
Valeur initiale 1, change seulement si curseurs modifiés sur l'app. Reset de la carte = retour combinaison par défaut.
- Variable booléenne
bool start = true;détecte si combinaison déjà trouvée, pour éviter réouverture à chaque boucle.
Sketch exemple complet :
#include <LiquidCrystal.h>
#include <SPI.h>
#include <WiFi101.h>
#include <BlynkSimpleWiFiShield101.h>
int redPin = 6; int greenPin = 8; int bluePin = 7;
const char* ssid = SECRET_SSID;
const char* password = SECRET_PSWD;
char auth[] = SECRET_TOKEN;
const int rs = 12, en = 11, d4 = 2, d5 = 3, d6 = 4, d7 = 5;
bool start = true;
int SliderValueOne = 1; int SliderValueTwo = 1; int SliderValueThree = 1;
BLYNK_WRITE(V1) { SliderValueOne = param.asInt(); }
BLYNK_WRITE(V2) { SliderValueTwo = param.asInt(); }
BLYNK_WRITE(V3) { SliderValueThree = param.asInt(); }
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
void setup() {
pinMode(redPin, OUTPUT); pinMode(greenPin, OUTPUT); pinMode(bluePin, OUTPUT);
analogWrite(A3, 0); Serial.begin(9600);
lcd.begin(16, 2);
Blynk.begin(auth, ssid, password);
}
void loop() {
int Temp_Slider_One_value = SliderValueOne;
int Temp_Slider_Two_value = SliderValueTwo;
int Temp_Slider_Three_value = SliderValueThree;
Blynk.run();
if(Temp_Slider_One_value != SliderValueOne || Temp_Slider_Two_value != SliderValueTwo || Temp_Slider_Three_value != SliderValueThree){
Serial.print("New combination: "); Serial.print(SliderValueOne); Serial.print(" "); Serial.print(SliderValueTwo); Serial.print(" "); Serial.println(SliderValueThree);
}
int PotOne = map(analogRead(A0), 0, 1023, 0, 9);
int PotTwo = map(analogRead(A1), 0, 1023, 0, 9);
int PotThree = map(analogRead(A2), 0, 1023, 0, 9);
lcd.setCursor(0, 0); lcd.print(PotOne);
lcd.setCursor(2, 0); lcd.print(PotTwo);
lcd.setCursor(4, 0); lcd.print(PotThree);
if (start) {
giveColorFeedback(PotOne, PotTwo, PotThree);
if (PotOne == SliderValueOne && PotTwo == SliderValueTwo && PotThree == SliderValueThree) {
blinkGreenLed(); start = false;
}
}
if(!start) {
if(PotOne == 0 && PotTwo == 0 && PotThree == 0){ start = true; }
}
}
void giveColorFeedback(int PotOne, int PotTwo, int PotThree) {
if (abs(PotOne - SliderValueOne) <= 1 && abs(PotTwo - SliderValueTwo) <= 1 && abs(PotThree - SliderValueThree) <= 1) {
setColor(255, 0, 0); // Rouge
} else if (abs(PotOne - SliderValueOne) <= 3 && abs(PotTwo - SliderValueTwo) <= 3 && abs(PotThree - SliderValueThree) <= 3) {
setColor(255, 255, 0); // Jaune
} else if (abs(PotOne - SliderValueOne) <= 4 && abs(PotTwo - SliderValueTwo) <= 4 && abs(PotThree - SliderValueThree) <= 4) {
setColor(0, 255, 255); // Cyan
} else {
setColor(0, 0, 255); // Bleu
}
}
void blinkGreenLed() {
for (int a = 0; a < 2; a++) {
for (int b = 0; b <= 255; b += 5) { setColor(0, b, 0); delay(5); }
for (int b = 255; b >= 0; b -= 5) { setColor(0, b, 0); delay(5); }
}
for (int b = 0; b <= 255; b += 5) { setColor(0, b, 0); delay(5); }
}
void setColor(int red, int green, int blue){
analogWrite(redPin, red); analogWrite(greenPin, green); analogWrite(bluePin, blue);
}
Ajouter le buzzer
Le buzzer joue une mélodie à l'ouverture : le thème Star Wars !

Code exemple :
const int c = 261; const int d = 294; const int e = 329; const int f = 349;
const int g = 391; const int gS = 415; const int a = 440; const int aS = 455;
const int b = 466; const int cH = 523; const int cSH = 554; const int dH = 587;
const int dSH = 622; const int eH = 659; const int fH = 698; const int fSH = 740;
const int gH = 784; const int gSH = 830; const int aH = 880;
int counter = 0; #define buzzerPin 1
void setup() { pinMode(buzzerPin, OUTPUT); Serial.begin(9600); }
void loop() { play_jingle(); delay(3000); }
void play_jingle() {
beep(a, 500); beep(a, 500); beep(a, 500);
beep(f, 350); beep(cH, 150); beep(a, 500);
beep(f, 350); beep(cH, 150); beep(a, 650); delay(500);
beep(eH, 500); beep(eH, 500); beep(eH, 500);
beep(fH, 350); beep(cH, 150); beep(gS, 500);
beep(f, 350); beep(cH, 150); beep(a, 650); delay(500);
}
void beep(int note, int duration) {
tone(buzzerPin, note, duration); noTone(buzzerPin); delay(50); counter++;
}
Ajouter le servomoteur
Le servo est le verrou de la boîte : rotation 90° pour l'ouvrir quand la combinaison est correcte.

3 fils suffisent. Pour tourner 90° :
#include <Servo.h>
int pos = 0; Servo myservo;
void setup() { myservo.attach(9); myservo.write(pos); }
void loop() { open_the_box(); delay(2000); close_the_box(); delay(2000); }
void open_the_box(){ for (pos = 0; pos <= 90; pos += 1) { myservo.write(pos); delay(15); } }
void close_the_box(){ for (pos = 90; pos >= 0; pos -= 1) { myservo.write(pos); delay(15); } }
Note : pour refermer et verrouiller, remettez tous les potentiomètres à 0.
Construire votre boîte à énigme
Pas de boîte sans boîte ! Téléchargez le fichier de boîtier ci-dessous comme guide.
Note : carton 2 mm utilisé.
Code
Sketch complet
(Le sketch complet intégrant tous les éléments est disponible dans le tutoriel original)
Pièces personnalisées et boîtiers
Carton 2 mm box_E5j7tnFdNC.dxf
Schémas

Processus de fabrication
- Maîtriser la syntaxe des netlists SPICE : nommage, composants passifs/actifs, sources
- Circuits intégrés (CI) : puces compactes et puissantes alimentant l'électronique moderne
- Intégration du TI SensorTag à Blynk via Node‑RED sur Raspberry Pi Zero
- Dé numérique Arduino sur écran LCD 16x2 – Générateur aléatoire à bouton poussoir
- Système de Capteur de Température Multi-Position pour Intégration Domotique
- Kit MOSMusic : MOSFET, Arduino et plus pour éclairage musical
- Microélectronique : Science des Composants Électroniques Miniatures
- Composants Essentiels d'une Perceuse : Vue d'Ensemble Complète
- Composants clés d'un moteur à combustion interne