diff --git a/content/hardware/08.kits/maker/iot-bundle/compatibility.yml b/content/hardware/08.kits/maker/iot-bundle/compatibility.yml new file mode 100644 index 0000000000..fb978c4b11 --- /dev/null +++ b/content/hardware/08.kits/maker/iot-bundle/compatibility.yml @@ -0,0 +1,8 @@ +software: + - arduino-ide + - arduino-cli + - web-editor +hardware: + shields: ~ + carriers: ~ + boards: ~ \ No newline at end of file diff --git a/content/hardware/08.kits/maker/iot-bundle/features.md b/content/hardware/08.kits/maker/iot-bundle/features.md new file mode 100644 index 0000000000..5264bb7fd4 --- /dev/null +++ b/content/hardware/08.kits/maker/iot-bundle/features.md @@ -0,0 +1,47 @@ + + +The Arduino IoT Bundle includes 5 step by step tutorials that will get you started with the components in the bundle. They are found just below: + + + + + + + + + Create a pillow that sends your love with the help of the Arduino IoT Cloud! + + + + + + + Create a Puzzle Box with the help of the Arduino IoT Cloud! + + + + + + + Train your cat with the help of the Arduino IoT Cloud! + + + + + + + Create a desktop pet with the help of the Arduino IoT Cloud! + + + + + + + Create a plant communicator with the help of the Arduino IoT Cloud! + + + + + + + diff --git a/content/hardware/08.kits/maker/iot-bundle/image.svg b/content/hardware/08.kits/maker/iot-bundle/image.svg new file mode 100644 index 0000000000..4f8ca4abe9 --- /dev/null +++ b/content/hardware/08.kits/maker/iot-bundle/image.svg @@ -0,0 +1,631 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/content/hardware/08.kits/maker/iot-bundle/product.md b/content/hardware/08.kits/maker/iot-bundle/product.md new file mode 100644 index 0000000000..8504323444 --- /dev/null +++ b/content/hardware/08.kits/maker/iot-bundle/product.md @@ -0,0 +1,6 @@ +--- +title: IoT Bundle +url_shop: https://store.arduino.cc/iot-bundle +--- + +Arduino IoT Bundle allows you to build your next smart project. Ever wanted an automated house? Or a smart garden? Well, now it’s easy with the Arduino IoT Cloud compatible boards. It means: you can connect devices, visualize data, control and share your projects from anywhere in the world. Whether you’re a beginner or a pro, we have a wide range of plans to make sure you get the features you need. \ No newline at end of file diff --git a/content/hardware/08.kits/maker/iot-bundle/tech-specs.md b/content/hardware/08.kits/maker/iot-bundle/tech-specs.md new file mode 100644 index 0000000000..7b7001fd54 --- /dev/null +++ b/content/hardware/08.kits/maker/iot-bundle/tech-specs.md @@ -0,0 +1 @@ +Here you will find the technical specifications for the Arduino® IoT Bundle. \ No newline at end of file diff --git a/content/hardware/08.kits/maker/iot-bundle/tech-specs.yml b/content/hardware/08.kits/maker/iot-bundle/tech-specs.yml new file mode 100644 index 0000000000..81e760cbb9 --- /dev/null +++ b/content/hardware/08.kits/maker/iot-bundle/tech-specs.yml @@ -0,0 +1,33 @@ +Kit: + Name: Arduino® IoT Bundle + SKU: AKX00042 +Components: + Arduino Nano RP2040 Connect: 1x + micro USB cable: 1x + 400-point breadboard: 1x + solid-core jumper wires: 70x + stranded jumper wire: 2x + phototransistors: 6x + potentiometers (10k ohm): 3x + pushbuttons: 10x + temperature sensor (TMP36): 1x + tilt sensor: 1x + alphanumeric LCD (16 x 2 characters): 1x + bright white: 1x + LEDs (1 RGB, 8 red, 8 green, 8 yellow, 3 blue): 28x + small DC motor (6/9V): 1x + small servo motor: 1x + piezo capsule (PKM17EPP-4001-B0): 1x + H-bridge motor driver (L293D): 1x + optocouplers (4N35): 1x + MOSFET transistors (IRF520): 2x + capacitors (100uF): 5x + diodes (1N4007): 5x + male pin strip (40 x 1): 1x + resistors (220 ohm): 20x + resistors (560 ohm): 5x + resistors (1k ohm): 5x + resistors (4.7k ohm): 5x + resistors (10k ohm): 20x + resistors (1M ohm): 5x + resistors (10M ohm): 5x diff --git a/content/hardware/08.kits/maker/iot-bundle/tutorials/i-love-you-pillow/assets/_ypE8fl7Ln6.png b/content/hardware/08.kits/maker/iot-bundle/tutorials/i-love-you-pillow/assets/_ypE8fl7Ln6.png new file mode 100644 index 0000000000..9bdb53d850 Binary files /dev/null and b/content/hardware/08.kits/maker/iot-bundle/tutorials/i-love-you-pillow/assets/_ypE8fl7Ln6.png differ diff --git a/content/hardware/08.kits/maker/iot-bundle/tutorials/i-love-you-pillow/assets/circuit_tLcnUy2ifl.png b/content/hardware/08.kits/maker/iot-bundle/tutorials/i-love-you-pillow/assets/circuit_tLcnUy2ifl.png new file mode 100644 index 0000000000..690890f972 Binary files /dev/null and b/content/hardware/08.kits/maker/iot-bundle/tutorials/i-love-you-pillow/assets/circuit_tLcnUy2ifl.png differ diff --git a/content/hardware/08.kits/maker/iot-bundle/tutorials/i-love-you-pillow/assets/love-you-pillow-01_VoyWPl8L6l.gif b/content/hardware/08.kits/maker/iot-bundle/tutorials/i-love-you-pillow/assets/love-you-pillow-01_VoyWPl8L6l.gif new file mode 100644 index 0000000000..1c2fb0301a Binary files /dev/null and b/content/hardware/08.kits/maker/iot-bundle/tutorials/i-love-you-pillow/assets/love-you-pillow-01_VoyWPl8L6l.gif differ diff --git a/content/hardware/08.kits/maker/iot-bundle/tutorials/i-love-you-pillow/assets/love-you-pillow-02_ydUsouV4bl.gif b/content/hardware/08.kits/maker/iot-bundle/tutorials/i-love-you-pillow/assets/love-you-pillow-02_ydUsouV4bl.gif new file mode 100644 index 0000000000..59211a7034 Binary files /dev/null and b/content/hardware/08.kits/maker/iot-bundle/tutorials/i-love-you-pillow/assets/love-you-pillow-02_ydUsouV4bl.gif differ diff --git a/content/hardware/08.kits/maker/iot-bundle/tutorials/i-love-you-pillow/assets/pillow2-cover_eWFrQi0MOT.png b/content/hardware/08.kits/maker/iot-bundle/tutorials/i-love-you-pillow/assets/pillow2-cover_eWFrQi0MOT.png new file mode 100644 index 0000000000..911c43a67a Binary files /dev/null and b/content/hardware/08.kits/maker/iot-bundle/tutorials/i-love-you-pillow/assets/pillow2-cover_eWFrQi0MOT.png differ diff --git a/content/hardware/08.kits/maker/iot-bundle/tutorials/i-love-you-pillow/assets/screenshot_2022-03-30_at_14_26_54_stYUq5y7c2.png b/content/hardware/08.kits/maker/iot-bundle/tutorials/i-love-you-pillow/assets/screenshot_2022-03-30_at_14_26_54_stYUq5y7c2.png new file mode 100644 index 0000000000..314310f88e Binary files /dev/null and b/content/hardware/08.kits/maker/iot-bundle/tutorials/i-love-you-pillow/assets/screenshot_2022-03-30_at_14_26_54_stYUq5y7c2.png differ diff --git a/content/hardware/08.kits/maker/iot-bundle/tutorials/i-love-you-pillow/assets/screenshot_2022-11-23_140745_adGbm9cDej.png b/content/hardware/08.kits/maker/iot-bundle/tutorials/i-love-you-pillow/assets/screenshot_2022-11-23_140745_adGbm9cDej.png new file mode 100644 index 0000000000..4e7b7c2bcb Binary files /dev/null and b/content/hardware/08.kits/maker/iot-bundle/tutorials/i-love-you-pillow/assets/screenshot_2022-11-23_140745_adGbm9cDej.png differ diff --git a/content/hardware/08.kits/maker/iot-bundle/tutorials/i-love-you-pillow/content.md b/content/hardware/08.kits/maker/iot-bundle/tutorials/i-love-you-pillow/content.md new file mode 100644 index 0000000000..a81a413f30 --- /dev/null +++ b/content/hardware/08.kits/maker/iot-bundle/tutorials/i-love-you-pillow/content.md @@ -0,0 +1,346 @@ +--- +title: "I Love You Pillow with the Arduino IoT Bundle" +description: "Open source is love, and so are hugs!" +coverImage: "assets/_ypE8fl7Ln6.png" +tags: [IoT Cloud, IoT Bundle, Capacitance] +author: "Arduino_Genuino" +source: "https://create.arduino.cc/projecthub/Arduino_Genuino/i-love-you-pillow-with-the-arduino-iot-bundle-cec4c4" +--- + +## Components and Supplies + +- [Arduino IoT Bundle](https://store.arduino.cc/iot-bundle) + +## Apps and Online Services + +- [Arduino IoT Cloud](https://cloud.arduino.cc) +- [Arduino IoT Cloud Remote app](https://play.google.com/store/apps/details?id=cc.arduino.cloudiot&hl=en&gl=US) + +## About This Project + +**Create a pillow that sends your love with the help of the Arduino IoT Cloud!** + +We all know that being without that special person in your life can be difficult, but what if you could send love and affection remotely over the Internet by just hugging a pillow? + +Now, we can't really send hugs... but what we can send is a sweet emoji through a messaging app, triggered by you giving a pillow a hug. + +When you hug the **I Love You Pillow** you will hear the sound of a heartbeat coming from the buzzer inside. Depending on the length of your hug, a different emoji will be sent to a chat box in the Arduino IoT Cloud Remote app. + +Stay in touch with your loved one with this huggable device! + +### In a Nutshell + +In this experiment, we will use aluminium foil to create a DIY capacitive sensor that will be used to detect hugs. By hugging the pillow you can send loving emojis to your beloved. + +### Components + +* Buzzer +* Aluminium foil +* 1 resistor 5M ohm + +![Show your love with a hug!](assets/pillow2-cover_eWFrQi0MOT.png) + +Show your love with a hug! + +### Learning Goals + +* Introducing the Arduino IoT Cloud +* Introducing the Arduino IoT Remote app +* Managing capacitive sensors +* Creating an Arduino IoT Cloud Dashboard +* Sharing dashboards **#ProTips** + +**Pro Tips** are useful but not strictly necessary steps that add a layer of complexity to the project. + +### Want to Know More? + +This tutorial is part of a series of experiments that familiarize you with the Arduino RP2040 and IoT. All experiments can be built using the components contained in the IoT Bundle. + +* [Puzzle Box with Arduino IoT Bundle](/tutorials/iot-bundle/puzzlebox) +* [Pavlov's Cat with the Arduino IoT Bundle](/tutorials/iot-bundle/pavlovs-cat) +* [Plant Communicator with the Arduino IoT Bundle](/tutorials/iot-bundle/plant-communicator) +* [The Nerd with the Arduino IoT Bundle](/tutorials/iot-bundle/the-nerd) + +### Circuit + +In this project, we will be using the following circuit. In it, we have a piezo speaker connected to pin 8, a 5M ohm resistor connected between A0 and A1, with jumper wires connected to the tin foil. + +![Arduino IoT Bundle](assets/circuit_tLcnUy2ifl.png) + +### Setting up the Arduino IoT Cloud + +If you are new to the Arduino IoT Cloud, check out our [Getting Started Guide](https://docs.arduino.cc/arduino-cloud/getting-started/iot-cloud-getting-started). + +**We will start by setting up the Arduino IoT Cloud by following the steps below:** + +* Login to your **Arduino Create account** +* Creating a **Thing** +* Attaching a **Device** +* Adding the following **Variables** +* Adding **Network** credentials + +![Arduino IoT Bundle](assets/love-you-pillow-01_VoyWPl8L6l.gif) + +### Variables + +We will start by adding these variables: + +![Arduino IoT Bundle](assets/screenshot_2022-11-23_140745_adGbm9cDej.png) + +### Programming Overview + +We will gradually build the code for the project. There are three steps to this: + +* Testing the chat function. +* Sending hugs to the cloud. +* The heartbeat (Final Sketch) + +In each of the sections, a separate code is provided. If you have created the variables in the Thing interface correctly, the code presented can simply be copy and pasted into the cloud editor, and be uploaded to your board. + +If you want to skip ahead to the final part, go to the **The Heartbeat** section which has the final sketch. + +**Testing the Chat Function** + +The first part in this project is to test out the **chat functionality.** The sketch below checks for whenever the string `<3` is received via the Arduino messenger widget, and sends back a heart emoji. + +In order to send an emoji we will need to use **UNICODE** characters.For instance to send an heart emoji we will use “\\U00002764”. You can see the full list of unicode emoji codes [here.](https://unicode.org/emoji/charts/full-emoji-list.html) + +``` +#include "thingProperties.h" +void setup() { + // Initialize serial and wait for port to open: + Serial.begin(9600); + delay(1500); + // Defined in thingProperties.h + initProperties(); + // Connect to Arduino IoT Cloud + ArduinoCloud.begin(ArduinoIoTPreferredConnection); + setDebugMessageLevel(2); + ArduinoCloud.printDebugInfo(); +} +void loop() { + ArduinoCloud.update(); + if (chat == +" + <3 +" +) { + chat = "\U00002764"; + } +} +void onChatChange() { +//this function is automatically generated +} +void onHeartBeatChange() { +//this function is automatically generated +} +void onPressedChange() { +//this function is automatically generated +} +``` + +After uploading the sketch above to your **Nano RP2040 Connect** board, you need to create a messenger widget where you can send and receive messages. To achieve that, navigate to **Arduino IoT Cloud -> Dashboards -> Build Dashboard -> Add -> Messenger Widget**. + +Now, you can try it out! Send `<3` via the messenger chat, and you should receive a heart. The "heart response" is sent from the physical Arduino board, and if it works, we know the connection between the Arduino Cloud and your Arduino is working! + +![Arduino IoT Bundle](assets/screenshot_2022-03-30_at_14_26_54_stYUq5y7c2.png) + +**Sending Hugs to the Cloud** + +We also want to be able to "send hugs" from the Arduino to the Arduino Cloud, and we will do so by measuring capacitance. In a nutshell, we will build a simple capacitance meter, using **tinfoil&jumperwires** connected to analog inputs. + +The tinfoil will be placed inside a pillow, and when we squeeze the pillow, the capacitance will change. When the capacitance change, we will change a boolean **(pressed)** to **true**, which will be visible in a dashboard. + +Upload the example sketch, connect the wires and see the result on the console: + +``` +#include "thingProperties.h" +void setup() { + // Initialize serial and wait for port to open: + Serial.begin(9600); + delay(1500); + // Defined in thingProperties.h + initProperties(); + // Connect to Arduino IoT Cloud + ArduinoCloud.begin(ArduinoIoTPreferredConnection); + setDebugMessageLevel(2); + ArduinoCloud.printDebugInfo(); +} +void loop() { + ArduinoCloud.update(); + if (chat == +" + <3 +" +) { + chat = "\U00002764"; + } + + int reading = analogRead(A0); + + //threshold set to 500, this can be adjusted to your liking + if(reading > 500){ + pressed = true; +} +else{ + pressed = false; +} +} +void onChatChange() { +//this function is automatically generated +} +void onHeartBeatChange() { +//this function is automatically generated +} +void onPressedChange() { +//this function is automatically generated +} +``` + +**The Heartbeat (and Final Sketch)** + +The longer you hug, the more heartbeats you hear. The more the heart beats the more love you send (and different emoji, as well). + +We will emulate the sound of a heartbeat using a buzzer and a few simple lines of code. + +``` +#include "thingProperties.h" +int Buzzer = 8; +void setup() { + // Initialize serial and wait for port to open: + Serial.begin(9600); + delay(1500); + // Defined in thingProperties.h + initProperties(); + // Connect to Arduino IoT Cloud + ArduinoCloud.begin(ArduinoIoTPreferredConnection); + setDebugMessageLevel(2); + ArduinoCloud.printDebugInfo(); +} +void loop() { + ArduinoCloud.update(); + if (chat == +" + <3 +" +) { + chat = "\U00002764"; + } + + int reading = analogRead(A0); + + //threshold set to 500, this can be adjusted to your liking + if(reading > 500){ + pressed = true; + + //execute the activateBuzzer() function when threshold is being met. + activateBuzzer(); + heart_beat +=1; //increase heart_beat value for every "heart beat". +} +else{ + pressed = false; +} +} +void activateBuzzer() { + tone(Buzzer, 31, 200); // tone(Pin, Note, Duration); + delay(200); + tone(Buzzer, 31, 400); + delay(200); + noTone(Buzzer); + delay(1000); +} +void onChatChange() { +//this function is automatically generated +} +void onHeartBeatChange() { +//this function is automatically generated +} +void onPressedChange() { +//this function is automatically generated +} +``` + +### Dashboard + +Finally, we need to build a dashboard to communicate with our loved one. In addition to the messenger widget we added to our dashboard, we will add two more widgets: + +* A Gauge widget linked to the “heart\_beat” variable +* A LED widget linked to the “pressed” variable + +![Arduino IoT Bundle](assets/love-you-pillow-02_ydUsouV4bl.gif) + +Next, you need to download the Arduino IoT Cloud Remote app. Both iOS and Android versions are available and can be downloaded for free from the [App Store ](https://apps.apple.com/us/app/id1514358431)and [Google Play.](https://play.google.com/store/apps/details?id=cc.arduino.cloudiot) The app can be used to display and interact with your Dashboards. + +After downloading the app on the device of your loved one, you can login with your Arduino Create account and open your “love-you-pillow” dashboard. Now your loved one can use the app to send and receive hugs from you virtually, via the Love You Pillow! + +### #ProTip: Shareable Dashboards + +Instead of logging into your account on the Arduino IoT Cloud Remote app, you can share your dashboards with any number with friends. This feature is only available if you have [the Arduino Maker subscription.](https://cloud.arduino.cc/plans?) + +### Want to Know More? + +This tutorial is part of a series of experiments that familiarize you with the Arduino RP2040 and IoT. All experiments can be built using the components contained in the IoT Bundle. + +* [Puzzle Box with Arduino IoT Bundle](/tutorials/iot-bundle/puzzlebox) +* [Pavlov's Cat with the Arduino IoT Bundle](/tutorials/iot-bundle/pavlovs-cat) +* [Plant Communicator with the Arduino IoT Bundle](/tutorials/iot-bundle/plant-communicator) +* [The Nerd with the Arduino IoT Bundle](/tutorials/iot-bundle/the-nerd) + +## Full Code + +```arduino +#include "thingProperties.h" +int Buzzer = 8; +void setup() { + // Initialize serial and wait for port to open: + Serial.begin(9600); + delay(1500); + // Defined in thingProperties.h + initProperties(); + // Connect to Arduino IoT Cloud + ArduinoCloud.begin(ArduinoIoTPreferredConnection); + setDebugMessageLevel(2); + ArduinoCloud.printDebugInfo(); +} +void loop() { + ArduinoCloud.update(); + if (chat == +" + <3 +" +) { + chat = "\U00002764"; + } + + int reading = analogRead(A0); + + //threshold set to 500, this can be adjusted to your liking + if(reading > 500){ + pressed = true; + + //execute the activateBuzzer() function when threshold is being met. + activateBuzzer(); + heart_beat +=1; //increase heart_beat value for every "heart beat". +} +else{ + pressed = false; +} +} +void activateBuzzer() { + tone(Buzzer, 31, 200); // tone(Pin, Note, Duration); + delay(200); + tone(Buzzer, 31, 400); + delay(200); + noTone(Buzzer); + delay(1000); +} +void onChatChange() { +//this function is automatically generated +} +void onHeartBeatChange() { +//this function is automatically generated +} +void onPressedChange() { +//this function is automatically generated +} +``` \ No newline at end of file diff --git a/content/hardware/08.kits/maker/iot-bundle/tutorials/i-love-you-pillow/hero-banner.png b/content/hardware/08.kits/maker/iot-bundle/tutorials/i-love-you-pillow/hero-banner.png new file mode 100644 index 0000000000..797eef9a56 Binary files /dev/null and b/content/hardware/08.kits/maker/iot-bundle/tutorials/i-love-you-pillow/hero-banner.png differ diff --git a/content/hardware/08.kits/maker/iot-bundle/tutorials/pavlovs-cat/assets/_mV3ZK8zeAh.png b/content/hardware/08.kits/maker/iot-bundle/tutorials/pavlovs-cat/assets/_mV3ZK8zeAh.png new file mode 100644 index 0000000000..9db6acc193 Binary files /dev/null and b/content/hardware/08.kits/maker/iot-bundle/tutorials/pavlovs-cat/assets/_mV3ZK8zeAh.png differ diff --git a/content/hardware/08.kits/maker/iot-bundle/tutorials/pavlovs-cat/assets/gif-cat_vCx1OHLrzl.gif b/content/hardware/08.kits/maker/iot-bundle/tutorials/pavlovs-cat/assets/gif-cat_vCx1OHLrzl.gif new file mode 100644 index 0000000000..f4a552639d Binary files /dev/null and b/content/hardware/08.kits/maker/iot-bundle/tutorials/pavlovs-cat/assets/gif-cat_vCx1OHLrzl.gif differ diff --git a/content/hardware/08.kits/maker/iot-bundle/tutorials/pavlovs-cat/assets/light_rp2040_w373rVgQAw.png b/content/hardware/08.kits/maker/iot-bundle/tutorials/pavlovs-cat/assets/light_rp2040_w373rVgQAw.png new file mode 100644 index 0000000000..48ef5b3085 Binary files /dev/null and b/content/hardware/08.kits/maker/iot-bundle/tutorials/pavlovs-cat/assets/light_rp2040_w373rVgQAw.png differ diff --git a/content/hardware/08.kits/maker/iot-bundle/tutorials/pavlovs-cat/assets/palvov-cat-01_FHBOz5Z3MA.gif b/content/hardware/08.kits/maker/iot-bundle/tutorials/pavlovs-cat/assets/palvov-cat-01_FHBOz5Z3MA.gif new file mode 100644 index 0000000000..d9a075d5a9 Binary files /dev/null and b/content/hardware/08.kits/maker/iot-bundle/tutorials/pavlovs-cat/assets/palvov-cat-01_FHBOz5Z3MA.gif differ diff --git a/content/hardware/08.kits/maker/iot-bundle/tutorials/pavlovs-cat/assets/palvov-cat-02.gif b/content/hardware/08.kits/maker/iot-bundle/tutorials/pavlovs-cat/assets/palvov-cat-02.gif new file mode 100644 index 0000000000..767f8534ae Binary files /dev/null and b/content/hardware/08.kits/maker/iot-bundle/tutorials/pavlovs-cat/assets/palvov-cat-02.gif differ diff --git a/content/hardware/08.kits/maker/iot-bundle/tutorials/pavlovs-cat/assets/palvov-cat-03_EJSoVjN9qB.gif b/content/hardware/08.kits/maker/iot-bundle/tutorials/pavlovs-cat/assets/palvov-cat-03_EJSoVjN9qB.gif new file mode 100644 index 0000000000..a06ea07923 Binary files /dev/null and b/content/hardware/08.kits/maker/iot-bundle/tutorials/pavlovs-cat/assets/palvov-cat-03_EJSoVjN9qB.gif differ diff --git a/content/hardware/08.kits/maker/iot-bundle/tutorials/pavlovs-cat/assets/piezo_buzzer_rp2040_whR92Z3Wgx.png b/content/hardware/08.kits/maker/iot-bundle/tutorials/pavlovs-cat/assets/piezo_buzzer_rp2040_whR92Z3Wgx.png new file mode 100644 index 0000000000..f8bc6a6bde Binary files /dev/null and b/content/hardware/08.kits/maker/iot-bundle/tutorials/pavlovs-cat/assets/piezo_buzzer_rp2040_whR92Z3Wgx.png differ diff --git a/content/hardware/08.kits/maker/iot-bundle/tutorials/pavlovs-cat/assets/screenshot_2022-11-23_141459_JVW8zmmeP0.png b/content/hardware/08.kits/maker/iot-bundle/tutorials/pavlovs-cat/assets/screenshot_2022-11-23_141459_JVW8zmmeP0.png new file mode 100644 index 0000000000..8bb5e3493e Binary files /dev/null and b/content/hardware/08.kits/maker/iot-bundle/tutorials/pavlovs-cat/assets/screenshot_2022-11-23_141459_JVW8zmmeP0.png differ diff --git a/content/hardware/08.kits/maker/iot-bundle/tutorials/pavlovs-cat/assets/servo_motor_rp2040_PAcv0Yejb2.png b/content/hardware/08.kits/maker/iot-bundle/tutorials/pavlovs-cat/assets/servo_motor_rp2040_PAcv0Yejb2.png new file mode 100644 index 0000000000..0037780b6c Binary files /dev/null and b/content/hardware/08.kits/maker/iot-bundle/tutorials/pavlovs-cat/assets/servo_motor_rp2040_PAcv0Yejb2.png differ diff --git a/content/hardware/08.kits/maker/iot-bundle/tutorials/pavlovs-cat/content.md b/content/hardware/08.kits/maker/iot-bundle/tutorials/pavlovs-cat/content.md new file mode 100644 index 0000000000..1179a967c6 --- /dev/null +++ b/content/hardware/08.kits/maker/iot-bundle/tutorials/pavlovs-cat/content.md @@ -0,0 +1,576 @@ +--- +title: "Pavlovs Cat with Arduino IoT Bundle" +description: "Time to get Pavlovian on your cat!" +coverImage: "assets/_mV3ZK8zeAh.png" +tags: [IoT Cloud, Home Automation, Pets] +author: "Arduino_Genuino" +source: "https://create.arduino.cc/projecthub/Arduino_Genuino/pavlov-s-cat-with-arduino-iot-bundle-d5b388" +--- + +## Components and Supplies + +- [Arduino IoT Bundle](https://store.arduino.cc/iot-bundle) +- 9V battery (generic) +- [9V Battery Clip](https://www.newark.com/22C4351?COM=ref_hackster) + +## Apps and Online Services + +- [Arduino IoT Cloud](https://cloud.arduino.cc) +- [Arduino IoT Cloud Remote app](https://play.google.com/store/apps/details?id=cc.arduino.cloudiot&hl=en&gl=US) + +## About This Project + +**Train your cat with the help of the Arduino IoT Cloud!** + +If you ever tried to train a cat, you know how hard it is. Cats are their own masters, but now you have the chance to let the cats do your bidding using this IoT-enabled device. + +**Welcome to Pavlov's Cat Experiment!** + +In this project, you will learn how to teach your cat when it is (and isn't) dinner time using nothing but the components in the IoT Bundle and some cardboard. + +And we all know that cats already love cardboard boxes! Every time the cat hears a certain melody, it receives food. A light sensor detects the presence of a cat. + +Another melody does nothing. See how this will work? You will be able to monitor your cat's progression over time and set the food dispensing rate from your phone. + +**Disclaimer:** **No cats were hurt in the development of this experiment. Also, no guarantee that the cat will eat the food, but you get the picture, right?** + +### In a Nutshell + +You will be able to build your own food dispenser by following these simple step-by-step instructions. The dispenser is basically just some cardboard and a servo motor with some added Arduino magic. + +Using the Arduino IoT Cloud Dashboard, you can set the amount of food to be dispensed and trigger the melodies played with the buzzer. + +A light sensor is used to detect if the cat reacted to the melody and got to the food. + +**Get the cardboard blueprint for this project** [here!](https://hacksterio.s3.amazonaws.com/uploads/attachments/387170/pavlovcase_ShVm1OJRIF.dxf) + +### Components + +* Servo moto +* Phototransistor +* 220 ohm resistor +* Buzzer + +![Arduino IoT Bundle](assets/gif-cat_vCx1OHLrzl.gif) + +### Learning Goals + +In this experiment you will learn how to: + +* Introducing the Arduino IoT Cloud +* Introducing the Arduino IoT Remote app +* Play a melody using your Arduino +* Include additional tabs in your code +* Creating an Arduino IoT Cloud Dashboard + +### Want to Know More? + +This tutorial is part of a series of experiments that familiarize you with the Arduino RP2040 and IoT. All experiments can be built using the components contained in the IoT Bundle. + +* [I Love You Pillow with Arduino IoT Bundle ](/tutorials/iot-bundle/i-love-you-pillow) +* [Puzzle Box with Arduino IoT Bundle ](/tutorials/iot-bundle/puzzlebox) +* [Plant Communicator with the Arduino IoT Bundle ](/tutorials/iot-bundle/plant-communicator) +* [The Nerd with the Arduino IoT Bundle](/tutorials/iot-bundle/the-nerd) + +### Setting up the Arduino IoT Cloud + +If you are new to the Arduino IoT Cloud, check out our [Getting Started Guide](https://docs.arduino.cc/arduino-cloud/getting-started/iot-cloud-getting-started). + +**We will start by setting up the Arduino IoT Cloud by following the steps below:** + +* **Login** to your Arduino Create account +* Creating a **Thing** +* Attaching a **Device** +* Adding **Variables** +* Adding **Network** credentials + +![Arduino IoT Bundle](assets/palvov-cat-01_FHBOz5Z3MA.gif) + +### Variables + +We wills start by adding four variables: + +![Arduino IoT Bundle](assets/screenshot_2022-11-23_141459_JVW8zmmeP0.png) + +### Setup Hardware & Sketch + +**Play the Song** + +The next section explains how to play a melody using a piezo buzzer and your Arduino. + +![Arduino IoT Bundle](assets/piezo_buzzer_rp2040_whR92Z3Wgx.png) + +Connect the buzzer to **digital pin 7**, as shown in the picture above. 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 `"pitches.h"`. See the GIF below for more detailed steps: + +![Arduino IoT Bundle](assets/palvov-cat-02.gif) + +Paste the following code into `"pitches.h"`. + +```arduino +#define NOTE_B0 31 +#define NOTE_C1 33 +#define NOTE_CS1 35 +#define NOTE_D1 37 +#define NOTE_DS1 39 +#define NOTE_E1 41 +#define NOTE_F1 44 +#define NOTE_FS1 46 +#define NOTE_G1 49 +#define NOTE_GS1 52 +#define NOTE_A1 55 +#define NOTE_AS1 58 +#define NOTE_B1 62 +#define NOTE_C2 65 +#define NOTE_CS2 69 +#define NOTE_D2 73 +#define NOTE_DS2 78 +#define NOTE_E2 82 +#define NOTE_F2 87 +#define NOTE_FS2 93 +#define NOTE_G2 98 +#define NOTE_GS2 104 +#define NOTE_A2 110 +#define NOTE_AS2 117 +#define NOTE_B2 123 +#define NOTE_C3 131 +#define NOTE_CS3 139 +#define NOTE_D3 147 +#define NOTE_DS3 156 +#define NOTE_E3 165 +#define NOTE_F3 175 +#define NOTE_FS3 185 +#define NOTE_G3 196 +#define NOTE_GS3 208 +#define NOTE_A3 220 +#define NOTE_AS3 233 +#define NOTE_B3 247 +#define NOTE_C4 262 +#define NOTE_CS4 277 +#define NOTE_D4 294 +#define NOTE_DS4 311 +#define NOTE_E4 330 +#define NOTE_F4 349 +#define NOTE_FS4 370 +#define NOTE_G4 392 +#define NOTE_GS4 415 +#define NOTE_A4 440 +#define NOTE_AS4 466 +#define NOTE_B4 494 +#define NOTE_C5 523 +#define NOTE_CS5 554 +#define NOTE_D5 587 +#define NOTE_DS5 622 +#define NOTE_E5 659 +#define NOTE_F5 698 +#define NOTE_FS5 740 +#define NOTE_G5 784 +#define NOTE_GS5 831 +#define NOTE_A5 880 +#define NOTE_AS5 932 +#define NOTE_B5 988 +#define NOTE_C6 1047 +#define NOTE_CS6 1109 +#define NOTE_D6 1175 +#define NOTE_DS6 1245 +#define NOTE_E6 1319 +#define NOTE_F6 1397 +#define NOTE_FS6 1480 +#define NOTE_G6 1568 +#define NOTE_GS6 1661 +#define NOTE_A6 1760 +#define NOTE_AS6 1865 +#define NOTE_B6 1976 +#define NOTE_C7 2093 +#define NOTE_CS7 2217 +#define NOTE_D7 2349 +#define NOTE_DS7 2489 +#define NOTE_E7 2637 +#define NOTE_F7 2794 +#define NOTE_FS7 2960 +#define NOTE_G7 3136 +#define NOTE_GS7 3322 +#define NOTE_A7 3520 +#define NOTE_AS7 3729 +#define NOTE_B7 3951 +#define NOTE_C8 4186 +#define NOTE_CS8 4435 +#define NOTE_D8 4699 +#define NOTE_DS8 4978 +/* notes in the melody */ +int melodyOne[] = { +NOTE_C4, NOTE_G3, NOTE_G3, NOTE_A3, NOTE_G3, 0, NOTE_B3, NOTE_C4 +}; +/* note durations: 4 = quarter note, 8 = eighth note, etc. */ +int noteDurationsOne[] = { +4, 8, 8, 4, 4, 4, 4, 4 +}; +int melodyTwo[] = { +NOTE_C5, NOTE_C5, NOTE_A4, NOTE_C5, 0, NOTE_G4, NOTE_C5, NOTE_F5, NOTE_E5, NOTE_C5, NOTE_C5 +}; +/* note durations: 4 = quarter note, 8 = eighth note, etc. */ +int noteDurationsTwo[] = { +2, 2, 4, 4, 8, 4, 4, 4, 4, 4 , 4 +}; +``` + +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 "pitches.h"` at the top of our code. + +Inside **setup()** we need to add our **buzzerPin** as **Output.** At the bottom of the code we will add a function called **playMelody()** with three parameters: **melody,durations** and **numberOfNotes.** + +To test our melody we can call the playMelody function inside **loop()** with our parameters in place. + +```arduino +void loop() { + playMelody(melodyOne, noteDurationsOne, 8); + delay(5000); +} +``` + +Copy the code below to test the melody + +```arduino +#include "thingProperties.h" +#include "pitches.h" +int buzzerPin = 7; +void setup() { + /* Initialize serial and wait for port to open: */ + Serial.begin(9600); + /* This delay gives the chance to wait for a Serial Monitor without blocking if none is found */ + delay(1500); + pinMode(buzzerPin, OUTPUT); + /* Defined in thingProperties.h */ + initProperties(); + /* Connect to Arduino IoT Cloud */ + ArduinoCloud.begin(ArduinoIoTPreferredConnection); + +/* +The following function allows you to obtain more information +related to the state of network and IoT Cloud connection and errors +the higher number the more granular information you’ll get. +The default is 0 (only errors). +Maximum is 4 +*/ +setDebugMessageLevel(2); +ArduinoCloud.printDebugInfo(); +} +void loop() { + ArduinoCloud.update(); + playMelody(melodyOne, noteDurationsOne, 8); + delay(5000); +} +void playMelody(int melody[], int noteDurations[], int numberOfNotes ) { + Serial.println("Playing melody"); + for (int thisNote = 0; thisNote < numberOfNotes; thisNote++) { + /* to calculate the note duration, take one second divided by the note type. + e.g. quarter note = 1000 / 4, eighth note = 1000/8, etc. */ + int noteDuration = 1000 / noteDurations[thisNote]; + tone(buzzerPin, melody[thisNote], noteDuration); + /* to distinguish the notes, set a minimum time between them. + the note's duration + 30% seems to work well */ + int pauseBetweenNotes = noteDuration * 1.30; + delay(pauseBetweenNotes); + /* stop the tone playing */ + noTone(buzzerPin); + } +} +/* +Since Notification is READ_WRITE variable, onNotificationChange() is +executed every time a new value is received from IoT Cloud. +*/ +void onNotificationChange() { +/* Add your code here to act upon Notification change */ +} +/* +Since SendData is READ_WRITE variable, onSendDataChange() is +executed every time a new value is received from IoT Cloud. +*/ +void onSendDataChange() { +/* Add your code here to act upon SendData change */ +} +/* +Since Portion is READ_WRITE variable, onPortionChange() is +executed every time a new value is received from IoT Cloud. +*/ +void onPortionChange() { +/* Add your code here to act upon Portion change */ +} +/* +Since Melody is READ_WRITE variable, onMelodyChange() is +executed every time a new value is received from IoT Cloud. +*/ +void onMelodyChange() { +/* Add your code here to act upon Melody change */ +} +``` + +**Detect the Cat!** + +In order to detect the presence of the cat we will use a **phototransistor**, which is able to measure the light intensity and therefore if someone has passed close to it. Connect the sensor to the **A0 pin** as shown below. + +![Arduino IoT Bundle](assets/light_rp2040_w373rVgQAw.png) + +**Note that we used a 220 ohm resistor.** + +To read values from the sensor we will only need to assign a **variable** to **analogRead(A0)**. Since we are interested in detecting the cat presence only after the melody, and just for a certain amount of time we can use the following logic: + +```arduino +#include "thingProperties.h" +#include "pitches.h" +int buzzerPin = 7; +unsigned long timer; +bool startDetecting = true; +int threshold = 200; +void setup() { + /* Initialize serial and wait for port to open: */ + Serial.begin(9600); + /* This delay gives the chance to wait for a Serial Monitor without blocking if none is found */ + delay(1500); + + pinMode(buzzerPin, OUTPUT); + timer = millis(); + + /* Defined in thingProperties.h */ + initProperties(); + + /* Connect to Arduino IoT Cloud */ + ArduinoCloud.begin(ArduinoIoTPreferredConnection); +/* +The following function allows you to obtain more information +related to the state of network and IoT Cloud connection and errors +the higher number the more granular information you’ll get. +The default is 0 (only errors). +Maximum is 4 +*/ +setDebugMessageLevel(2); +ArduinoCloud.printDebugInfo(); +} +void loop() { + ArduinoCloud.update(); + + if (startDetecting) { + int value = analogRead(A0); + if (value < threshold) { + Serial.println("cat detected!"); + startDetecting = false; + } else if (millis() - timer < 12000) { + Serial.println("no cat detected in the past two minutes"); + startDetecting = false; + } + } +} +void playMelody(int melody[], int noteDurations[], int numberOfNotes ) { + Serial.println("Playing melody"); + for (int thisNote = 0; thisNote < numberOfNotes; thisNote++) { + /* to calculate the note duration, take one second divided by the note type. + e.g. quarter note = 1000 / 4, eighth note = 1000/8, etc. */ + int noteDuration = 1000 / noteDurations[thisNote]; + tone(buzzerPin, melody[thisNote], noteDuration); + /* to distinguish the notes, set a minimum time between them. + the note's duration + 30% seems to work well */ + int pauseBetweenNotes = noteDuration * 1.30; + delay(pauseBetweenNotes); + /* stop the tone playing */ + noTone(buzzerPin); + } +} +/* +Since Notification is READ_WRITE variable, onNotificationChange() is +executed every time a new value is received from IoT Cloud. +*/ +void onNotificationChange() { +/* Add your code here to act upon Notification change */ +} +/* +Since SendData is READ_WRITE variable, onSendDataChange() is +executed every time a new value is received from IoT Cloud. +*/ +void onSendDataChange() { +/* Add your code here to act upon SendData change */ +} +/* +Since Portion is READ_WRITE variable, onPortionChange() is +executed every time a new value is received from IoT Cloud. +*/ +void onPortionChange() { +/* Add your code here to act upon Portion change */ +} +/* +Since Melody is READ_WRITE variable, onMelodyChange() is +executed every time a new value is received from IoT Cloud. +*/ +void onMelodyChange() { +/* Add your code here to act upon Melody change */ +} +``` + +Note that we use themillis()function to set a timer. `millis()` gives us the time in milliseconds since the board was up and running. We can use it to set timers and trigger events after a certain amount of time. + +**We also use a threshold** to determine if the cat was detected. That threshold is arbitrary, you can set it according to your light condition. + +**Add the Servo Motor** + +> **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. + +The servo is used to open the box and deliver food. Note that we will use the portion variable to set the amount of time the servo has to remain turned 90 degrees. We will be able to change the portion value through the Arduino IoT Cloud Dashboard. + +![Arduino IoT Bundle](assets/servo_motor_rp2040_PAcv0Yejb2.png) + +Attach the **servo** to **pin 6** as shown above. To control the will make us of the servo library by adding `#include "servo.h"` at the top. We also need to initialize a variable setting the starting position of the servo by adding `Servo myservo` under our libraries and inside `setup()` add `myservo.attach(6)` which tells the program which pin we are using. + +Inside the **loop()** function we also need to change some things as we put the project together. We only want to dispense food if the portion size is set and the melody has been played. We also want to start detecting if a cat is approaching and log the time it needed to arrive to the serial port. + +Finally, we can add a function below `playMelody()` called `moveServo()`. + +``` +#include "thingProperties.h" +#include "pitches.h" +#include "Servo.h" +Servo myservo; +int pos = 0; +int buzzerPin = 7; +unsigned long timer; +bool startDetecting = true; +int threshold = 200; +void setup() { + /* Initialize serial and wait for port to open: */ + Serial.begin(9600); + /* This delay gives the chance to wait for a Serial Monitor without blocking if none is found */ + delay(1500); + + pinMode(buzzerPin, OUTPUT); + timer = millis(); + + /* Defined in thingProperties.h */ + initProperties(); + + /* Connect to Arduino IoT Cloud */ + ArduinoCloud.begin(ArduinoIoTPreferredConnection); +/* +The following function allows you to obtain more information +related to the state of network and IoT Cloud connection and errors +the higher number the more granular information you’ll get. +The default is 0 (only errors). +Maximum is 4 +*/ +setDebugMessageLevel(2); +ArduinoCloud.printDebugInfo(); +} +void loop() { + ArduinoCloud.update(); + if (sendData) { /* Checks if there are some updates */ + if (melody) { + if (portion > 0) { /* if Melody AND food */ + notification = "Dispensing " + String(portion) + " portion of food right now"; /* notification of dispensed food */ + playMelody(melodyOne, noteDurationsOne, 8); + moveServo(); + startDetecting = true; + timer = millis(); + } else if (portion == 0) { /* if Melody and NO food */ + notification = "At your command"; + playMelody(melodyTwo, noteDurationsTwo, 11); + startDetecting = true; + timer = millis(); + } + } else if (!melody) { + notification = "Hello! \n Please turn the melody ON to train your cat"; + } +} +if (startDetecting) { + int value = analogRead(A0); + if (value < 200) { + String TimeValue = String((millis() - timer) / 1000); + notification = "Cat detected! \nTime to reach the feeder: " + TimeValue + " seconds"; + startDetecting = false; + } else if (millis() - timer > 120000) { + notification= "No cat detected in the past two minutes"; + startDetecting = false; + } +} +delay(1000); +} +void playMelody(int melody[], int noteDurations[], int numberOfNotes ) { + Serial.println("Playing melody"); + for (int thisNote = 0; thisNote < numberOfNotes; thisNote++) { + /* to calculate the note duration, take one second divided by the note type. + e.g. quarter note = 1000 / 4, eighth note = 1000/8, etc. */ + int noteDuration = 1000 / noteDurations[thisNote]; + tone(buzzerPin, melody[thisNote], noteDuration); + /* to distinguish the notes, set a minimum time between them. + the note's duration + 30% seems to work well */ + int pauseBetweenNotes = noteDuration * 1.30; + delay(pauseBetweenNotes); + /* stop the tone playing */ + noTone(buzzerPin); + } +} +void moveServo() { + if (portion > 0){ + Serial.println("moving servo"); + for (pos = 0; pos <= 90; pos += 1) { + /* goes from 0 degrees to 90 degrees */ + myservo.write(pos); /* tell servo to go to position in variable 'pos' */ + delay(15); /* waits 15ms for the servo to reach the position */ + } + delay(portion * 300); /* keep the box open for a time interval based on the amount of food you want to deliver */ + for (pos = 90; pos >= 0; pos -= 1) { +/* goes from 90 degrees to 0 degrees */ + myservo.write(pos); /* tell servo to go to position in variable 'pos' */ + delay(15); /* waits 15ms for the servo to reach the position */ + } + } +} +/* +Since Notification is READ_WRITE variable, onNotificationChange() is +executed every time a new value is received from IoT Cloud. +*/ +void onNotificationChange() { +/* Add your code here to act upon Notification change */ +} +/* +Since SendData is READ_WRITE variable, onSendDataChange() is +executed every time a new value is received from IoT Cloud. +*/ +void onSendDataChange() { +/* Add your code here to act upon SendData change */ +} +/* +Since Portion is READ_WRITE variable, onPortionChange() is +executed every time a new value is received from IoT Cloud. +*/ +void onPortionChange() { +/* Add your code here to act upon Portion change */ +} +/* +Since Melody is READ_WRITE variable, onMelodyChange() is +executed every time a new value is received from IoT Cloud. +*/ +void onMelodyChange() { +/* Add your code here to act upon Melody change */ +} +``` + +### Dashboard + +The final step to deploying our project is adding a control panel using the Arduino IoT Dashboards. We can navigate to **Dashboards > Build Dashboard > ADD**, then we can add four widget and link them to the variable as the following: + +* Messenger widget -> notification variable +* Slider widget -> portion variable +* Push button widget -> sendData variable +* Switch widget -> melody variable + +![Arduino IoT Bundle](assets/palvov-cat-03_EJSoVjN9qB.gif) + +Congratulations! Now you can upload the full sketch below and test your Pavlov Cat Machine! + +### Want to Know More? + +This tutorial is part of a series of experiments that familiarize you with the Arduino IoT Bundle. All experiments can be built using the components contained in the IoT Bundle. + +* [I Love You Pillow with the Arduino IoT Bundle ](/tutorials/iot-bundle/i-love-you-pillow) +* [Puzzle Box with Arduino IoT Bundle ](/tutorials/iot-bundle/puzzlebox) +* [Plant Communicator with the Arduino IoT Bundle ](/tutorials/iot-bundle/plant-communicator) +* [The Nerd with the Arduino IoT Bundle](/tutorials/iot-bundle/the-nerd) + +## Full Code + + \ No newline at end of file diff --git a/content/hardware/08.kits/maker/iot-bundle/tutorials/pavlovs-cat/hero-banner.png b/content/hardware/08.kits/maker/iot-bundle/tutorials/pavlovs-cat/hero-banner.png new file mode 100644 index 0000000000..0be19a3198 Binary files /dev/null and b/content/hardware/08.kits/maker/iot-bundle/tutorials/pavlovs-cat/hero-banner.png differ diff --git a/content/hardware/08.kits/maker/iot-bundle/tutorials/plant-communicator/assets/_rdaslUwR6h.png b/content/hardware/08.kits/maker/iot-bundle/tutorials/plant-communicator/assets/_rdaslUwR6h.png new file mode 100644 index 0000000000..ce433f5b50 Binary files /dev/null and b/content/hardware/08.kits/maker/iot-bundle/tutorials/plant-communicator/assets/_rdaslUwR6h.png differ diff --git a/content/hardware/08.kits/maker/iot-bundle/tutorials/plant-communicator/assets/diy-soil-moisture-rp2040_q2RlMGdgl9.png b/content/hardware/08.kits/maker/iot-bundle/tutorials/plant-communicator/assets/diy-soil-moisture-rp2040_q2RlMGdgl9.png new file mode 100644 index 0000000000..e5ce502495 Binary files /dev/null and b/content/hardware/08.kits/maker/iot-bundle/tutorials/plant-communicator/assets/diy-soil-moisture-rp2040_q2RlMGdgl9.png differ diff --git a/content/hardware/08.kits/maker/iot-bundle/tutorials/plant-communicator/assets/light__temperature_sensor_rp2040_bfbwQp7XjU.png b/content/hardware/08.kits/maker/iot-bundle/tutorials/plant-communicator/assets/light__temperature_sensor_rp2040_bfbwQp7XjU.png new file mode 100644 index 0000000000..6e9085d9c5 Binary files /dev/null and b/content/hardware/08.kits/maker/iot-bundle/tutorials/plant-communicator/assets/light__temperature_sensor_rp2040_bfbwQp7XjU.png differ diff --git a/content/hardware/08.kits/maker/iot-bundle/tutorials/plant-communicator/assets/plant_communicator_01.gif b/content/hardware/08.kits/maker/iot-bundle/tutorials/plant-communicator/assets/plant_communicator_01.gif new file mode 100644 index 0000000000..cc6fdd2720 Binary files /dev/null and b/content/hardware/08.kits/maker/iot-bundle/tutorials/plant-communicator/assets/plant_communicator_01.gif differ diff --git a/content/hardware/08.kits/maker/iot-bundle/tutorials/plant-communicator/assets/plant_communicator_03__2_.gif b/content/hardware/08.kits/maker/iot-bundle/tutorials/plant-communicator/assets/plant_communicator_03__2_.gif new file mode 100644 index 0000000000..cd7feebe41 Binary files /dev/null and b/content/hardware/08.kits/maker/iot-bundle/tutorials/plant-communicator/assets/plant_communicator_03__2_.gif differ diff --git a/content/hardware/08.kits/maker/iot-bundle/tutorials/plant-communicator/assets/plant_communicator_04.gif b/content/hardware/08.kits/maker/iot-bundle/tutorials/plant-communicator/assets/plant_communicator_04.gif new file mode 100644 index 0000000000..4da6061d50 Binary files /dev/null and b/content/hardware/08.kits/maker/iot-bundle/tutorials/plant-communicator/assets/plant_communicator_04.gif differ diff --git a/content/hardware/08.kits/maker/iot-bundle/tutorials/plant-communicator/assets/screenshot_2022-11-23_141037_Q9gBcgrkER.png b/content/hardware/08.kits/maker/iot-bundle/tutorials/plant-communicator/assets/screenshot_2022-11-23_141037_Q9gBcgrkER.png new file mode 100644 index 0000000000..83b4ee8135 Binary files /dev/null and b/content/hardware/08.kits/maker/iot-bundle/tutorials/plant-communicator/assets/screenshot_2022-11-23_141037_Q9gBcgrkER.png differ diff --git a/content/hardware/08.kits/maker/iot-bundle/tutorials/plant-communicator/content.md b/content/hardware/08.kits/maker/iot-bundle/tutorials/plant-communicator/content.md new file mode 100644 index 0000000000..76c3fbd709 --- /dev/null +++ b/content/hardware/08.kits/maker/iot-bundle/tutorials/plant-communicator/content.md @@ -0,0 +1,251 @@ +--- +title: "Plant Communicator with the Arduino IoT Bundle" +description: "Ever wished you could talk with your plants?" +coverImage: "assets/_rdaslUwR6h.png" +tags: [IoT Cloud, Smart Garden] +author: "Arduino_Genuino" +source: "https://create.arduino.cc/projecthub/Arduino_Genuino/plant-communicator-with-the-arduino-iot-bundle-918636" +--- + +## Components and Supplies + +- [Arduino IoT Bundle](https://store.arduino.cc/iot-bundle) + +## Apps and Online Services + +- [Arduino IoT Cloud](https://cloud.arduino.cc) +- [Arduino IoT Cloud Remote app](https://play.google.com/store/apps/details?id=cc.arduino.cloudiot&hl=en&gl=US) + +## About This Project + +**Create a plant communicator with the help of the Arduino IoT Cloud!** + +As the English poet William Wordsworth once said: + +"Your mind is the garden, your thoughts are the seeds, the harvest can be either flowers or weeds." + +Keeping our plants alive can be quite the challenge as there’s a lack of clear communication between us and plants. One way to keep them happy is to bring our plants with us, but maybe we don't want to lug around with that big-ole-cactus or fern sticking out of our winter jacket pockets. Also, most plants dislike the cold. After spending months trying to communicate with our Spider Plant, we gave up and used the IoT Bundle components together with the Arduino IoT Cloud to create a device that remotely surveys the well being of any plant instead. + +### In a Nutshell + +In this experiment we will learn how to protect our plants and make sure they survive as well as using Arduino magic. By monitoring moisture, temperature and light, we can make sure that our plants are happy. + +By the end of this project, your plant will communicate its needs with you visually and show you how it's currently doing through the Arduino IoT CLoud. + +### Components + +* TMP36 temperature sensor +* Phototransistor +* DIY moisture sensor + +> **Note:** to achieve all the functions demonstrated in this project, you would need a subscription to the Arduino IoT Cloud. The project can be carried without an Arduino IoT Cloud subscription by removing one of the variables (Light, Temperature, or moisture). + +### Learning Goals + +* Introducing the Arduino IoT Cloud +* Introducing the Arduino IoT Remote app +* Building a DIY moisture sensor +* Creating an Arduino IoT Cloud Dashboard + +### Want to Know More? + +This tutorial is part of a series of experiments that familiarize you with the Arduino RP2040 and IoT. All experiments can be built using the components contained in the IoT Bundle. + +* [I Love You Pillow with the Arduino IoT Bundle ](/tutorials/iot-bundle/i-love-you-pillow) +* [Puzzle Box with Arduino IoT Bundle ](/tutorials/iot-bundle/puzzlebox) +* [Pavlov's Cat with the Arduino IoT Bundle](/tutorials/iot-bundle/pavlovs-cat) +* [The Nerd with the Arduino IoT Bundle](/tutorials/iot-bundle/the-nerd) + +### Setting up the Arduino IoT Cloud + +If you are new to the Arduino IoT Cloud, check out our [Getting Started Guide](https://docs.arduino.cc/arduino-cloud/getting-started/iot-cloud-getting-started). + +We will start by setting up the Arduino IoT Cloud by following the steps below: + +* **Login** to your Arduino Create account +* Creating a **Thing** +* Attaching a **Device** +* Adding **Variables** +* Adding **Network** credentials + +![Setting up the Arduino IoT Cloud](assets/plant_communicator_01.gif) + +Setting up the Arduino IoT Cloud + +### Variables + +We will start by adding four variables: + +![Arduino IoT Bundle](assets/screenshot_2022-11-23_141037_Q9gBcgrkER.png) + +### Setup Hardware & Sketch + +**DIY soil moisture** + +Two wires placed in the soil pot form a variable resistor, whose resistance varies depending on soil moisture. This variable resistor is connected in a voltage divider configuration, and Arduino collects a voltage proportional to resistance between the 2 wires. Meaning that the more humid the soil is, the less voltage will be measured from the Arduino because the resistance in the soil decreases with its moisture. The dryer the soil is the higher resistance is. Using the 1 Mega Ohm resistor and two wires, we can create our DIY soil moisture sensor. + +![Arduino IoT Bundle](assets/diy-soil-moisture-rp2040_q2RlMGdgl9.png) + +That value will be used to set a threshold so that the Arduino will know when your plants need water. Add the code shown below to your sketch and test the moisture levels of your plant. The values are shown in the serial monitor. + +``` +#include "thingProperties.h" +int moisturePin = A2; +/* Set this threeshold accordingly to the resistance you used */ +/* The easiest way to calibrate this value is to test the sensor in both dry and wet earth */ +int threshold = 800; +void setup() { + /* Initialize serial and wait for port to open: */ + Serial.begin(9600); + /* This delay gives the chance to wait for a Serial Monitor without blocking if none is found */ + delay(1500); + /* Defined in thingProperties.h */ + initProperties(); + /* Connect to Arduino IoT Cloud */ + ArduinoCloud.begin(ArduinoIoTPreferredConnection); + /* + The following function allows you to obtain more information + related to the state of network and IoT Cloud connection and errors + the higher number the more granular information you’ll get. + The default is 0 (only errors). + Maximum is 4 + */ + setDebugMessageLevel(2); + ArduinoCloud.printDebugInfo(); +} +void loop() { + ArduinoCloud.update(); + moisture = get_average_moisture(); + Serial.print("moisture "); + Serial.println(moisture); + /* assign the message variable based on water levels */ + if (moisture > threshold) { + message = "Warning your plant needs water!"; /* Insert here your emergency message */ + } else { + message = "Your plant has enough water!"; + } + Serial.println(message); +} +int get_average_moisture() { + int tempValue = 0; /* variable to temporarily store moisture value */ + /* make an average of 10 values to be more accurate */ + for (int a = 0; a < 10; a++) { + tempValue += analogRead(moisturePin); + delay(100); + } + return tempValue / 10; +} +/* +Since Message is READ_WRITE variable, onMessageChange() is +executed every time a new value is received from IoT Cloud. +*/ +void onMessageChange() { + /* Add your code here to act upon Message change */ +} +``` + +**Light & temperature sensors** + +See the schematic below to wire up the two sensors. We will use these two functions to read values from the sensors: + +![Arduino IoT Bundle](assets/light__temperature_sensor_rp2040_bfbwQp7XjU.png) + +``` +#include "thingProperties.h" +int lightPin = A0; /*the analog pin the light sensor is connected to */ +int tempPin = A1; /*the analog pin the TMP36's Vout (sense) pin is connected to */ +int moisturePin = A2; +/* Set this threshold accordingly to the resistance you used */ +/* The easiest way to calibrate this value is to test the sensor in both dry and wet earth */ +int threshold = 800; +void setup() { + /* Initialize serial and wait for port to open: */ + Serial.begin(9600); + /* This delay gives the chance to wait for a Serial Monitor without blocking if none is found */ + delay(1500); + /* Defined in thingProperties.h */ + initProperties(); + /* Connect to Arduino IoT Cloud */ + ArduinoCloud.begin(ArduinoIoTPreferredConnection); + /* + The following function allows you to obtain more information + related to the state of network and IoT Cloud connection and errors + the higher number the more granular information you’ll get. + The default is 0 (only errors). + Maximum is 4 + */ + setDebugMessageLevel(2); + ArduinoCloud.printDebugInfo(); +} +void loop() { + ArduinoCloud.update(); + light = analogRead(lightPin); /* assign light variable to light sensor values */ + Serial.print("light "); + Serial.println(light); + temperature = get_temperature(); /* assign temperature variable to temperature in Celsius */ + Serial.print("temperature "); + Serial.println(temperature); + + moisture = get_average_moisture(); + /* assign the message variable based on water levels */ + if (moisture > threshold) { + message = "Warning your plant needs water!"; /* Insert here your emergency message */ + } else { + message = "Your plant has enough water!"; + } +} +int get_average_moisture() { + int tempValue = 0; /* variable to temporarily store moisture value */ + /* make an average of 10 values to be more accurate */ + for (int a = 0; a < 10; a++) { + tempValue += analogRead(moisturePin); + delay(100); + } + return tempValue / 10; +} +float get_temperature() { + int reading = analogRead(tempPin); + float voltage = reading * 3.3; + voltage /= 1024.0; + /* temperature in Celsius */ + float temperatureC = (voltage - 0.5) * 100 ; /*converting from 10 mv per degree with 500 mV offset */ + /* Convert to Fahrenheit */ + float temperatureF = (temperatureC * 9.0 / 5.0) + 32.0; + return temperatureC; +} +void onMessageChange() { + /* Add your code here to act upon Message change */ +} +``` + +Note that you can use the Fahrenheit units by returning temperatureF instead of temperatureC at the end of the **“get\_temperature()”** function. + +### Dashboard + +The final step to deploying our project is adding a control panel using the Arduino IoT Dashboards. We can navigate to **Dashboards -> Build Dashboard -> ADD,** then we can add four widget and link them to the variable as the following: + +* Graph widget -> temperature variable +* Graph widget -> moisture variable +* Gauge widget -> light variable +* Messenger widget -> message variable + +![Arduino IoT Bundle](assets/plant_communicator_03__2_.gif) + +Now, we can see a visual representation of our sensor data. + +![Arduino IoT Bundle](assets/plant_communicator_04.gif) + +Congratulations you have now build your own DIY plant communicator showing how your plants are doing using the IoT Bundle and IoT Cloud. + +### Want to Know More? + +This tutorial is part of a series of experiments that familiarize you with the Arduino IoT Bundle. All experiments can be built using the components contained in the IoT Bundle. + +* [I Love You Pillow with the Arduino IoT Bundle ](/tutorials/iot-bundle/i-love-you-pillow) +* [Puzzle Box with Arduino IoT Bundle ](/tutorials/iot-bundle/puzzlebox) +* [Pavlov's Cat with the Arduino IoT Bundle](/tutorials/iot-bundle/pavlovs-cat) +* [The Nerd with the Arduino IoT Bundle](/tutorials/iot-bundle/the-nerd) + +## Full Code + + \ No newline at end of file diff --git a/content/hardware/08.kits/maker/iot-bundle/tutorials/plant-communicator/hero-banner.png b/content/hardware/08.kits/maker/iot-bundle/tutorials/plant-communicator/hero-banner.png new file mode 100644 index 0000000000..ef1cf5959a Binary files /dev/null and b/content/hardware/08.kits/maker/iot-bundle/tutorials/plant-communicator/hero-banner.png differ diff --git a/content/hardware/08.kits/maker/iot-bundle/tutorials/puzzlebox/assets/_VbBUKNXj0o.png b/content/hardware/08.kits/maker/iot-bundle/tutorials/puzzlebox/assets/_VbBUKNXj0o.png new file mode 100644 index 0000000000..08c0c7a489 Binary files /dev/null and b/content/hardware/08.kits/maker/iot-bundle/tutorials/puzzlebox/assets/_VbBUKNXj0o.png differ diff --git a/content/hardware/08.kits/maker/iot-bundle/tutorials/puzzlebox/assets/cloudinstructions_rp2040_0AMlQHeGHs.gif b/content/hardware/08.kits/maker/iot-bundle/tutorials/puzzlebox/assets/cloudinstructions_rp2040_0AMlQHeGHs.gif new file mode 100644 index 0000000000..f505e4cd16 Binary files /dev/null and b/content/hardware/08.kits/maker/iot-bundle/tutorials/puzzlebox/assets/cloudinstructions_rp2040_0AMlQHeGHs.gif differ diff --git a/content/hardware/08.kits/maker/iot-bundle/tutorials/puzzlebox/assets/lcd_part_rp2040_wOrq2EKGuO.png b/content/hardware/08.kits/maker/iot-bundle/tutorials/puzzlebox/assets/lcd_part_rp2040_wOrq2EKGuO.png new file mode 100644 index 0000000000..959a924367 Binary files /dev/null and b/content/hardware/08.kits/maker/iot-bundle/tutorials/puzzlebox/assets/lcd_part_rp2040_wOrq2EKGuO.png differ diff --git a/content/hardware/08.kits/maker/iot-bundle/tutorials/puzzlebox/assets/piezo_buzzer_comeplete_rp2040_JAUtOjyKq1.png b/content/hardware/08.kits/maker/iot-bundle/tutorials/puzzlebox/assets/piezo_buzzer_comeplete_rp2040_JAUtOjyKq1.png new file mode 100644 index 0000000000..12ee14a4ea Binary files /dev/null and b/content/hardware/08.kits/maker/iot-bundle/tutorials/puzzlebox/assets/piezo_buzzer_comeplete_rp2040_JAUtOjyKq1.png differ diff --git a/content/hardware/08.kits/maker/iot-bundle/tutorials/puzzlebox/assets/piezo_buzzer_part_rp2040_iaPHtGSH0X.png b/content/hardware/08.kits/maker/iot-bundle/tutorials/puzzlebox/assets/piezo_buzzer_part_rp2040_iaPHtGSH0X.png new file mode 100644 index 0000000000..92897c54ba Binary files /dev/null and b/content/hardware/08.kits/maker/iot-bundle/tutorials/puzzlebox/assets/piezo_buzzer_part_rp2040_iaPHtGSH0X.png differ diff --git a/content/hardware/08.kits/maker/iot-bundle/tutorials/puzzlebox/assets/potentiometer_part_rp2040_q8hHfs8AIS.png b/content/hardware/08.kits/maker/iot-bundle/tutorials/puzzlebox/assets/potentiometer_part_rp2040_q8hHfs8AIS.png new file mode 100644 index 0000000000..18f342c764 Binary files /dev/null and b/content/hardware/08.kits/maker/iot-bundle/tutorials/puzzlebox/assets/potentiometer_part_rp2040_q8hHfs8AIS.png differ diff --git a/content/hardware/08.kits/maker/iot-bundle/tutorials/puzzlebox/assets/puzzlebox_pi0UiMBngP.gif b/content/hardware/08.kits/maker/iot-bundle/tutorials/puzzlebox/assets/puzzlebox_pi0UiMBngP.gif new file mode 100644 index 0000000000..32cb268eaf Binary files /dev/null and b/content/hardware/08.kits/maker/iot-bundle/tutorials/puzzlebox/assets/puzzlebox_pi0UiMBngP.gif differ diff --git a/content/hardware/08.kits/maker/iot-bundle/tutorials/puzzlebox/assets/rgb_comeplete_rp2040_6AuNMnXduR.png b/content/hardware/08.kits/maker/iot-bundle/tutorials/puzzlebox/assets/rgb_comeplete_rp2040_6AuNMnXduR.png new file mode 100644 index 0000000000..317e893e9b Binary files /dev/null and b/content/hardware/08.kits/maker/iot-bundle/tutorials/puzzlebox/assets/rgb_comeplete_rp2040_6AuNMnXduR.png differ diff --git a/content/hardware/08.kits/maker/iot-bundle/tutorials/puzzlebox/assets/rgb_part_rp2040_4eGOKtRQgk.png b/content/hardware/08.kits/maker/iot-bundle/tutorials/puzzlebox/assets/rgb_part_rp2040_4eGOKtRQgk.png new file mode 100644 index 0000000000..9223dd2408 Binary files /dev/null and b/content/hardware/08.kits/maker/iot-bundle/tutorials/puzzlebox/assets/rgb_part_rp2040_4eGOKtRQgk.png differ diff --git a/content/hardware/08.kits/maker/iot-bundle/tutorials/puzzlebox/assets/rgbled_s82wjxgcnf_1WXt8cDpSj.png b/content/hardware/08.kits/maker/iot-bundle/tutorials/puzzlebox/assets/rgbled_s82wjxgcnf_1WXt8cDpSj.png new file mode 100644 index 0000000000..4417a426f9 Binary files /dev/null and b/content/hardware/08.kits/maker/iot-bundle/tutorials/puzzlebox/assets/rgbled_s82wjxgcnf_1WXt8cDpSj.png differ diff --git a/content/hardware/08.kits/maker/iot-bundle/tutorials/puzzlebox/assets/safe_combination_Xkek4QBhoy.gif b/content/hardware/08.kits/maker/iot-bundle/tutorials/puzzlebox/assets/safe_combination_Xkek4QBhoy.gif new file mode 100644 index 0000000000..f8c311efa4 Binary files /dev/null and b/content/hardware/08.kits/maker/iot-bundle/tutorials/puzzlebox/assets/safe_combination_Xkek4QBhoy.gif differ diff --git a/content/hardware/08.kits/maker/iot-bundle/tutorials/puzzlebox/assets/screenshot_2022-11-17_095328_ujTWxb7Xtp.png b/content/hardware/08.kits/maker/iot-bundle/tutorials/puzzlebox/assets/screenshot_2022-11-17_095328_ujTWxb7Xtp.png new file mode 100644 index 0000000000..06a6236454 Binary files /dev/null and b/content/hardware/08.kits/maker/iot-bundle/tutorials/puzzlebox/assets/screenshot_2022-11-17_095328_ujTWxb7Xtp.png differ diff --git a/content/hardware/08.kits/maker/iot-bundle/tutorials/puzzlebox/assets/screenshot_2022-11-23_141306_tsMoI77zJw.png b/content/hardware/08.kits/maker/iot-bundle/tutorials/puzzlebox/assets/screenshot_2022-11-23_141306_tsMoI77zJw.png new file mode 100644 index 0000000000..8b72f9a21e Binary files /dev/null and b/content/hardware/08.kits/maker/iot-bundle/tutorials/puzzlebox/assets/screenshot_2022-11-23_141306_tsMoI77zJw.png differ diff --git a/content/hardware/08.kits/maker/iot-bundle/tutorials/puzzlebox/assets/servo_motor_comeplete_rp2040_mXHekbPnRO.png b/content/hardware/08.kits/maker/iot-bundle/tutorials/puzzlebox/assets/servo_motor_comeplete_rp2040_mXHekbPnRO.png new file mode 100644 index 0000000000..e41f1e1197 Binary files /dev/null and b/content/hardware/08.kits/maker/iot-bundle/tutorials/puzzlebox/assets/servo_motor_comeplete_rp2040_mXHekbPnRO.png differ diff --git a/content/hardware/08.kits/maker/iot-bundle/tutorials/puzzlebox/assets/servo_motor_part_rp2040_4ZqZ4C9F5w.png b/content/hardware/08.kits/maker/iot-bundle/tutorials/puzzlebox/assets/servo_motor_part_rp2040_4ZqZ4C9F5w.png new file mode 100644 index 0000000000..a1e13446ce Binary files /dev/null and b/content/hardware/08.kits/maker/iot-bundle/tutorials/puzzlebox/assets/servo_motor_part_rp2040_4ZqZ4C9F5w.png differ diff --git a/content/hardware/08.kits/maker/iot-bundle/tutorials/puzzlebox/content.md b/content/hardware/08.kits/maker/iot-bundle/tutorials/puzzlebox/content.md new file mode 100644 index 0000000000..25f41d9a43 --- /dev/null +++ b/content/hardware/08.kits/maker/iot-bundle/tutorials/puzzlebox/content.md @@ -0,0 +1,1122 @@ +--- +title: "Puzzle Box with Arduino IoT Bundle" +description: "Protect your valuables with a puzzle." +coverImage: "assets/_VbBUKNXj0o.png" +tags: [IoT Cloud, Puzzle] +author: "Arduino_Genuino" +source: "https://create.arduino.cc/projecthub/Arduino_Genuino/puzzlebox-with-arduino-iot-bundle-96d09c" +--- + +## Components and Supplies + +- [Arduino IoT Bundle](https://store.arduino.cc/iot-bundle) +- 9V battery (generic) +- [9V Battery Clip](https://www.newark.com/22C4351?COM=ref_hackster) + +## Apps and Online Services + +- [Arduino IoT Cloud](https://cloud.arduino.cc) +- [Arduino IoT Cloud Remote app](https://play.google.com/store/apps/details?id=cc.arduino.cloudiot&hl=en&gl=US) + +## About This Project + +**Create a Puzzle Box with the help of the Arduino IoT Cloud!** + +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. + +### In a Nutshell + +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 IoT 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: + +* Buzzer +* RGB LED +* 3 potentiometers +* Servo motor + +![Arduino IoT Bundle](assets/puzzlebox_pi0UiMBngP.gif) + +### Learning Goals + +* Introducing the Arduino IoT Cloud +* Introducing the Arduino IoT Remote app +* Playing a melody with the piezo buzzer +* Creating an Arduino IoT Cloud Dashboard + +### Want to Know More + +This tutorial is part of a series of experiments that familiarize you with the Arduino RP2040 and IoT. All experiments can be built using the components contained in the IoT Bundle. + +* [I Love You Pillow with the Arduino IoT Bundle ](/tutorials/iot-bundle/i-love-you-pillow) +* [Pavlov's Cat with the Arduino IoT Bundle](/tutorials/iot-bundle/pavlovs-cat) +* [Plant Communicator with the Arduino IoT Bundle ](/tutorials/iot-bundle/plant-communicator) +* [The Nerd with the Arduino IoT Bundle](/tutorials/iot-bundle/the-nerd) + +### Setting up the Arduino IoT Cloud + +If you are new to the Arduino IoT Cloud, check out our [Getting Started Guide](https://docs.arduino.cc/arduino-cloud/getting-started/iot-cloud-getting-started). + +We will start by setting up the Arduino IoT Cloud by following the steps below: + +* Creating a **Thing** +* Attaching a **Device** +* Adding **Variables** +* Adding **Network** credentials + +![Arduino IoT Bundle](assets/cloudinstructions_rp2040_0AMlQHeGHs.gif) + +### Variables + +We will start by adding four variables: + +![Arduino IoT Bundle](assets/screenshot_2022-11-23_141306_tsMoI77zJw.png) + +### Dashboard + +Before we upload the code to the board, let's create the dashboard with the sliders. We can navigate to **Dashboards > Build Dashboard > ADD**, then we can add four widget and link them to the variable as the following: + +* Slider widget -> sliderOne +* Slider widget -> sliderTwo +* Slider widget -> sliderThree + +![Arduino IoT Bundle](assets/safe_combination_Xkek4QBhoy.gif) + +### Setup Hardware & Sketch + +Now we are ready to go. Upload this sketch and play with the sliders to see the result in the serial monitor. + +``` +#include "thingProperties.h" +void setup() { + /* Initialize serial and wait for port to open: */ + Serial.begin(9600); + /* This delay gives the chance to wait for a Serial Monitor without blocking if none is found */ + delay(1500); + /* Defined in thingProperties.h */ + initProperties(); + /* Connect to Arduino IoT Cloud */ + ArduinoCloud.begin(ArduinoIoTPreferredConnection); + setDebugMessageLevel(2); + ArduinoCloud.printDebugInfo(); +} +void loop() { + ArduinoCloud.update(); +} +void onSliderOneChange() { + /* Add your code here to act upon SliderValue1 change */ + Serial.print("New combination: "); + Serial.print(sliderOne); + Serial.print(" "); + Serial.print(sliderTwo); + Serial.print(" "); + Serial.println(sliderThree); +} +void onSliderTwoChange() { + /* Add your code here to act upon SliderValue2 change */ + Serial.print("New combination: "); + Serial.print(sliderOne); + Serial.print(" "); + Serial.print(sliderTwo); + Serial.print(" "); + Serial.println(sliderThree); +} +void onSliderThreeChange() { + /* Add your code here to act upon SliderValue3 change */ + Serial.print("New combination: "); + Serial.print(sliderOne); + Serial.print(" "); + Serial.print(sliderTwo); + Serial.print(" "); + Serial.println(sliderThree); +} +void onDisplayChange() { + /* Add your code here to act upon Display change */ +} +``` + +**Add Potentiometers** + +Now it's time to connect our potentiometers, which are used to open your puzzle box. To read the value of the potentiometers we will only need an **analogRead()** on the correct pin. We are connecting them to Analog pins 0, 1, 2. + +![Arduino IoT Bundle](assets/potentiometer_part_rp2040_q8hHfs8AIS.png) + +Note that the value of a potentiometer spans from 0 to 1023 making the combination impossible to guess. To map those values from 0 to 9 we will use the map() function, + +``` +int PotOne = map(analogRead(A0), 0, 1023, 0, 9); +``` + +You won't see any changes until you build your interface in the next step but you can take a look at how to map the values from the potentiometers. + +``` +#include "thingProperties.h" +void setup() { + /* Initialize serial and wait for port to open: */ + Serial.begin(9600); + /* This delay gives the chance to wait for a Serial Monitor without blocking if none is found */ + delay(1500); + /* Defined in thingProperties.h */ + initProperties(); + /* Connect to Arduino IoT Cloud */ + ArduinoCloud.begin(ArduinoIoTPreferredConnection); + setDebugMessageLevel(2); + ArduinoCloud.printDebugInfo(); +} +void loop() { + ArduinoCloud.update(); + 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); +} +void onSliderOneChange() { + /* Add your code here to act upon SliderValue1 change */ + Serial.print("New combination: "); + Serial.print(sliderOne); + Serial.print(" "); + Serial.print(sliderTwo); + Serial.print(" "); + Serial.println(sliderThree); +} +void onSliderTwoChange() { + /* Add your code here to act upon SliderValue2 change */ + Serial.print("New combination: "); + Serial.print(sliderOne); + Serial.print(" "); + Serial.print(sliderTwo); + Serial.print(" "); + Serial.println(sliderThree); +} +void onSliderThreeChange() { + /* Add your code here to act upon SliderValue3 change */ + Serial.print("New combination: "); + Serial.print(sliderOne); + Serial.print(" "); + Serial.print(sliderTwo); + Serial.print(" "); + Serial.println(sliderThree); +} +void onDisplayChange() { +/* Add your code here to act upon Display change */ +} +``` + +### Display + +**Dashboard** + +We already have one dashboard allowing you to set the combination to your puzzle box. But now we are going to create a new one so you can use your phone to check the current position you’re at. + +Start by creating a new dashboard, add a messenger widget and link it to the display variable. For printing the potentiometer values to the display you can use the following logic: + +``` +String numberOne = String(PotOne); +String numberTwo = String(PotTwo); +String numberThree = String(PotThree); +``` + +Then simply assign all three strings to our display variable to see them in the messenger widget. + +``` +display =String(numberOne + numberTwo + numberThree); +``` + +You will see a new message appear every time you turn one of the potentiometers. + +![Arduino IoT Bundle](assets/screenshot_2022-11-17_095328_ujTWxb7Xtp.png) + +Upload this code to see it working: + +``` +#include "thingProperties.h" +void setup() { + /* Initialize serial and wait for port to open: */ + Serial.begin(9600); + /* This delay gives the chance to wait for a Serial Monitor without blocking if none is found */ + delay(1500); + /* Defined in thingProperties.h */ + initProperties(); + /* Connect to Arduino IoT Cloud */ + ArduinoCloud.begin(ArduinoIoTPreferredConnection); + setDebugMessageLevel(2); + ArduinoCloud.printDebugInfo(); +} +void loop() { + ArduinoCloud.update(); + 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); + String numberOne = String(PotOne); + String numberTwo = String(PotTwo); + String numberThree = String(PotThree); + display =String(numberOne + numberTwo + numberThree); +} +void onSliderOneChange() { + /* Add your code here to act upon SliderValue1 change */ + Serial.print("New combination: "); + Serial.print(sliderOne); + Serial.print(" "); + Serial.print(sliderTwo); + Serial.print(" "); + Serial.println(sliderThree); +} +void onSliderTwoChange() { + /* Add your code here to act upon SliderValue2 change */ + Serial.print("New combination: "); + Serial.print(sliderOne); + Serial.print(" "); + Serial.print(sliderTwo); + Serial.print(" "); + Serial.println(sliderThree); +} +void onSliderThreeChange() { + /* Add your code here to act upon SliderValue3 change */ + Serial.print("New combination: "); + Serial.print(sliderOne); + Serial.print(" "); + Serial.print(sliderTwo); + Serial.print(" "); + Serial.println(sliderThree); +} +void onDisplayChange() { +/* Add your code here to act upon Display change */ +} +``` + +**LCD** + +You could also use the LCD screen that comes with the kit, though we recommend using the dashboard because not all the components fit on the breadboard at the same time. + +> **Note**: The LCD has a 5V operating voltage, so you have to enable the 5V pad on the back of the board by soldering it. See [here](https://support.arduino.cc/hc/en-us/articles/360014779679-About-Nano-boards-with-disabled-5-V-pins) for more details. + +![Arduino IoT Bundle](assets/lcd_part_rp2040_wOrq2EKGuO.png) + +We are using a 220 Ohm resistor and the brightness can be regulated by changing the output value of the Analog pin 3 from 0 to 255 with 0 being the maximum value. Add the following line inside **void** setup(). + +``` +analogWrite(A3, 0); +``` + +Upload this code to see "**hello, world!"** on your display. + +``` +#include "thingProperties.h" +#include "LiquidCrystal.h" +/* initialize the library by associating any needed LCD interface pin with the arduino pin number it is connected to LCD screen pins */ +const int rs = 12, +en = 11, +d4 = 2, +d5 = 3, +d6 = 4, +d7 = 5; +LiquidCrystal lcd(rs, en, d4, d5, d6, d7); +void setup() { + /* Initialize serial and wait for port to open: */ + Serial.begin(9600); + /* This delay gives the chance to wait for a Serial Monitor without blocking if none is found */ + delay(1500); + /* Defined in thingProperties.h */ + initProperties(); + /* Connect to Arduino IoT Cloud */ + ArduinoCloud.begin(ArduinoIoTPreferredConnection); + setDebugMessageLevel(2); + ArduinoCloud.printDebugInfo(); + analogWrite(A3, 0); /* Set the brightness to its maximum value */ + /* set up the LCD's number of columns and rows: */ + lcd.begin(16, 2); /* Print a message to the LCD. */ + lcd.print("hello, world!"); +} +void loop() { + ArduinoCloud.update(); + 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); + String numberOne = String(PotOne); + String numberTwo = String(PotTwo); + String numberThree = String(PotThree); + display =String(numberOne + numberTwo + numberThree); +} +void onSliderOneChange() { + /* Add your code here to act upon SliderValue1 change */ + Serial.print("New combination: "); + Serial.print(sliderOne); + Serial.print(" "); + Serial.print(sliderTwo); + Serial.print(" "); + Serial.println(sliderThree); +} +void onSliderTwoChange() { + /* Add your code here to act upon SliderValue2 change */ + Serial.print("New combination: "); + Serial.print(sliderOne); + Serial.print(" "); + Serial.print(sliderTwo); + Serial.print(" "); + Serial.println(sliderThree); +} +void onSliderThreeChange() { + /* Add your code here to act upon SliderValue3 change */ + Serial.print("New combination: "); + Serial.print(sliderOne); + Serial.print(" "); + Serial.print(sliderTwo); + Serial.print(" "); + Serial.println(sliderThree); +} +void onDisplayChange() { +/* Add your code here to act upon Display change */ +} +``` + +**RGB LED** + +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. + +![RGB LED](assets/rgbled_s82wjxgcnf_1WXt8cDpSj.png) + +RGB LED + +![Arduino IoT Bundle](assets/rgb_part_rp2040_4eGOKtRQgk.png) + +![Arduino IoT Bundle](assets/rgb_comeplete_rp2040_6AuNMnXduR.png) + +To control the RGB we can use the following logic: + +``` +setColor(0, 0, 255); /* blue */ + delay(1000); + setColor(0, 255, 255); /* aqua */ + delay(1000); + setColor(255, 255, 0); /* yellow */ + delay(1000); + setColor(255, 0, 0); /* Red */ + delay(1000); +``` + +You can use this example sketch to see the RGB in action! + +``` +#include "thingProperties.h" +#include "LiquidCrystal.h" +/* RGB LED pins */ +int redPin = 6; +int greenPin = 8; +int bluePin = 7; +bool start = true; +/* initialize the library by associating any needed LCD interface pin with the arduino pin number it is connected to LCD screen pins */ +const int rs = 12, +en = 11, +d4 = 2, +d5 = 3, +d6 = 4, +d7 = 5; +LiquidCrystal lcd(rs, en, d4, d5, d6, d7); +void setup() { + /* Initialize serial and wait for port to open: */ + Serial.begin(9600); + /* This delay gives the chance to wait for a Serial Monitor without blocking if none is found */ + delay(1500); + /* Defined in thingProperties.h */ + initProperties(); + /* Connect to Arduino IoT Cloud */ + ArduinoCloud.begin(ArduinoIoTPreferredConnection); + setDebugMessageLevel(2); + ArduinoCloud.printDebugInfo(); + analogWrite(A3, 0); /* Set the brightness to its maximum value */ + /* set up the LCD's number of columns and rows: */ + lcd.begin(16, 2); /* Print a message to the LCD. */ + pinMode(redPin, OUTPUT); + pinMode(greenPin, OUTPUT); + pinMode(bluePin, OUTPUT); +} +void loop() { + ArduinoCloud.update(); + 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); + String numberOne = String(PotOne); + String numberTwo = String(PotTwo); + String numberThree = String(PotThree); + display =String(numberOne + numberTwo + numberThree); + setColor(0, 0, 255); /* blue */ + delay(1000); + setColor(0, 255, 255); /* aqua */ + delay(1000); + setColor(255, 255, 0); /* yellow */ + delay(1000); + setColor(255, 0, 0); /* Red */ + delay(1000); +} +void onSliderOneChange() { + /* Add your code here to act upon SliderValue1 change */ + Serial.print("New combination: "); + Serial.print(sliderOne); + Serial.print(" "); + Serial.print(sliderTwo); + Serial.print(" "); + Serial.println(sliderThree); +} +void onSliderTwoChange() { + /* Add your code here to act upon SliderValue2 change */ + Serial.print("New combination: "); + Serial.print(sliderOne); + Serial.print(" "); + Serial.print(sliderTwo); + Serial.print(" "); + Serial.println(sliderThree); +} +void onSliderThreeChange() { + /* Add your code here to act upon SliderValue3 change */ + Serial.print("New combination: "); + Serial.print(sliderOne); + Serial.print(" "); + Serial.print(sliderTwo); + Serial.print(" "); + Serial.println(sliderThree); +} +/* Send RGB values to the LED pins */ +void setColor(int red, int green, int blue) { + analogWrite(redPin, red); + analogWrite(greenPin, green); + analogWrite(bluePin, blue); +} +void onDisplayChange() { +/* Add your code here to act upon Display change */ +} +``` + +### Connect It to the Arduino IoT Cloud + +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. + +- 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. + +``` +void giveColorFeedback(int PotOne, int PotTwo, int PotThree){...} +``` + +- 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. + +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. + +Upload this example sketch and turn the potentiometers to see it in action. + +```arduino +#include "LiquidCrystal.h" +#include "SPI.h" +#include "thingProperties.h" +/* RGB LED pins */ +int redPin = 6; +int greenPin = 8; +int bluePin = 7; +/* LCD screen pins */ +const int rs = 12, + en = 11, + d4 = 2, + d5 = 3, + d6 = 4, + d7 = 5; +bool start = true; +LiquidCrystal lcd(rs, en, d4, d5, d6, d7); +void setup() { + pinMode(redPin, OUTPUT); + pinMode(greenPin, OUTPUT); + pinMode(bluePin, OUTPUT); + analogWrite(A3, 0); /* set the brightness of the LCD screen to the maximum value */ + Serial.begin(9600); + delay(1500); + initProperties(); + ArduinoCloud.begin(ArduinoIoTPreferredConnection); + setDebugMessageLevel(2); + ArduinoCloud.printDebugInfo(); + lcd.begin(16, 2); /* begin LCD screen with 16 columns and 2 rows */ +} +void loop() { + ArduinoCloud.update(); + 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); + String numberOne = String(PotOne); + String numberTwo = String(PotTwo); + String numberThree = String(PotThree); + display =String(numberOne + numberTwo + numberThree); + if (start) { + giveColorFeedback(PotOne, PotTwo, PotThree); + if (PotOne == sliderOne && PotTwo == sliderTwo && PotThree == sliderThree) + { + blinkGreenLed(); + start = false; + } + } + if (!start) { + if (PotOne == 0 && PotTwo == 0 && PotThree == 0) { + start = true; + } + } +} +/* Give feedback based on how close the potentiometer are to the combination value +The more it's close the warmer is the color of the LED */ +void giveColorFeedback(int PotOne, int PotTwo, int PotThree) { + if (abs(PotOne - sliderOne) <= 1 && abs(PotTwo - sliderTwo) <= 1 && abs(PotThree - sliderThree) <= 1 ) { + /* Red */ + setColor(255, 0, 0); + } + else if (abs(PotOne - sliderOne) <= 3 && abs(PotTwo - sliderTwo) <= 3 && abs(PotThree - sliderThree) <= 3 ) { + /* yellow */ + setColor(255, 255, 0); + } + else if (abs(PotOne - sliderOne) <= 4 && abs(PotTwo - sliderTwo) <= 4 && abs(PotThree - sliderThree) <= 4 ) { + /* aqua */ + setColor(0, 255, 255); + } + else { + /* blue */ + setColor(0, 0, 255); + } +} +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 initLCD() { + Serial.println(">>> begin LCD"); + lcd.begin(16, 2); + lcd.print(" Initialising"); + + delay(100); +} +void onSliderOneChange() { + /* Add your code here to act upon SliderValue1 change */ + Serial.print("New combination: "); + Serial.print(sliderOne); + Serial.print(" "); + Serial.print(sliderTwo); + Serial.print(" "); + Serial.println(sliderThree); +} +void onSliderTwoChange() { + /* Add your code here to act upon SliderValue2 change */ + Serial.print("New combination: "); + Serial.print(sliderOne); + Serial.print(" "); + Serial.print(sliderTwo); + Serial.print(" "); + Serial.println(sliderThree); +} +void onSliderThreeChange() { + /* Add your code here to act upon SliderValue3 change */ + Serial.print("New combination: "); + Serial.print(sliderOne); + Serial.print(" "); + Serial.print(sliderTwo); + Serial.print(" "); + Serial.println(sliderThree); +} +/* Send RGB values to the LED pins */ +void setColor(int red, int green, int blue) { + analogWrite(redPin, red); + analogWrite(greenPin, green); + analogWrite(bluePin, blue); +} +void onDisplayChange() { +/* Add your code here to act upon Display change +} +``` + +**Buzzer** + +We will use the buzzer to play a melody when the box is opened. Connect the buzzer to **digital pin 10**, as shown in the picture below. + +![Arduino IoT Bundle](assets/piezo_buzzer_comeplete_rp2040_JAUtOjyKq1.png) + +![Arduino IoT Bundle](assets/piezo_buzzer_part_rp2040_iaPHtGSH0X.png) + +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. + +``` +#define NOTE_B0 31 +#define NOTE_C1 33 +#define NOTE_CS1 35 +#define NOTE_D1 37 +#define NOTE_DS1 39 +#define NOTE_E1 41 +#define NOTE_F1 44 +#define NOTE_FS1 46 +#define NOTE_G1 49 +#define NOTE_GS1 52 +#define NOTE_A1 55 +#define NOTE_AS1 58 +#define NOTE_B1 62 +#define NOTE_C2 65 +#define NOTE_CS2 69 +#define NOTE_D2 73 +#define NOTE_DS2 78 +#define NOTE_E2 82 +#define NOTE_F2 87 +#define NOTE_FS2 93 +#define NOTE_G2 98 +#define NOTE_GS2 104 +#define NOTE_A2 110 +#define NOTE_AS2 117 +#define NOTE_B2 123 +#define NOTE_C3 131 +#define NOTE_CS3 139 +#define NOTE_D3 147 +#define NOTE_DS3 156 +#define NOTE_E3 165 +#define NOTE_F3 175 +#define NOTE_FS3 185 +#define NOTE_G3 196 +#define NOTE_GS3 208 +#define NOTE_A3 220 +#define NOTE_AS3 233 +#define NOTE_B3 247 +#define NOTE_C4 262 +#define NOTE_CS4 277 +#define NOTE_D4 294 +#define NOTE_DS4 311 +#define NOTE_E4 330 +#define NOTE_F4 349 +#define NOTE_FS4 370 +#define NOTE_G4 392 +#define NOTE_GS4 415 +#define NOTE_A4 440 +#define NOTE_AS4 466 +#define NOTE_B4 494 +#define NOTE_C5 523 +#define NOTE_CS5 554 +#define NOTE_D5 587 +#define NOTE_DS5 622 +#define NOTE_E5 659 +#define NOTE_F5 698 +#define NOTE_FS5 740 +#define NOTE_G5 784 +#define NOTE_GS5 831 +#define NOTE_A5 880 +#define NOTE_AS5 932 +#define NOTE_B5 988 +#define NOTE_C6 1047 +#define NOTE_CS6 1109 +#define NOTE_D6 1175 +#define NOTE_DS6 1245 +#define NOTE_E6 1319 +#define NOTE_F6 1397 +#define NOTE_FS6 1480 +#define NOTE_G6 1568 +#define NOTE_GS6 1661 +#define NOTE_A6 1760 +#define NOTE_AS6 1865 +#define NOTE_B6 1976 +#define NOTE_C7 2093 +#define NOTE_CS7 2217 +#define NOTE_D7 2349 +#define NOTE_DS7 2489 +#define NOTE_E7 2637 +#define NOTE_F7 2794 +#define NOTE_FS7 2960 +#define NOTE_G7 3136 +#define NOTE_GS7 3322 +#define NOTE_A7 3520 +#define NOTE_AS7 3729 +#define NOTE_B7 3951 +#define NOTE_C8 4186 +#define NOTE_CS8 4435 +#define NOTE_D8 4699 +#define NOTE_DS8 4978 +/* notes in the melody: */ +int melody[] = { + NOTE_C4, NOTE_G3, NOTE_G3, NOTE_A3, NOTE_G3, 0, NOTE_B3, NOTE_C4 +}; +/* note durations: 4 = quarter note, 8 = eighth note, etc.: */ +int noteDurations[] = { + 4, 8, 8, 4, 4, 4, 4, 4 +}; +void playMelody() { + /* iterate over the notes of the melody: */ + for (int thisNote = 0; thisNote < 8; thisNote++) { + /* to calculate the note duration, take one second divided by the note type. */ + /*e.g. quarter note = 1000 / 4, eighth note = 1000/8, etc.*/ + int noteDuration = 1000 / noteDurations[thisNote]; + tone(10, melody[thisNote], noteDuration); + /* to distinguish the notes, set a minimum time between them. */ + /* the note's duration + 30% seems to work well: */ + int pauseBetweenNotes = noteDuration * 1.30; + delay(pauseBetweenNotes); + /* stop the tone playing: */ + noTone(10); + } +} +``` + +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. + +``` +#include "LiquidCrystal.h" +#include "SPI.h" +#include "thingProperties.h" +#include "Melody.h" +/* RGB LED pins */ +int redPin = 6; +int greenPin = 8; +int bluePin = 7; +/* LCD screen pins */ +const int rs = 12, + en = 11, + d4 = 2, + d5 = 3, + d6 = 4, + d7 = 5; +bool start = true; +LiquidCrystal lcd(rs, en, d4, d5, d6, d7); +void setup() { + pinMode(redPin, OUTPUT); + pinMode(greenPin, OUTPUT); + pinMode(bluePin, OUTPUT); + analogWrite(A3, 0); /* set the brightness of the LCD screen to the maximum value */ + Serial.begin(9600); + delay(1500); + initProperties(); + ArduinoCloud.begin(ArduinoIoTPreferredConnection); + setDebugMessageLevel(2); + ArduinoCloud.printDebugInfo(); + lcd.begin(16, 2); /* begin LCD screen with 16 columns and 2 rows */ +} +void loop() { + ArduinoCloud.update(); + 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); + String numberOne = String(PotOne); + String numberTwo = String(PotTwo); + String numberThree = String(PotThree); + display =String(numberOne + numberTwo + numberThree); + if (start) { + giveColorFeedback(PotOne, PotTwo, PotThree); + if (PotOne == sliderOne && PotTwo == sliderTwo && PotThree == sliderThree) + { + blinkGreenLed(); + start = false; + playMelody(); + } + } + if (!start) { + if (PotOne == 0 && PotTwo == 0 && PotThree == 0) { + start = true; + } + } +} +/* Give feedback based on how close the potentiometer are to the combination value +The more it's close the warmer is the color of the LED */ +void giveColorFeedback(int PotOne, int PotTwo, int PotThree) { + if (abs(PotOne - sliderOne) <= 1 && abs(PotTwo - sliderTwo) <= 1 && abs(PotThree - sliderThree) <= 1 ) { + /* Red */ + setColor(255, 0, 0); + } + else if (abs(PotOne - sliderOne) <= 3 && abs(PotTwo - sliderTwo) <= 3 && abs(PotThree - sliderThree) <= 3 ) { + /* yellow */ + setColor(255, 255, 0); + } + else if (abs(PotOne - sliderOne) <= 4 && abs(PotTwo - sliderTwo) <= 4 && abs(PotThree - sliderThree) <= 4 ) { + /* aqua */ + setColor(0, 255, 255); + } + else { + /* blue */ + setColor(0, 0, 255); + } +} +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 initLCD() { + Serial.println(">>> begin LCD"); + lcd.begin(16, 2); + lcd.print(" Initialising"); + + delay(100); +} +void onSliderOneChange() { + /* Add your code here to act upon SliderValue1 change */ + Serial.print("New combination: "); + Serial.print(sliderOne); + Serial.print(" "); + Serial.print(sliderTwo); + Serial.print(" "); + Serial.println(sliderThree); +} +void onSliderTwoChange() { + /* Add your code here to act upon SliderValue2 change */ + Serial.print("New combination: "); + Serial.print(sliderOne); + Serial.print(" "); + Serial.print(sliderTwo); + Serial.print(" "); + Serial.println(sliderThree); +} +void onSliderThreeChange() { + /* Add your code here to act upon SliderValue3 change */ + Serial.print("New combination: "); + Serial.print(sliderOne); + Serial.print(" "); + Serial.print(sliderTwo); + Serial.print(" "); + Serial.println(sliderThree); +} +/* Send RGB values to the LED pins */ +void setColor(int red, int green, int blue) { + analogWrite(redPin, red); + analogWrite(greenPin, green); + analogWrite(bluePin, blue); +} +void playMelody() { + /* iterate over the notes of the melody: */ + for (int thisNote = 0; thisNote < 8; thisNote++) { + /* to calculate the note duration, take one second divided by the note type. */ + /*e.g. quarter note = 1000 / 4, eighth note = 1000/8, etc. */ + int noteDuration = 1000 / noteDurations[thisNote]; + tone(10, melody[thisNote], noteDuration); + /* to distinguish the notes, set a minimum time between them. */ + /* the note's duration + 30% seems to work well: */ + int pauseBetweenNotes = noteDuration * 1.30; + delay(pauseBetweenNotes); + /* stop the tone playing: */ + noTone(10); + } +} +void onDisplayChange() { +/* Add your code here to act upon Display change */ +} +``` + +**Servo Motor** + +> **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. + +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. + +![Arduino IoT Bundle](assets/servo_motor_part_rp2040_4ZqZ4C9F5w.png) + +![Arduino IoT Bundle](assets/servo_motor_comeplete_rp2040_mXHekbPnRO.png) + +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. + +```arduino +#include "LiquidCrystal.h" +#include "SPI.h" +#include "thingProperties.h" +#include "Melody.h" +#include "Servo.h" +int pos = 0; +Servo myservo; +/* RGB LED pins */ +int redPin = 6; +int greenPin = 8; +int bluePin = 7; +/* LCD screen pins */ +const int rs = 12, + en = 11, + d4 = 2, + d5 = 3, + d6 = 4, + d7 = 5; +bool start = true; +LiquidCrystal lcd(rs, en, d4, d5, d6, d7); +void setup() { + pinMode(redPin, OUTPUT); + pinMode(greenPin, OUTPUT); + pinMode(bluePin, OUTPUT); + analogWrite(A3, 0); /* set the brightness of the LCD screen to the maximum value */ + Serial.begin(9600); + delay(1500); + initProperties(); + ArduinoCloud.begin(ArduinoIoTPreferredConnection); + setDebugMessageLevel(2); + ArduinoCloud.printDebugInfo(); + lcd.begin(16, 2); /* begin LCD screen with 16 columns and 2 rows */ +myservo.attach(9); +myservo.write(pos); +} +void loop() { + ArduinoCloud.update(); + 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); + String numberOne = String(PotOne); + String numberTwo = String(PotTwo); + String numberThree = String(PotThree); + display =String(numberOne + numberTwo + numberThree); + if (start) { + giveColorFeedback(PotOne, PotTwo, PotThree); + if (PotOne == sliderOne && PotTwo == sliderTwo && PotThree == sliderThree) + { + blinkGreenLed(); + start = false; + open_the_box(); + playMelody(); + } + } + if (!start) { + if (PotOne == 0 && PotTwo == 0 && PotThree == 0) { + start = true; + close_the_box(); + } + } +} +/* Give feedback based on how close the potentiometer are to the combination value +The more it's close the warmer is the color of the LED */ +void giveColorFeedback(int PotOne, int PotTwo, int PotThree) { + if (abs(PotOne - sliderOne) <= 1 && abs(PotTwo - sliderTwo) <= 1 && abs(PotThree - sliderThree) <= 1 ) { + /* Red */ + setColor(255, 0, 0); + } + else if (abs(PotOne - sliderOne) <= 3 && abs(PotTwo - sliderTwo) <= 3 && abs(PotThree - sliderThree) <= 3 ) { + /* yellow */ + setColor(255, 255, 0); + } + else if (abs(PotOne - sliderOne) <= 4 && abs(PotTwo - sliderTwo) <= 4 && abs(PotThree - sliderThree) <= 4 ) { + /* aqua */ + setColor(0, 255, 255); + } + else { + /* blue */ + setColor(0, 0, 255); + } +} +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 open_the_box() { + for (pos = 0; pos <= 90; pos += 1) { /* goes from 0 degrees to 90 degrees */ + myservo.write(pos); /* tell servo to go to position in variable 'pos' */ + delay(15); /* waits 15ms for the servo to reach the position */ + } +} +void close_the_box() { + for (pos = 90; pos >= 0; pos -= 1) { /* goes from 90 degrees to 0 degrees */ + myservo.write(pos); /* tell servo to go to position in variable 'pos' */ + delay(15); /* waits 15ms for the servo to reach the position */ + } +} +void initLCD() { + Serial.println(">>> begin LCD"); + lcd.begin(16, 2); + lcd.print(" Initialising"); + + delay(100); +} +void onSliderOneChange() { + /* Add your code here to act upon SliderValue1 change */ + Serial.print("New combination: "); + Serial.print(sliderOne); + Serial.print(" "); + Serial.print(sliderTwo); + Serial.print(" "); + Serial.println(sliderThree); +} +void onSliderTwoChange() { + /* Add your code here to act upon SliderValue2 change */ + Serial.print("New combination: "); + Serial.print(sliderOne); + Serial.print(" "); + Serial.print(sliderTwo); + Serial.print(" "); + Serial.println(sliderThree); +} +void onSliderThreeChange() { + /* Add your code here to act upon SliderValue3 change */ + Serial.print("New combination: "); + Serial.print(sliderOne); + Serial.print(" "); + Serial.print(sliderTwo); + Serial.print(" "); + Serial.println(sliderThree); +} +/* Send RGB values to the LED pins */ +void setColor(int red, int green, int blue) { + analogWrite(redPin, red); + analogWrite(greenPin, green); + analogWrite(bluePin, blue); +} +void onDisplayChange() { +/* Add your code here to act upon Display change */ +} +``` + +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. + +### Build Your Puzzle Box + +It wouldn't be a box without a box, so download the case file below and use it as guide to build your own. Note that we used a 2mm cardboard. + +### Want to Know More? + +This tutorial is part of a series of experiments that familiarize you with the Arduino IoT Bundle. All experiments can be built using the components contained in the IoT Bundle. + +* [I Love You Pillow with the Arduino IoT Bundle](/tutorials/iot-bundle/i-love-you-pillow) +* [Pavlov's Cat with the Arduino IoT Bundle](/tutorials/iot-bundle/pavlovs-cat) +* [Plant Communicator with the Arduino IoT Bundle](/tutorials/iot-bundle/plant-communicator) +* [The Nerd with the Arduino IoT Bundle](/tutorials/iot-bundle/the-nerd) + +## Full Code + + \ No newline at end of file diff --git a/content/hardware/08.kits/maker/iot-bundle/tutorials/puzzlebox/hero-banner.png b/content/hardware/08.kits/maker/iot-bundle/tutorials/puzzlebox/hero-banner.png new file mode 100644 index 0000000000..442a6a6ec0 Binary files /dev/null and b/content/hardware/08.kits/maker/iot-bundle/tutorials/puzzlebox/hero-banner.png differ diff --git a/content/hardware/08.kits/maker/iot-bundle/tutorials/the-nerd/assets/_45dZFAyOab.png b/content/hardware/08.kits/maker/iot-bundle/tutorials/the-nerd/assets/_45dZFAyOab.png new file mode 100644 index 0000000000..01b727bbe8 Binary files /dev/null and b/content/hardware/08.kits/maker/iot-bundle/tutorials/the-nerd/assets/_45dZFAyOab.png differ diff --git a/content/hardware/08.kits/maker/iot-bundle/tutorials/the-nerd/assets/nerd-cloud-setup_RC5c4S0ASc.gif b/content/hardware/08.kits/maker/iot-bundle/tutorials/the-nerd/assets/nerd-cloud-setup_RC5c4S0ASc.gif new file mode 100644 index 0000000000..4899546efb Binary files /dev/null and b/content/hardware/08.kits/maker/iot-bundle/tutorials/the-nerd/assets/nerd-cloud-setup_RC5c4S0ASc.gif differ diff --git a/content/hardware/08.kits/maker/iot-bundle/tutorials/the-nerd/assets/screenshot_2022-11-18_175524_4XRWc1dHYc.png b/content/hardware/08.kits/maker/iot-bundle/tutorials/the-nerd/assets/screenshot_2022-11-18_175524_4XRWc1dHYc.png new file mode 100644 index 0000000000..492baba52c Binary files /dev/null and b/content/hardware/08.kits/maker/iot-bundle/tutorials/the-nerd/assets/screenshot_2022-11-18_175524_4XRWc1dHYc.png differ diff --git a/content/hardware/08.kits/maker/iot-bundle/tutorials/the-nerd/assets/the_nerd_m3DggOdFBj.gif b/content/hardware/08.kits/maker/iot-bundle/tutorials/the-nerd/assets/the_nerd_m3DggOdFBj.gif new file mode 100644 index 0000000000..fae6d314ac Binary files /dev/null and b/content/hardware/08.kits/maker/iot-bundle/tutorials/the-nerd/assets/the_nerd_m3DggOdFBj.gif differ diff --git a/content/hardware/08.kits/maker/iot-bundle/tutorials/the-nerd/assets/the_nerd_rp2040_dqr7egmpao_ESpsLy8iaq.png b/content/hardware/08.kits/maker/iot-bundle/tutorials/the-nerd/assets/the_nerd_rp2040_dqr7egmpao_ESpsLy8iaq.png new file mode 100644 index 0000000000..cc6786368b Binary files /dev/null and b/content/hardware/08.kits/maker/iot-bundle/tutorials/the-nerd/assets/the_nerd_rp2040_dqr7egmpao_ESpsLy8iaq.png differ diff --git a/content/hardware/08.kits/maker/iot-bundle/tutorials/the-nerd/content.md b/content/hardware/08.kits/maker/iot-bundle/tutorials/the-nerd/content.md new file mode 100644 index 0000000000..b632adf314 --- /dev/null +++ b/content/hardware/08.kits/maker/iot-bundle/tutorials/the-nerd/content.md @@ -0,0 +1,149 @@ +--- +title: "The Nerd with Arduino IoT Bundle" +description: "Create your own IoT pet with Arduino and the Arduino Cloud!" +coverImage: "assets/_45dZFAyOab.png" +tags: [IoT Cloud, Creative, Sensors] +author: "Arduino_Genuino" +source: "https://create.arduino.cc/projecthub/Arduino_Genuino/the-nerd-with-arduino-iot-bundle-b1d0ca" +--- + +## Components and Supplies + +- [Arduino IoT Bundle](https://store.arduino.cc/iot-bundle) + +## Apps and Online Services + +- [Arduino IoT Cloud](https://cloud.arduino.cc) + +## About This Project + +**Create a desktop pet with the help of the Arduino IoT Cloud!** + +The Nerd is a desktop electronic pet that survives by eating and some sunlight. In order for it to thrive, you must feed it periodically and expose it to sunlight. If it is running out of food, it will communicate an SOS in Morse code using its built-in piezo speaker. + +### In a Nutshell + +The Nerd will need food which you can give it by pressing its button. Otherwise it will complain by making noise with the buzzer until you either feed it or put it in sunlight. The nerd will be connected to the Arduino Cloud, where we can visualize the amount of food the Nerd has and the level of light it is in. The cloud will also handle the timing elements needed in the code. If the Nerd runs out of food, it will die dramatically, making a lot of noise. + +### Components + +* RGB LED +* Phototransistor +* Buzzer +* Push button +* 220 Ohm resistor +* 10K Ohm resistor + +### Learning Goals + +* Introducing the Arduino IoT Cloud +* Introducing the Arduino IoT Remote app +* Managing sensors with the Arduino IoT Cloud +* Creating an Arduino IoT Cloud Dashboard + +### Want to Know More? + +This tutorial is part of a series of experiments that familiarise you with the Arduino MKR IoT Bundle. All experiments can be built using the components contained in the Arduino MKR IoT Bundle. + +* [I Love You Pillow with the Arduino IoT Bundle ](/tutorials/iot-bundle/i-love-you-pillow) +* [Puzzle Box with Arduino IoT Bundle ](/tutorials/iot-bundle/puzzlebox) +* [Plant Communicator with the Arduino IoT Bundle ](/tutorials/iot-bundle/plant-communicator) +* [Pavlov's Cat with the Arduino IoT Bundle](/tutorials/iot-bundle/pavlovs-cat) + +### Circuit + +In this project, we will be using the following circuit. In it we have a 220 ohm resistor connected between ground and the A2 pin used for the phototransistor. And a 10k ohm resistor connected between between ground and the push button. + +![Arduino IoT Bundle](assets/the_nerd_rp2040_dqr7egmpao_ESpsLy8iaq.png) + +### Setting up the Arduino IoT Cloud + +If you are new to the Arduino IoT Cloud, check out our [Getting Started Guide](https://docs.arduino.cc/arduino-cloud/getting-started/iot-cloud-getting-started). + +Creating a new thing and dashboard is really easy. First go to the Arduino Cloud site [here.](https://create.arduino.cc/iot) Setting up the cloud consists of the following parts: + +* Creating a **Thing** +* Attaching a **Device** +* Adding **Variables** +* Adding **Network** credentials + +![Arduino IoT Bundle](assets/nerd-cloud-setup_RC5c4S0ASc.gif) + +### Variables + +We will start by adding three variables: + +![Arduino IoT Bundle](assets/screenshot_2022-11-18_175524_4XRWc1dHYc.png) + +### Dashboard + +The next step to deploying our project is adding a control panel using the Arduino IoT Dashboards. We can navigate to **Dashboards > Build Dashboard > ADD**, then we can add two widgets and link them to the variable as the following: + +* Gauge widget -> nerdsFood (max. 12) +* Gauge widget -> nerdsLight (max. 500) + +![Arduino IoT Bundle](assets/the_nerd_m3DggOdFBj.gif) + +### Setup Hardware & Sketch + +**Keeping track of the Nerds food** + +To keep track of the Nerds food we will be using an **int** variable. When the Nerd is in enough sunlight and the button is pressed it will be fed. Making a sound so you know that it received the food. The RGB led will change color depending on the Nerds hunger state. + +``` +/* Set color status feedback */ +if(nerdsFood < 4){ /* if starving show red */ + setColor(255, 0, 0); /* Red */ +} +else if(nerdsFood >= 4 && nerdsFood < 8){ + setColor(255, 255, 0); /* yellow */ +} +else{ + setColor(0, 255, 0); /* green */ +} +``` + +And we can use the Arduino Cloud dashboard to keep track of the food numerically. We will also use a time variable from the Arduino Cloud to easily manage when the food count should go down. Here we will let it take 10 minutes before the food supply is decreased by one. The max food storage is set to 12, this can be expanded by changing the threshold in the "**if"** operator, and don't forgot to update the tracker on the dashboard as well so you can accurately track the food that the Nerd has. + +``` +void onNerdsFoodChange(){ + if(nerdsFood == 0 && justWokeUp==false){ + /* DIE :( */ + SOS(); + } +} +``` + +The Nerd will start with 2 food the first time it wakes up, then this value will be tracked by the Cloud. If it dies it will start over with 2 food as well. + +**Checking the light level** + +To check so that our Nerd gets enough sunlight we will use a Phototransistor. Keeping track of the light level with the **nerdsLight** cloud variable. + +``` +int SensorPin = A2; +nerdsLight = analogRead(SensorPin); +``` + +When the Nerd first wakes up, this is when the device is started and the Nerd first receives sunlight. It will make a sound and blink its light. Then the variable will be checked every time you try to give the Nerd some food. The threshold of the light level can be changed if you are having trouble feeding the Nerd. You can use the Cloud to check what values you get when the Nerd is in the light, and then change the threshold here in the code: + +``` +if(nerdsFood < 12 && nerdsLight>150) +``` + +**Time tracker with the Arduino Cloud** + +The Nerd will get hungry every 10 minutes and eat the food it has been given. To keep track of when the Nerd gets hungry we will use a time variable from the Arduino Cloud. We will use the auto generated functions we get from the Arduino cloud to make the changes to the Nerds food when it eats. This function will be executed after a amount of time has passed. The time is determined in the nerdsTime variable configuration. In this example we set the time to be 10 minutes, this has to be stated in seconds. + +### Want to Know More? + +This tutorial is part of a series of experiments that familiarize you with the Arduino IoT Bundle. All experiments can be built using the components contained in the IoT Bundle. + +* [I Love You Pillow with the Arduino IoT Bundle ](/tutorials/iot-bundle/i-love-you-pillow) +* [Puzzle Box with Arduino IoT Bundle ](/tutorials/iot-bundle/puzzlebox) +* [Plant Communicator with the Arduino IoT Bundle ](/tutorials/iot-bundle/plant-communicator) +* [Pavlov's Cat with the Arduino IoT Bundle](/tutorials/iot-bundle/pavlovs-cat) + +## Full Code + + \ No newline at end of file diff --git a/content/hardware/08.kits/maker/iot-bundle/tutorials/the-nerd/hero-banner.png b/content/hardware/08.kits/maker/iot-bundle/tutorials/the-nerd/hero-banner.png new file mode 100644 index 0000000000..2b056aefa4 Binary files /dev/null and b/content/hardware/08.kits/maker/iot-bundle/tutorials/the-nerd/hero-banner.png differ