Skip to content

Commit 3867ae3

Browse files
Merge pull request #1836 from arduino/Hannes7eicher/IoT-Bundle-Fix
update puzzlebox, the nerd
2 parents 67d3588 + 4355c43 commit 3867ae3

File tree

6 files changed

+387
-35
lines changed

6 files changed

+387
-35
lines changed

content/hardware/09.kits/maker/iot-bundle/tutorials/puzzlebox/content.md

+200-14
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,11 @@ source: "https://create.arduino.cc/projecthub/Arduino_Genuino/puzzlebox-with-ard
2222

2323
**Create a Puzzle Box with the help of the Arduino Cloud!**
2424

25-
Keeping your valuable items away from prying eyes can be hard sometimes, unless you put it in a big safe or something similar... but who has room for that? Instead, create your own puzzle box using the components from the IoT Bundle and some cardboard! We can't guarantee the safety of your belongings, but at least it will be a fun deterrent for potential thieves. Of course, we advise you to stash your candy in there... not actual valuables.
25+
Keeping your valuable items away from prying eyes can be hard sometimes unless you put them in a big safe or something similar... but who has room for that? Instead, create your own puzzle box using the components from the IoT Bundle and some cardboard! We can't guarantee the safety of your belongings, but at least it will be a fun deterrent for potential thieves. Of course, we advise you to stash your candy in there... not actual valuables.
2626

2727
### In a Nutshell
2828

29-
In order to open the box, which is held closed with a servo motor, you will have to turn the potentiometers until you get the right combination. The combination can be set through the dashboard on the Arduino Cloud. An LED will help you guess, giving you colour feedbacks: the closer you are, the warmer the color. When the right combination is guessed, the box will open and a victorious melody will start playing, revealing whatever you have locked inside. In order to create our puzzle box we will need the following components:
29+
In order to open the box, which is held closed with a servo motor, you will have to turn the potentiometers until you get the right combination. The combination can be set through the dashboard on the Arduino Cloud. An LED will help you guess, giving you color feedback: the closer you are, the warmer the color. When the right combination is guessed, the box will open and a victorious melody will start playing, revealing whatever you have locked inside. To create our puzzle box we will need the following components:
3030

3131
* Buzzer
3232
* RGB LED
@@ -76,7 +76,13 @@ We will start by setting up the Arduino Cloud by following the steps below:
7676

7777
We will start by adding four variables:
7878

79-
![Arduino IoT Bundle](assets/screenshot_2022-11-23_141306_tsMoI77zJw.png)
79+
- `display` - `String` - `READ & WRITE`
80+
81+
- `sliderOne` - `INT` - `READ & WRITE`
82+
83+
- `sliderThree` - `TIME` - `READ & WRITE`
84+
85+
- `sliderTwo` - `INT` - `READ & WRITE`
8086

8187
### Dashboard
8288

@@ -376,7 +382,7 @@ void onDisplayChange() {
376382

377383
**RGB LED**
378384

379-
We will use the RGB LED as a feedback to help people guessing the combination, the closer they get to the right value the warmer the colour of the LED, spanning from blue, aqua, yellow and red.
385+
We will use the RGB LED as feedback to help people guess the combination, the closer they get to the right value the warmer the color of the LED, spanning from blue, aqua, yellow and red.
380386

381387
![RGB LED](assets/rgbled_s82wjxgcnf_1WXt8cDpSj.png)
382388

@@ -499,7 +505,7 @@ void onDisplayChange() {
499505

500506
### Connect It to the Arduino Cloud
501507

502-
Now we are starting to put things together: we have connected the potentiometers to unlock the box, created two dashboards for setting the combination and seeing your current position, as well as installed a RGB which will tell you how close you are to the right combination.
508+
Now we are starting to put things together: we have connected the potentiometers to unlock the box, created two dashboards for setting the combination and seeing your current position, as well as installed an RGB which will tell you how close you are to the right combination.
503509

504510
- Note that we will use the function `giveColorFeedback()` to set the color of the RGB LED when the absolute value of each potentiometer is closer than a certain threshold to the correct combination.
505511

@@ -509,7 +515,7 @@ void giveColorFeedback(int PotOne, int PotTwo, int PotThree){...}
509515

510516
- Note that the initial value is set to 1, it will change only if you modify the values of the sliders on the Cloud dashboard. If you reset the board the combination will be back to the default value.
511517

512-
A boolean variable **bool start = true;** is used to detect when the combination has already been guessed, so to avoid reopening the the box at every loop.
518+
A boolean variable **bool start = true;** is used to detect when the combination has already been guessed, to avoid reopening the the box at every loop.
513519

514520
Upload this example sketch and turn the potentiometers to see it in action.
515521

@@ -661,7 +667,7 @@ We will use the buzzer to play a melody when the box is opened. Connect the buzz
661667

662668
![Arduino IoT Bundle](assets/piezo_buzzer_part_rp2040_iaPHtGSH0X.png)
663669

664-
Now, navigate into the Arduino Web Editor through **Thing > Sketch tab > open full editor**. This will open up our automatically generated sketch in the full Arduino Web Editor. Next we need to add an extra tab containing all the necessary notes to play the song. Click the arrow on the right side to add a new tab called `"Melody.h"` and add the code below.
670+
Now, navigate into the Arduino Web Editor through **Thing > Sketch tab > open full editor**. This will open up our automatically generated sketch in the full Arduino Web Editor. Next we need to add an extra tab containing all the necessary notes to play the song. Click the arrow on the right side to add a new tab called `"melody.h"` and add the code below.
665671

666672
```
667673
#define NOTE_B0 31
@@ -778,13 +784,13 @@ void playMelody() {
778784
}
779785
```
780786

781-
Now, we need to go back to our main sketch to play the melody. In order to use the notes we need to add " **#include "Melody.h"** " at the top of our code and inside **setup()** we need to add our **buzzerPin** as **Output.** To test our melody we can call **playMelody()** inside **loop()** if the combination has been set right.
787+
Now, we need to go back to our main sketch to play the melody. In order to use the notes we need to add " **#include "melody.h"** " at the top of our code and inside **setup()** we need to add our **buzzerPin** as **Output.** To test our melody we can call **playMelody()** inside **loop()** if the combination has been set right.
782788

783789
```
784790
#include "LiquidCrystal.h"
785791
#include "SPI.h"
786792
#include "thingProperties.h"
787-
#include "Melody.h"
793+
#include "melody.h"
788794
/* RGB LED pins */
789795
int redPin = 6;
790796
int greenPin = 8;
@@ -941,19 +947,19 @@ void onDisplayChange() {
941947

942948
> **Note:** for the servo motor you will need a 9V battery which is not included in the IoT Bundle! Alternatively you can use another external power supply such as a phone charger with open ended cables.
943949
944-
The servo motor is the lock of our box, we will need it to turn 90 degrees when the combination is correct, so that the box will open. Connecting the servo only requires three wires though you will need a 9V battery to power the servo motor. Connect **9V**, **GND** and **pin9** as shown below.
950+
The servo motor is the lock of our box, we will need it to turn 90 degrees when the combination is correct so that the box will open. Connecting the servo only requires three wires though you will need a 9V battery to power the servo motor. Connect **9V**, **GND** and **pin9** as shown below.
945951

946952
![Arduino IoT Bundle](assets/servo_motor_part_rp2040_4ZqZ4C9F5w.png)
947953

948954
![Arduino IoT Bundle](assets/servo_motor_comeplete_rp2040_mXHekbPnRO.png)
949955

950-
To use the servo motor we need to `#include "Servo.h"` at the top of our code as well as set starting position to 0 and include the `Servo myservo` object. Now we can create two functions, one for opening the box and one for closing it.
956+
To use the servo motor we need to `#include "Servo.h"` at the top of our code as well as set the starting position to 0 and include the `Servo myservo` object. Now we can create two functions, one for opening the box and one for closing it.
951957

952958
```arduino
953959
#include "LiquidCrystal.h"
954960
#include "SPI.h"
955961
#include "thingProperties.h"
956-
#include "Melody.h"
962+
#include "melody.h"
957963
#include "Servo.h"
958964
int pos = 0;
959965
Servo myservo;
@@ -1110,7 +1116,7 @@ void onDisplayChange() {
11101116
}
11111117
```
11121118

1113-
Note that in order to turn the servo back and close the box all you'll have to do is to turn all potentiometer to 0.
1119+
Note that in order to turn the servo back and close the box all you'll have to do is to turn all potentiometers to 0.
11141120

11151121
### Build Your Puzzle Box
11161122

@@ -1127,4 +1133,184 @@ This tutorial is part of a series of experiments that familiarize you with the A
11271133

11281134
## Full Code
11291135

1130-
<iframe src="https://create.arduino.cc/editor/Arduino_Genuino/77796ee5-af44-422c-99a8-fde653a8a51b/preview?embed" style="height:510px;width:100%;margin:10px 0" frameborder="0"></iframe>
1136+
```arduino
1137+
#include "LiquidCrystal.h"
1138+
#include "SPI.h"
1139+
#include "thingProperties.h"
1140+
#include "melody.h"
1141+
#include "Servo.h"
1142+
1143+
int pos = 0;
1144+
Servo myservo;
1145+
1146+
/* RGB LED pins */
1147+
int redPin = 6;
1148+
int greenPin = 8;
1149+
int bluePin = 7;
1150+
1151+
/* LCD screen pins */
1152+
const int rs = 12,
1153+
en = 11,
1154+
d4 = 2,
1155+
d5 = 3,
1156+
d6 = 4,
1157+
d7 = 5;
1158+
1159+
bool start = true;
1160+
1161+
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
1162+
1163+
void setup() {
1164+
pinMode(redPin, OUTPUT);
1165+
pinMode(greenPin, OUTPUT);
1166+
pinMode(bluePin, OUTPUT);
1167+
analogWrite(A3, 0); /* set the brightness of the LCD screen to the maximum value */
1168+
Serial.begin(9600);
1169+
delay(1500);
1170+
initProperties();
1171+
ArduinoCloud.begin(ArduinoIoTPreferredConnection{{if .Broker}}, false, "{{.Broker}}"{{end}});
1172+
setDebugMessageLevel(2);
1173+
ArduinoCloud.printDebugInfo();
1174+
lcd.begin(16, 2); /* begin LCD screen with 16 columns and 2 rows */
1175+
1176+
myservo.attach(9);
1177+
myservo.write(pos);
1178+
}
1179+
1180+
void loop() {
1181+
ArduinoCloud.update();
1182+
int PotOne = map(analogRead(A0), 0, 1023, 0, 9);
1183+
int PotTwo = map(analogRead(A1), 0, 1023, 0, 9);
1184+
int PotThree = map(analogRead(A2), 0, 1023, 0, 9);
1185+
lcd.setCursor(0, 0);
1186+
lcd.print(PotOne);
1187+
lcd.setCursor(2, 0);
1188+
lcd.print(PotTwo);
1189+
lcd.setCursor(4, 0);
1190+
lcd.print(PotThree);
1191+
1192+
String numberOne = String(PotOne);
1193+
String numberTwo = String(PotTwo);
1194+
String numberThree = String(PotThree);
1195+
1196+
display =String(numberOne + numberTwo + numberThree);
1197+
1198+
if (start) {
1199+
giveColorFeedback(PotOne, PotTwo, PotThree);
1200+
if (PotOne == sliderOne && PotTwo == sliderTwo && PotThree == sliderThree)
1201+
{
1202+
blinkGreenLed();
1203+
start = false;
1204+
open_the_box();
1205+
playMelody();
1206+
}
1207+
}
1208+
if (!start) {
1209+
if (PotOne == 0 && PotTwo == 0 && PotThree == 0) {
1210+
start = true;
1211+
close_the_box();
1212+
}
1213+
}
1214+
}
1215+
1216+
/* Give feedback based on how close the potentiometer are to the combination value
1217+
The more it's close the warmer is the color of the LED */
1218+
void giveColorFeedback(int PotOne, int PotTwo, int PotThree) {
1219+
if (abs(PotOne - sliderOne) <= 1 && abs(PotTwo - sliderTwo) <= 1 && abs(PotThree - sliderThree) <= 1 ) {
1220+
/* Red */
1221+
setColor(255, 0, 0);
1222+
}
1223+
else if (abs(PotOne - sliderOne) <= 3 && abs(PotTwo - sliderTwo) <= 3 && abs(PotThree - sliderThree) <= 3 ) {
1224+
/* yellow */
1225+
setColor(255, 255, 0);
1226+
}
1227+
else if (abs(PotOne - sliderOne) <= 4 && abs(PotTwo - sliderTwo) <= 4 && abs(PotThree - sliderThree) <= 4 ) {
1228+
/* aqua */
1229+
setColor(0, 255, 255);
1230+
}
1231+
else {
1232+
/* blue */
1233+
setColor(0, 0, 255);
1234+
}
1235+
}
1236+
1237+
void blinkGreenLed() {
1238+
for (int a = 0; a < 2; a++) {
1239+
for (int b = 0; b <= 255; b += 5) {
1240+
setColor(0, b, 0);
1241+
delay(5);
1242+
}
1243+
for (int b = 255; b >= 0; b -= 5) {
1244+
setColor(0, b, 0);
1245+
delay(5);
1246+
}
1247+
}
1248+
for (int b = 0; b <= 255; b += 5) {
1249+
setColor(0, b, 0);
1250+
delay(5);
1251+
}
1252+
}
1253+
1254+
void open_the_box() {
1255+
for (pos = 0; pos <= 90; pos += 1) { /* goes from 0 degrees to 90 degrees */
1256+
myservo.write(pos); /* tell servo to go to position in variable 'pos' */
1257+
delay(15); /* waits 15ms for the servo to reach the position */
1258+
}
1259+
}
1260+
1261+
void close_the_box() {
1262+
for (pos = 90; pos >= 0; pos -= 1) { /* goes from 90 degrees to 0 degrees */
1263+
myservo.write(pos); /* tell servo to go to position in variable 'pos' */
1264+
delay(15); /* waits 15ms for the servo to reach the position */
1265+
}
1266+
}
1267+
1268+
void initLCD() {
1269+
Serial.println(">>> begin LCD");
1270+
lcd.begin(16, 2);
1271+
lcd.print(" Initialising");
1272+
1273+
delay(100);
1274+
}
1275+
1276+
void onSliderOneChange() {
1277+
/* Add your code here to act upon SliderValue1 change */
1278+
Serial.print("New combination: ");
1279+
Serial.print(sliderOne);
1280+
Serial.print(" ");
1281+
Serial.print(sliderTwo);
1282+
Serial.print(" ");
1283+
Serial.println(sliderThree);
1284+
}
1285+
1286+
void onSliderTwoChange() {
1287+
/* Add your code here to act upon SliderValue2 change */
1288+
Serial.print("New combination: ");
1289+
Serial.print(sliderOne);
1290+
Serial.print(" ");
1291+
Serial.print(sliderTwo);
1292+
Serial.print(" ");
1293+
Serial.println(sliderThree);
1294+
}
1295+
1296+
void onSliderThreeChange() {
1297+
/* Add your code here to act upon SliderValue3 change */
1298+
Serial.print("New combination: ");
1299+
Serial.print(sliderOne);
1300+
Serial.print(" ");
1301+
Serial.print(sliderTwo);
1302+
Serial.print(" ");
1303+
Serial.println(sliderThree);
1304+
}
1305+
1306+
/* Send RGB values to the LED pins */
1307+
void setColor(int red, int green, int blue) {
1308+
analogWrite(redPin, red);
1309+
analogWrite(greenPin, green);
1310+
analogWrite(bluePin, blue);
1311+
}
1312+
1313+
void onDisplayChange() {
1314+
/* Add your code here to act upon Display change */
1315+
}
1316+
```
Loading

0 commit comments

Comments
 (0)