Construye una Caja Puzle IoT Segura con Arduino MKR Bundle – Guía Paso a Paso
Componentes y materiales
| Arduino MKR IoT Bundle | Incluye MKR1000, sensores, actuadores, pantalla LCD, servo, etc. | 1 |
Aplicaciones y servicios
- Blynk: App móvil IoT para control remoto
Sobre el proyecto
Nota: Este tutorial podría estar desactualizado. Vaya aquí para versión actual.
Mantener objetos valiosos lejos de miradas curiosas es difícil, salvo que uses una caja fuerte grande... pero ¿quién tiene espacio? Crea tu propia caja puzle con componentes del MKR IoT Bundle y cartón. No garantizamos seguridad real, pero será un divertido disuasorio para ladrones. ¡Mejor guarda golosinas, no objetos de valor real!
En resumen
Para abrir la caja (cerrada con servomotor), debe girar tres potenciómetros hasta la combinación correcta. La combinación se configura vía app Blynk. Un LED RGB da retroalimentación: color más cálido = más cerca de la combinación.
Al acertar, el buzzer reproduce una melodía (tema Star Wars) y el servo abre la caja.
Componentes necesarios del bundle:
- Buzzer
- LED RGB
- 3 Potenciómetros
- Pantalla LCD
- Servomotor

Objetivos de aprendizaje
- Introducción a plataforma Blynk IoT
- Cableado y uso de pantalla LCD
- Reproducir tema Star Wars con buzzer
¿Quiere saber más?
Este tutorial es parte de serie de experimentos con MKR1000 e IoT. Todos usan componentes del MKR IoT Bundle:
- Cojín "Te Quiero"
- Caja Puzle
- Gato de Pavlov
- El Friki
- Comunicador de Plantas
Introducción a Blynk
Blynk es app móvil popular para IoT, permite controlar Arduino conectado a internet desde cualquier lugar, anytime. Fundada en Kickstarter, se volvió muy usada por su documentación y simplicidad.
Primeros pasos con Blynk
Crear proyecto nuevo es fácil, siga estos pasos o vea guía oficial de Blynk.









Tras crear proyecto recibirá por email el Auth Token: identificador único para conectar hardware con smartphone. Cada proyecto tiene su token.
Instale librería Blynk (en Arduino Web Editor se descarga sola al incluirla; si no, desde Library Manager).
Suba este sketch y juegue con sliders:
#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);
}
}

Uso de la pantalla LCD
Conectar la pantalla requiere muchos cables, ¡paciencia!

Usamos alimentación 5V y resistencia 220Ω. Brillo regulable en pin analógico A3 (0-255, 0 = máximo):
analogWrite(A3, 0);
Sketch de prueba:
#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);
}
Añadir potenciómetros
Leer potenciómetros: analogRead() en pines A0, A1, A2.

Valores 0-1023 → mapear a 0-9 con map():
int PotOne = map(analogRead(A0), 0, 1023, 0, 9);
Sketch para mostrar valores en 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);
}
Añadir LED RGB
LED RGB da feedback: azul (lejos) → cian → amarillo → rojo (cerca).


Sketch prueba LED:
int redPin = 6, greenPin = 8, bluePin = 7;
void setup() {
pinMode(redPin, OUTPUT);
pinMode(greenPin, OUTPUT);
pinMode(bluePin, OUTPUT);
Serial.begin(9600);
}
void loop() {
setColor(0, 0, 255); delay(1000); // azul
setColor(0, 255, 255); delay(1000); // cian
setColor(255, 255, 0); delay(1000); // amarillo
setColor(255, 0, 0); delay(1000); // rojo
}
void setColor(int red, int green, int blue){
analogWrite(redPin, red);
analogWrite(greenPin, green);
analogWrite(bluePin, blue);
}
Conectar a Blynk
Unimos todo: Blynk + potenciómetros en LCD + LED feedback verde al acertar.
- Función
giveColorFeedback()pone color LED según proximidad a combinación (umbral absoluto por potenciómetro). - Variables
SliderValueOne/Two/Threeguardan combinación desde app (inicial 1,1,1). Al resetear placa, vuelve a 1,1,1. - Boolean
start = trueevita reabrir caja en cada loop.
#include <LiquidCrystal.h>
#include <SPI.h>
#include <WiFi101.h>
#include <BlynkSimpleWiFiShield101.h>
int redPin = 6, greenPin = 8, 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, SliderValueTwo = 1, 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); // Rojo
} else if (abs(PotOne - SliderValueOne) <= 3 && abs(PotTwo - SliderValueTwo) <= 3 && abs(PotThree - SliderValueThree) <= 3) {
setColor(255, 255, 0); // Amarillo
} else if (abs(PotOne - SliderValueOne) <= 4 && abs(PotTwo - SliderValueTwo) <= 4 && abs(PotThree - SliderValueThree) <= 4) {
setColor(0, 255, 255); // Cian
} else {
setColor(0, 0, 255); // Azul
}
}
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);
}
Añadir buzzer
Reproducirá tema Star Wars al abrir caja.

const int c = 261, d = 294, e = 329, f = 349, g = 391, gS = 415, a = 440, aS = 455, b = 466;
const int cH = 523, cSH = 554, dH = 587, dSH = 622, eH = 659, fH = 698, fSH = 740, gH = 784, gSH = 830, 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++;
}
Añadir servomotor
El servo es el cerrojo: gira 90° al acertar combinación para abrir.

Solo 3 cables. Para girar 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);
}
}
Para cerrar caja de nuevo, gire los tres potenciómetros a 0.
Construye tu caja puzle
Descargue archivo de caja abajo y úselo de guía. Usamos cartón 2mm.
Código
Sketch completo
(El sketch completo integrando todos los módulos está disponible en el repositorio del proyecto)
Partes personalizadas y cajas
Cartón 2mm box_E5j7tnFdNC.dxf
Esquemáticos
Proceso de manufactura
- Circuitos integrados (CI): chips compactos y potentes que impulsan la electrónica moderna
- Integración de TI SensorTag con Blynk vía Node‑RED en Raspberry Pi Zero
- Proyecto Dados Digitales Arduino: Construye tu Propio Generador de Números Aleatorios con LCD
- Sistema de Sensor de Temperatura Multiposición para Integración en Hogar Inteligente
- Mando USB para juegos DIY con Arduino – Construye tu propio gamepad de alto rendimiento
- MotionSense: Detección inteligente de intrusos con Arduino y ESP8266
- Kit MOSMusic: Control de Iluminación de Alta Potencia Sincronizada con Música vía MOSFET y Arduino
- Componentes Esenciales de una Taladradora: Visión General Completa
- Componentes Clave del Motor de Combustión Interna
- Dominando la sintaxis de netlist SPICE: Nomenclatura de componentes, elementos pasivos y activos, y definición de fuentes
- Microelectrónica Explicada: La Ciencia de la Electrónica Miniatura