diff --git a/content/tutorials/generic/arduino-linux-on-up2-board-with-intel-mraa/arduino-linux-on-up2-board-with-intel-mraa.md b/content/tutorials/generic/arduino-linux-on-up2-board-with-intel-mraa/arduino-linux-on-up2-board-with-intel-mraa.md index 1d4a06f081..995941fb86 100644 --- a/content/tutorials/generic/arduino-linux-on-up2-board-with-intel-mraa/arduino-linux-on-up2-board-with-intel-mraa.md +++ b/content/tutorials/generic/arduino-linux-on-up2-board-with-intel-mraa/arduino-linux-on-up2-board-with-intel-mraa.md @@ -1,5 +1,5 @@ --- -title: "Arduino ♥ Linux (on UP2 Board) with Intel Mraa © CC BY-NC-SA" +title: "Arduino ♥ Linux (on UP2 Board) with Intel Mraa" description: "Use libArduino and MRAA to interact with the board OS and report some nice stats with LEDs." tags: [embedded, internet of things, lights, monitoring] author: "Arduino_Genuino" diff --git a/content/tutorials/generic/intel-math-kernel-library-on-arduino/intel-math-kernel-library-on-arduino.md b/content/tutorials/generic/intel-math-kernel-library-on-arduino/intel-math-kernel-library-on-arduino.md index 3e9c7b7785..090346c2cb 100644 --- a/content/tutorials/generic/intel-math-kernel-library-on-arduino/intel-math-kernel-library-on-arduino.md +++ b/content/tutorials/generic/intel-math-kernel-library-on-arduino/intel-math-kernel-library-on-arduino.md @@ -1,5 +1,5 @@ --- -title: "Intel Math Kernel Library on Arduino © CC BY-NC-SA" +title: "Intel Math Kernel Library on Arduino" description: "Learn how to integrate Intel MKL library with a very streamlined Arduino workflow." coverImage: "assets/intel_math_j5NKlynvAk.png" tags: [embedded] diff --git a/content/tutorials/generic/interacting-with-a-ti-sensortag-from-an-intel-nuc.md/interacting-with-a-ti-sensortag-from-an-intel-nuc.md.md b/content/tutorials/generic/interacting-with-a-ti-sensortag-from-an-intel-nuc.md/interacting-with-a-ti-sensortag-from-an-intel-nuc.md.md index ca9b68f4c8..333c1ffc95 100644 --- a/content/tutorials/generic/interacting-with-a-ti-sensortag-from-an-intel-nuc.md/interacting-with-a-ti-sensortag-from-an-intel-nuc.md.md +++ b/content/tutorials/generic/interacting-with-a-ti-sensortag-from-an-intel-nuc.md/interacting-with-a-ti-sensortag-from-an-intel-nuc.md.md @@ -1,5 +1,5 @@ --- -title: "Interacting with a TI SensorTag from an Intel NUC © CC BY-NC-SA" +title: "Interacting with a TI SensorTag from an Intel NUC" description: "This project shows you how setup an Intel NUC to interact with a TI SensorTag device using Bluetooth® Low Energy." coverImage: "assets/intel_bluetooth_Rx75ZbMLc8.png" tags: [internet of things] diff --git a/content/tutorials/projects/alexa-light-my-mood/alexa-light-my-mood.md b/content/tutorials/projects/alexa-light-my-mood/alexa-light-my-mood.md index 575fc42fd8..d525d32e8e 100644 --- a/content/tutorials/projects/alexa-light-my-mood/alexa-light-my-mood.md +++ b/content/tutorials/projects/alexa-light-my-mood/alexa-light-my-mood.md @@ -1,5 +1,5 @@ --- -title: "Alexa, Light My Mood © CC BY-NC-SA" +title: "Alexa, Light My Mood" description: "Learn how to control your MKR RGB Shield using Arduino IoT Cloud and Amazon Alexa." coverImage: "assets/_FhGbSMUC5c.png" difficulty: intermediate diff --git a/content/tutorials/projects/arduino-iot-cloud-amazon-alexa-integration/arduino-iot-cloud-amazon-alexa-integration.md b/content/tutorials/projects/arduino-iot-cloud-amazon-alexa-integration/arduino-iot-cloud-amazon-alexa-integration.md index 1254108039..36453470a7 100644 --- a/content/tutorials/projects/arduino-iot-cloud-amazon-alexa-integration/arduino-iot-cloud-amazon-alexa-integration.md +++ b/content/tutorials/projects/arduino-iot-cloud-amazon-alexa-integration/arduino-iot-cloud-amazon-alexa-integration.md @@ -1,5 +1,5 @@ --- -title: "Arduino IoT Cloud Amazon Alexa Integration © CC BY-NC" +title: "Arduino IoT Cloud Amazon Alexa Integration" description: "Learn how to use Arduino IoT Cloud and Amazon Alexa to interact with your sensors." coverImage: "assets/blob_ognVMF5UTp.png" tags: [environmental sensing, home automation, smart appliances] diff --git a/content/tutorials/projects/cancellino/cancellino.md b/content/tutorials/projects/cancellino/cancellino.md index 2ac23c4642..429404404d 100644 --- a/content/tutorials/projects/cancellino/cancellino.md +++ b/content/tutorials/projects/cancellino/cancellino.md @@ -1,5 +1,5 @@ --- -title: "Cancellino © CC BY-NC" +title: "Cancellino" description: "Control everything with a SINGLE phone call." coverImage: "assets/blob_c9oY2qvB4r.png" tags: [home automation, internet of things, remote control] diff --git a/content/tutorials/projects/control-two-relays-with-an-sms/control-two-relays-with-an-sms.md b/content/tutorials/projects/control-two-relays-with-an-sms/control-two-relays-with-an-sms.md index 2140f14e0a..1be87bdf78 100644 --- a/content/tutorials/projects/control-two-relays-with-an-sms/control-two-relays-with-an-sms.md +++ b/content/tutorials/projects/control-two-relays-with-an-sms/control-two-relays-with-an-sms.md @@ -1,5 +1,5 @@ --- -title: "Control Two Relays with an SMS © GPL3+" +title: "Control Two Relays with an SMS" description: "Drive the relays of the MKR Relay Shield connected to a MKR GSM 1400 with an SMS." coverImage: "assets/blob_PWZsWS7C1J.png" tags: [communication, home automation, remote control] diff --git a/content/tutorials/projects/control-your-iot-cloud-kit-via-blynk/control-your-iot-cloud-kit-via-blynk.md b/content/tutorials/projects/control-your-iot-cloud-kit-via-blynk/control-your-iot-cloud-kit-via-blynk.md index 315979a53a..5c6dbaf144 100644 --- a/content/tutorials/projects/control-your-iot-cloud-kit-via-blynk/control-your-iot-cloud-kit-via-blynk.md +++ b/content/tutorials/projects/control-your-iot-cloud-kit-via-blynk/control-your-iot-cloud-kit-via-blynk.md @@ -1,5 +1,5 @@ --- -title: "Control Your IoT Cloud Kit via Blynk © CERN-OHL" +title: "Control Your IoT Cloud Kit via Blynk" description: "Use the popular Blynk app to control and change the state of your IoT Cloud Kit through your smartphone." coverImage: "assets/blob_vVw5dIKQgP.png" tags: [arduino, blynk, iot] diff --git a/content/tutorials/projects/control-your-iot-cloud-kit-via-mqtt-and-node-red/control-your-iot-cloud-kit-via-mqtt-and-node-red.md b/content/tutorials/projects/control-your-iot-cloud-kit-via-mqtt-and-node-red/control-your-iot-cloud-kit-via-mqtt-and-node-red.md index bb132a14b2..2d9d2acff0 100644 --- a/content/tutorials/projects/control-your-iot-cloud-kit-via-mqtt-and-node-red/control-your-iot-cloud-kit-via-mqtt-and-node-red.md +++ b/content/tutorials/projects/control-your-iot-cloud-kit-via-mqtt-and-node-red/control-your-iot-cloud-kit-via-mqtt-and-node-red.md @@ -1,5 +1,5 @@ --- -title: "Control Your IoT Cloud Kit via MQTT and Node-RED © CC BY" +title: "Control Your IoT Cloud Kit via MQTT and Node-RED" description: "We are going to use popular tools such as Node-RED and the MQTT protocol to create a simple dashabord esposing data and a simple UI" coverImage: "assets/blob_Q08iq374rE.png" tags: [environmental sensing, mqtt, node-red] diff --git a/content/tutorials/projects/full-control-of-your-tv-using-alexa-and-arduino-iot-cloud/full-control-of-your-tv-using-alexa-and-arduino-iot-cloud.md b/content/tutorials/projects/full-control-of-your-tv-using-alexa-and-arduino-iot-cloud/full-control-of-your-tv-using-alexa-and-arduino-iot-cloud.md index 0bd43967e2..dcc1933b07 100644 --- a/content/tutorials/projects/full-control-of-your-tv-using-alexa-and-arduino-iot-cloud/full-control-of-your-tv-using-alexa-and-arduino-iot-cloud.md +++ b/content/tutorials/projects/full-control-of-your-tv-using-alexa-and-arduino-iot-cloud/full-control-of-your-tv-using-alexa-and-arduino-iot-cloud.md @@ -1,5 +1,5 @@ --- -title: "Full Control of Your TV Using Alexa and Arduino IoT Cloud © CC BY-NC-SA" +title: "Full Control of Your TV Using Alexa and Arduino IoT Cloud" description: "Learn how to use Arduino IoT Cloud and Amazon Alexa to switch the channel, adjust the volume and turn on or off any TV." coverImage: "assets/_VKKWOq5yC4.png" tags: [alexa, cloud, home automation, television] diff --git a/content/tutorials/projects/gnome-forecaster/gnome-forecaster.md b/content/tutorials/projects/gnome-forecaster/gnome-forecaster.md index fa00ba8642..758ee04135 100644 --- a/content/tutorials/projects/gnome-forecaster/gnome-forecaster.md +++ b/content/tutorials/projects/gnome-forecaster/gnome-forecaster.md @@ -1,5 +1,5 @@ --- -title: "Gnome Forecaster © CC BY-SA" +title: "Gnome Forecaster" description: "Our Gnome becomes a weather forecaster with an Arduino Nano Every and a pressure sensor. Get your local forecast without the internet." coverImage: "assets/blob_kwfPOeEtt2.png" tags: [nanoevery, pressure, weather] diff --git a/content/tutorials/projects/gnome-traveller/gnome-traveller.md b/content/tutorials/projects/gnome-traveller/gnome-traveller.md index e0ee384b20..e6b9a24fb0 100644 --- a/content/tutorials/projects/gnome-traveller/gnome-traveller.md +++ b/content/tutorials/projects/gnome-traveller/gnome-traveller.md @@ -1,5 +1,5 @@ --- -title: "Gnome Traveller © CC BY" +title: "Gnome Traveller" description: "Our Gnome is ready to follow you in your travels and keep track of all the places you visit, thanks to a GPS shield and the Nano Every." coverImage: "assets/blob_CEAMRFvHo9.png" tags: [gps, nano, tracking] diff --git a/content/tutorials/projects/i-love-you-pillow-with-mkr-wifi-1010/assets/blob_JltCzS6wMx.png b/content/tutorials/projects/i-love-you-pillow-with-mkr-wifi-1010/assets/blob_JltCzS6wMx.png deleted file mode 100644 index e72d8848a6..0000000000 Binary files a/content/tutorials/projects/i-love-you-pillow-with-mkr-wifi-1010/assets/blob_JltCzS6wMx.png and /dev/null differ diff --git a/content/tutorials/projects/i-love-you-pillow-with-mkr-wifi-1010/assets/capacitiveexample_6dTzWdC9JH.jpg b/content/tutorials/projects/i-love-you-pillow-with-mkr-wifi-1010/assets/capacitiveexample_6dTzWdC9JH.jpg deleted file mode 100644 index d43666cd1c..0000000000 Binary files a/content/tutorials/projects/i-love-you-pillow-with-mkr-wifi-1010/assets/capacitiveexample_6dTzWdC9JH.jpg and /dev/null differ diff --git a/content/tutorials/projects/i-love-you-pillow-with-mkr-wifi-1010/assets/gif-pillow_7A5pB9hbfF.gif b/content/tutorials/projects/i-love-you-pillow-with-mkr-wifi-1010/assets/gif-pillow_7A5pB9hbfF.gif deleted file mode 100644 index 91e9274a92..0000000000 Binary files a/content/tutorials/projects/i-love-you-pillow-with-mkr-wifi-1010/assets/gif-pillow_7A5pB9hbfF.gif and /dev/null differ diff --git a/content/tutorials/projects/i-love-you-pillow-with-mkr-wifi-1010/assets/layout_bb_bXIwE3EEDm.png b/content/tutorials/projects/i-love-you-pillow-with-mkr-wifi-1010/assets/layout_bb_bXIwE3EEDm.png deleted file mode 100644 index 3640407925..0000000000 Binary files a/content/tutorials/projects/i-love-you-pillow-with-mkr-wifi-1010/assets/layout_bb_bXIwE3EEDm.png and /dev/null differ diff --git a/content/tutorials/projects/i-love-you-pillow-with-mkr-wifi-1010/assets/pillow2-cover_ewfrqi0mot_j0Vbt0P9UJ.jpg b/content/tutorials/projects/i-love-you-pillow-with-mkr-wifi-1010/assets/pillow2-cover_ewfrqi0mot_j0Vbt0P9UJ.jpg deleted file mode 100644 index 2d5dd864eb..0000000000 Binary files a/content/tutorials/projects/i-love-you-pillow-with-mkr-wifi-1010/assets/pillow2-cover_ewfrqi0mot_j0Vbt0P9UJ.jpg and /dev/null differ diff --git a/content/tutorials/projects/i-love-you-pillow-with-mkr-wifi-1010/assets/screen_shot_2017-11-24_at_11_44_15_u2yojrJTyi.png b/content/tutorials/projects/i-love-you-pillow-with-mkr-wifi-1010/assets/screen_shot_2017-11-24_at_11_44_15_u2yojrJTyi.png deleted file mode 100644 index 0eeda079f3..0000000000 Binary files a/content/tutorials/projects/i-love-you-pillow-with-mkr-wifi-1010/assets/screen_shot_2017-11-24_at_11_44_15_u2yojrJTyi.png and /dev/null differ diff --git a/content/tutorials/projects/i-love-you-pillow-with-mkr-wifi-1010/assets/screen_shot_2017-11-24_at_12_18_58_KkHjzUq6Bj.png b/content/tutorials/projects/i-love-you-pillow-with-mkr-wifi-1010/assets/screen_shot_2017-11-24_at_12_18_58_KkHjzUq6Bj.png deleted file mode 100644 index 6507c453d9..0000000000 Binary files a/content/tutorials/projects/i-love-you-pillow-with-mkr-wifi-1010/assets/screen_shot_2017-11-24_at_12_18_58_KkHjzUq6Bj.png and /dev/null differ diff --git a/content/tutorials/projects/i-love-you-pillow-with-mkr-wifi-1010/assets/screenbot1_rGlFjCfwKJ.png b/content/tutorials/projects/i-love-you-pillow-with-mkr-wifi-1010/assets/screenbot1_rGlFjCfwKJ.png deleted file mode 100644 index 150f78d4b2..0000000000 Binary files a/content/tutorials/projects/i-love-you-pillow-with-mkr-wifi-1010/assets/screenbot1_rGlFjCfwKJ.png and /dev/null differ diff --git a/content/tutorials/projects/i-love-you-pillow-with-mkr-wifi-1010/assets/screenbot2_ody4j7hsz7_sMErWJUWBD.png b/content/tutorials/projects/i-love-you-pillow-with-mkr-wifi-1010/assets/screenbot2_ody4j7hsz7_sMErWJUWBD.png deleted file mode 100644 index 38eab3730b..0000000000 Binary files a/content/tutorials/projects/i-love-you-pillow-with-mkr-wifi-1010/assets/screenbot2_ody4j7hsz7_sMErWJUWBD.png and /dev/null differ diff --git a/content/tutorials/projects/i-love-you-pillow-with-mkr-wifi-1010/assets/screenbot3_bej6rolq0x_c9tIvnMDZT.png b/content/tutorials/projects/i-love-you-pillow-with-mkr-wifi-1010/assets/screenbot3_bej6rolq0x_c9tIvnMDZT.png deleted file mode 100644 index 1acefa79d7..0000000000 Binary files a/content/tutorials/projects/i-love-you-pillow-with-mkr-wifi-1010/assets/screenbot3_bej6rolq0x_c9tIvnMDZT.png and /dev/null differ diff --git a/content/tutorials/projects/i-love-you-pillow-with-mkr-wifi-1010/assets/telegram1_M0kZ6yh5MP.jpeg b/content/tutorials/projects/i-love-you-pillow-with-mkr-wifi-1010/assets/telegram1_M0kZ6yh5MP.jpeg deleted file mode 100644 index a9fa5930fb..0000000000 Binary files a/content/tutorials/projects/i-love-you-pillow-with-mkr-wifi-1010/assets/telegram1_M0kZ6yh5MP.jpeg and /dev/null differ diff --git a/content/tutorials/projects/i-love-you-pillow-with-mkr-wifi-1010/assets/telegram2_UopqPCCu2G.jpeg b/content/tutorials/projects/i-love-you-pillow-with-mkr-wifi-1010/assets/telegram2_UopqPCCu2G.jpeg deleted file mode 100644 index 162a318e94..0000000000 Binary files a/content/tutorials/projects/i-love-you-pillow-with-mkr-wifi-1010/assets/telegram2_UopqPCCu2G.jpeg and /dev/null differ diff --git a/content/tutorials/projects/i-love-you-pillow-with-mkr-wifi-1010/assets/telegram3_CCulqr6iNl.jpeg b/content/tutorials/projects/i-love-you-pillow-with-mkr-wifi-1010/assets/telegram3_CCulqr6iNl.jpeg deleted file mode 100644 index a5ba836f4e..0000000000 Binary files a/content/tutorials/projects/i-love-you-pillow-with-mkr-wifi-1010/assets/telegram3_CCulqr6iNl.jpeg and /dev/null differ diff --git a/content/tutorials/projects/i-love-you-pillow-with-mkr-wifi-1010/assets/telegram4_5L7j7rgVP1.jpeg b/content/tutorials/projects/i-love-you-pillow-with-mkr-wifi-1010/assets/telegram4_5L7j7rgVP1.jpeg deleted file mode 100644 index 3d62ad230b..0000000000 Binary files a/content/tutorials/projects/i-love-you-pillow-with-mkr-wifi-1010/assets/telegram4_5L7j7rgVP1.jpeg and /dev/null differ diff --git a/content/tutorials/projects/i-love-you-pillow-with-mkr-wifi-1010/assets/telegram5_bqLildIWmH.jpeg b/content/tutorials/projects/i-love-you-pillow-with-mkr-wifi-1010/assets/telegram5_bqLildIWmH.jpeg deleted file mode 100644 index e83c102187..0000000000 Binary files a/content/tutorials/projects/i-love-you-pillow-with-mkr-wifi-1010/assets/telegram5_bqLildIWmH.jpeg and /dev/null differ diff --git a/content/tutorials/projects/i-love-you-pillow-with-mkr-wifi-1010/i-love-you-pillow-with-mkr-wifi-1010.md b/content/tutorials/projects/i-love-you-pillow-with-mkr-wifi-1010/i-love-you-pillow-with-mkr-wifi-1010.md deleted file mode 100644 index 2e83eae5b5..0000000000 --- a/content/tutorials/projects/i-love-you-pillow-with-mkr-wifi-1010/i-love-you-pillow-with-mkr-wifi-1010.md +++ /dev/null @@ -1,289 +0,0 @@ ---- -title: "I Love You Pillow with MKR WiFi 1010 © CC BY-NC" -description: "Open source is love, and so are hugs!" -coverImage: "assets/blob_JltCzS6wMx.png" -tags: [art, internet of things] -author: "Arduino_Genuino" -difficulty: intermediate -source: "https://create.arduino.cc/projecthub/Arduino_Genuino/i-love-you-pillow-with-mkr-wifi-1010-84b6da" ---- - -## Components and Supplies - -- [Arduino MKR IoT Bundle 1010](https://store.arduino.cc/arduino-iot-mkr-wifi-1010-bundle) - -## About This Project - -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 from a Telegram Bot to whatever chat you choose. Stay in touch with your loved one with this huggable device! - -### In a Nutshell - -In this experiment, we will use aluminum foil to create a DIY capacitive sensor that will be used to detect hugs. In order to create our hug-sending-device we will need the following components: - -* Buzzer -* Aluminum foil -* 1 resistor 5M ohm -* Breadboard -* Wires - -![Hide all the electronics inside](assets/gif-pillow_7A5pB9hbfF.gif) - - -![Show your love with a hug!](assets/pillow2-cover_ewfrqi0mot_j0Vbt0P9UJ.jpg) - - -### Learning Goals - -* Introducing Telegram Bots -* Managing capacitive sensors -* Telegram Bots and group chats **#ProTips** -* WiFi best practices **#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 familiarise you with the MKR WiFi 1010 and IoT. All experiments can be built using the components contained in the MKR IoT Bundle. - -* I Love You Pillow with MKR WiFi 1010 -* [Puzzle Box with MKR WiFi 1010](https://create.arduino.cc/projecthub/Arduino_Genuino/puzzlebox-with-mkr-wifi-1010-7a39c4) -* [Pavlov's Cat with MKR WiFi 1010](https://create.arduino.cc/projecthub/Arduino_Genuino/pavlov-s-cat-with-mkr-wifi-1010-9ea418) -* [The Nerd with MKR WiFi 1010](https://create.arduino.cc/projecthub/Arduino_Genuino/the-nerd-with-mkr-wifi-1010-462cc5) -* [Plant Communicator with MKR WiFi 1010](https://create.arduino.cc/projecthub/Arduino_Genuino/plant-communicator-with-mkr-wifi-1010-efc920) - -### Introducing Telegram Bots - -[Telegram](https://telegram.org/) is a popular messaging app for both mobile and desktop. Besides letting us chat with our friends it also allows us to create handy and powerful chat-bots! - -A chat-bot is nothing but a contact you can chat with, but instead a person behind it, there is a machine that replies accordingly to the code you wrote. - -[The TelegramBot library](https://github.com/CasaJasmina/TelegramBot-Library) for Arduino gives us an easy way to implement the logic behind the chat-bot. - -### Create Your Bot - -Creating a bot is so easy! Just follow these few simple steps or take a look at the documentation [here](https://core.telegram.org/bots#3-how-do-i-create-a-bot). - -![Step 1 - Look for BotFather](assets/telegram1_M0kZ6yh5MP.jpeg) - - -![Step 2 - type /newbot to create a Telegram Bot](assets/telegram2_UopqPCCu2G.jpeg) - - -![Step 3 - Type your Bot's name](assets/telegram3_CCulqr6iNl.jpeg) - - -![Step 4 - Type your Bot's username](assets/telegram4_5L7j7rgVP1.jpeg) - - -![Step 5 - Note down your Bot's API token](assets/telegram5_bqLildIWmH.jpeg) - - -### Set Up the Board - -**First off make sure we have all the needed libraries.** Here's the list of all the libraries we will need: - -* WiFiNINA -* TelegramBot -* ArduinoJson -* CapacitiveSensor - -You can easily install them following this [simple guide](https://www.arduino.cc/en/Guide/Libraries). - -In order to use Telegram's API we first need to upload the certificates on the MKR WiFi 1010. **This applies to most of online services and APIs!** - -Upload the Firmware Updater example from the WiFiNINA library and add [api.telegram.org ](http://api.telegram.org/)to the domains. These are the steps to follow: - -* Run the IDE; -* Upload the sketch "Example->WiFiNINA->tools->Firmware updater" -* Open "WiFi101/WiFiNINA firmware updater" in tools -* Click on "Add Domain" -* Add -* Click on "Upload Certificates to WiFi module" -* Upload your sketch - -Let the magic happen! - -**Open the EchoBot example from the TelegramBot library, fill in your WiFi credentials and the API token you received from the BotFather and upload!** - -> example > TelegramBot > EchoBot - -You just created a bot that echoes all your messages. - -### EchoBot and Emoji - -Emojis are everywhere! We will use them to send our love and hugs. Using the EchoBot example is an easy way to see how the bots read your emoji. - -![Send an emoji to the Bot and see what is the encoded equivalent](assets/screen_shot_2017-11-24_at_11_44_15_u2yojrJTyi.png) - - -**Unfortunately the way the bot receives the emoji is not the same used to send them.** 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). In order to create a bot that replies to an heart emoji with another heart emoji we will use a code like this: - -```arduino -void loop() { - message m = bot.getUpdates(); // Read new messages - if ( m.chat_id != 0 ) { // Check if there are some updates - Serial.println(m.text); // print the message received - if (m.text == "u2764ufe0f") { //check if it received an heart emoji - bot.sendMessage(m.chat_id, "\U00002764"); - // Reply to the same chat with the heart emoji - } - } -} -``` - -The result will be: - -![Reply to heart emoji with another heart emoji](assets/screen_shot_2017-11-24_at_12_18_58_KkHjzUq6Bj.png) - - - -### Capacitive Sensor - -Enough with Telegram, let's start building our DIY capacitive sensor! - -The [CapacitiveSensor](https://github.com/PaulStoffregen/CapacitiveSensor) library turns two or more Arduino pins into a capacitive sensor, which can sense the electrical capacitance of the human body. - -All the sensor setup requires is a medium to high value resistor and a piece of aluminum foil. - -**At its most sensitive, the sensor will start to sense a hand or body inches away from the sensor and through different kind of materials**. We will hide our sensor inside the pillow! - -Upload the example sketch, connect the wires and see the result on the console: - -```arduino -#include -CapacitiveSensor foil = CapacitiveSensor(5, 4); -// 10M resistor between pins 5 & 4, pin 4 is sensor pin, add a wire and or foil -void setup() -{ - foil.set_CS_AutocaL_Millis(0xFFFFFFFF); // turn off autocalibrate - Serial.begin(9600); -} -void loop() -{ - long start = millis(); - long sensor_value = foil.capacitiveSensor(30); - Serial.print(millis() - start); // check on performance in milliseconds - Serial.print("\t"); // tab character for debug windown spacing - Serial.print(sensor_value); // print sensor output - Serial.println("\t"); // print sensor output 3 - delay(500); // arbitrary delay to limit data to serial port -} -``` - - - -![See values on the console](assets/capacitiveexample_6dTzWdC9JH.jpg) - - -We will use `sensor_value` as a threshold to detect hugs! - -### The Heartbeat - -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. - -```arduino -int Buzzer = 8; // Pin attached to the buzzer -void setup() {} -void loop() { - HeartBeat(); - delay(1000); -} -void HeartBeat() { - tone(Buzzer, 31, 200); // tone(Pin, Note, Duration); - delay(200); - tone(Buzzer, 31, 400); - delay(200); - noTone(Buzzer); - delay(1000); -} -``` - -For a more complex use of the buzzer and the Tone function take a look at the dropdown menu examples and look for `Digital > ToneMelody` - -## Complete Sketch - - - -## Schematics -![Love your pillow with MKR WiFi 1010](assets/layout_bb_bXIwE3EEDm.png) - -### #ProTip: Chat-Id and Group-Chat - -In order to send messages, a bot needs a **chat-id.** The chat id is the unique identifier of a chat between someone and a bot. In order to get the bot to send messages to a specific person you first need that person to text the bot and save the chat-id of that specific chat. - -In this project, the bot will reply only to the very last person who text it no matter who that was. - -**The bots are public, everyone can text a Bot!** - -If you want to include the bot in a group chat you need to disable the privacy mode allowing the bot to read all the messages, otherwise it would only be able to detect commands that start with `/:` - -![Text @BotFather with the /mybot command and select your Bot and Bot Settings](assets/screenbot1_rGlFjCfwKJ.png) - - -![Select Group Privacy](assets/screenbot2_ody4j7hsz7_sMErWJUWBD.png) - - -![Turn off the Privacy Settings](assets/screenbot3_bej6rolq0x_c9tIvnMDZT.png) - - -### #ProTip: WiFi Best Practices - -WiFi can be tricky. Sometimes it just turns off for few seconds with apparently no reason at all. This could be a problem for your Arduino since most of the time we run the WiFi connection function only at the beginning of the sketch. - -Online services can be tricky as well, When the Arduino sends a request to a server (Telegram in this case) it waits for a reply. For hundreds of reasons a reply can fail to arrive, keeping the Arduino in an infinite loop. - -**To make your project more stable, you can add a watchdog.**A watchdog is a timer that has to be periodically updated, otherwise it will reboot the board. - -You can use these two libraries to add a watchdog to your project: - -* [Adafruit SleepyDog](https://github.com/adafruit/Adafruit_SleepyDog) -* [Adafruit ASF Core](https://github.com/adafruit/Adafruit_ASFcore) // has to be downloaded and installed manually from Github - -The EchoBot example will then look like this: - -```arduino -#include -#include -#include -#include -// Initialize Wifi connection to the router -char ssid[] = "xxxx"; // your network SSID (name) -char pass[] = "yyyy"; // your network key -// Initialize Telegram BOT -const char BotToken[] = "xxxx"; -WiFiSSLClient client; -TelegramBot bot (BotToken, client); -void setup() { - Serial.begin(115200); - while (!Serial) {} - delay(3000); - // attempt to connect to Wifi network: - Serial.print("Connecting Wifi: "); - Serial.println(ssid); - while (WiFi.begin(ssid, pass) != WL_CONNECTED) { - Serial.print("."); - delay(500); - } - Serial.println(""); - Serial.println("WiFi connected"); - bot.begin(); - Watchdog.enable(10000); // set the timer to 10 sec -} -void loop() { - Watchdog.reset(); // if this function is not called within 10 seconds the board will reset itself - message m = bot.getUpdates(); // Read new messages - if ( m.chat_id != 0 ) { // Checks if there are some updates - Serial.println(m.text); - bot.sendMessage(m.chat_id, m.text); // Reply to the same chat with the same text - } else { - Serial.println("no new message"); - } -} -``` - diff --git a/content/tutorials/projects/i2s-theremin/i2s-theremin.md b/content/tutorials/projects/i2s-theremin/i2s-theremin.md index a2fe267817..16f3cb2c17 100644 --- a/content/tutorials/projects/i2s-theremin/i2s-theremin.md +++ b/content/tutorials/projects/i2s-theremin/i2s-theremin.md @@ -1,5 +1,5 @@ --- -title: "I2S Theremin © GPL3+" +title: "I2S Theremin" description: "Discover how to make an I2S Theremin based on the new Arduino I2S library." coverImage: "assets/1XxDkvet6xpYPKeYpUNM.png" tags: [audio, maker] diff --git a/content/tutorials/projects/iot-air-quality-checker/iot-air-quality-checker.md b/content/tutorials/projects/iot-air-quality-checker/iot-air-quality-checker.md index e08e1bd43a..0b4347b768 100644 --- a/content/tutorials/projects/iot-air-quality-checker/iot-air-quality-checker.md +++ b/content/tutorials/projects/iot-air-quality-checker/iot-air-quality-checker.md @@ -1,5 +1,5 @@ --- -title: "IoT Air Quality checker © LGPL" +title: "IoT Air Quality checker" description: "Would you like to know quality of the air inside / outside your house, or in your DIY lab? Let's build this IoT Air Quality checker!" coverImage: "assets/_Vqcv50XM6W.png" tags: [diy, iot] diff --git a/content/tutorials/projects/localize-your-board-with-an-sms/localize-your-board-with-an-sms.md b/content/tutorials/projects/localize-your-board-with-an-sms/localize-your-board-with-an-sms.md index 151ce354f4..2eed2aa06d 100644 --- a/content/tutorials/projects/localize-your-board-with-an-sms/localize-your-board-with-an-sms.md +++ b/content/tutorials/projects/localize-your-board-with-an-sms/localize-your-board-with-an-sms.md @@ -1,5 +1,5 @@ --- -title: "Localize Your Board with an SMS © CC BY" +title: "Localize Your Board with an SMS" description: "Get the position of your MKR GSM 1400 on your smartphone through an SMS with a Google Maps link." coverImage: "assets/blob_FLqNPWjaVR.png" tags: [monitoring, tracking] diff --git a/content/tutorials/projects/lorawan-farming-with-mkr-wan-1310/lorawan-farming-with-mkr-wan-1310.md b/content/tutorials/projects/lorawan-farming-with-mkr-wan-1310/lorawan-farming-with-mkr-wan-1310.md index 6d2905cbbd..1c574082ef 100644 --- a/content/tutorials/projects/lorawan-farming-with-mkr-wan-1310/lorawan-farming-with-mkr-wan-1310.md +++ b/content/tutorials/projects/lorawan-farming-with-mkr-wan-1310/lorawan-farming-with-mkr-wan-1310.md @@ -1,5 +1,5 @@ --- -title: "LoRaWAN Farming with MKR WAN 1310 © Apache-2.0" +title: "LoRaWAN Farming with MKR WAN 1310" description: "Let's collect sensor data with MKR WAN 1300 or 1310 and combine it with weather forecast in order to optimize watering in a wide area!" coverImage: "assets/blob_KruXU85KZx.png" tags: [mkr1300, mkr1310, nodered, ttn] diff --git a/content/tutorials/projects/love-you-pillow/assets/capacitiveexample_3aMZiELbXt.png b/content/tutorials/projects/love-you-pillow/assets/capacitiveexample_3aMZiELbXt.png deleted file mode 100644 index 182f0556db..0000000000 Binary files a/content/tutorials/projects/love-you-pillow/assets/capacitiveexample_3aMZiELbXt.png and /dev/null differ diff --git a/content/tutorials/projects/love-you-pillow/assets/gif-pillow_7A5pB9hbfF.gif b/content/tutorials/projects/love-you-pillow/assets/gif-pillow_7A5pB9hbfF.gif deleted file mode 100644 index 00f6ddbb8e..0000000000 Binary files a/content/tutorials/projects/love-you-pillow/assets/gif-pillow_7A5pB9hbfF.gif and /dev/null differ diff --git a/content/tutorials/projects/love-you-pillow/assets/middle-pillow_k2OtsJsBrM.png b/content/tutorials/projects/love-you-pillow/assets/middle-pillow_k2OtsJsBrM.png deleted file mode 100644 index 656e92a328..0000000000 Binary files a/content/tutorials/projects/love-you-pillow/assets/middle-pillow_k2OtsJsBrM.png and /dev/null differ diff --git a/content/tutorials/projects/love-you-pillow/assets/pillow-cover_aJCbEB6I6M.png b/content/tutorials/projects/love-you-pillow/assets/pillow-cover_aJCbEB6I6M.png deleted file mode 100644 index 86c1138c94..0000000000 Binary files a/content/tutorials/projects/love-you-pillow/assets/pillow-cover_aJCbEB6I6M.png and /dev/null differ diff --git a/content/tutorials/projects/love-you-pillow/assets/pillow2-cover_eWFrQi0MOT.png b/content/tutorials/projects/love-you-pillow/assets/pillow2-cover_eWFrQi0MOT.png deleted file mode 100644 index aff09fbd1c..0000000000 Binary files a/content/tutorials/projects/love-you-pillow/assets/pillow2-cover_eWFrQi0MOT.png and /dev/null differ diff --git a/content/tutorials/projects/love-you-pillow/assets/pillow_layout_UXnVy28bHe.png b/content/tutorials/projects/love-you-pillow/assets/pillow_layout_UXnVy28bHe.png deleted file mode 100644 index bd11b7ae03..0000000000 Binary files a/content/tutorials/projects/love-you-pillow/assets/pillow_layout_UXnVy28bHe.png and /dev/null differ diff --git a/content/tutorials/projects/love-you-pillow/assets/screen1_YZntSAAfOf.png b/content/tutorials/projects/love-you-pillow/assets/screen1_YZntSAAfOf.png deleted file mode 100644 index cdbfda68da..0000000000 Binary files a/content/tutorials/projects/love-you-pillow/assets/screen1_YZntSAAfOf.png and /dev/null differ diff --git a/content/tutorials/projects/love-you-pillow/assets/screen2_Zzt45ZS9wX.png b/content/tutorials/projects/love-you-pillow/assets/screen2_Zzt45ZS9wX.png deleted file mode 100644 index 082f5e296e..0000000000 Binary files a/content/tutorials/projects/love-you-pillow/assets/screen2_Zzt45ZS9wX.png and /dev/null differ diff --git a/content/tutorials/projects/love-you-pillow/assets/screen3_WAGbYdHcos.png b/content/tutorials/projects/love-you-pillow/assets/screen3_WAGbYdHcos.png deleted file mode 100644 index f4b3d9755f..0000000000 Binary files a/content/tutorials/projects/love-you-pillow/assets/screen3_WAGbYdHcos.png and /dev/null differ diff --git a/content/tutorials/projects/love-you-pillow/assets/screen_shot_2017-11-24_at_11_44_15_u2yojrJTyi.png b/content/tutorials/projects/love-you-pillow/assets/screen_shot_2017-11-24_at_11_44_15_u2yojrJTyi.png deleted file mode 100644 index d8feffd8b8..0000000000 Binary files a/content/tutorials/projects/love-you-pillow/assets/screen_shot_2017-11-24_at_11_44_15_u2yojrJTyi.png and /dev/null differ diff --git a/content/tutorials/projects/love-you-pillow/assets/screen_shot_2017-11-24_at_12_18_58_KkHjzUq6Bj.png b/content/tutorials/projects/love-you-pillow/assets/screen_shot_2017-11-24_at_12_18_58_KkHjzUq6Bj.png deleted file mode 100644 index 68e945338f..0000000000 Binary files a/content/tutorials/projects/love-you-pillow/assets/screen_shot_2017-11-24_at_12_18_58_KkHjzUq6Bj.png and /dev/null differ diff --git a/content/tutorials/projects/love-you-pillow/assets/screenbot1_rGlFjCfwKJ.png b/content/tutorials/projects/love-you-pillow/assets/screenbot1_rGlFjCfwKJ.png deleted file mode 100644 index db88d8e1fa..0000000000 Binary files a/content/tutorials/projects/love-you-pillow/assets/screenbot1_rGlFjCfwKJ.png and /dev/null differ diff --git a/content/tutorials/projects/love-you-pillow/assets/screenbot2_odY4J7HSZ7.png b/content/tutorials/projects/love-you-pillow/assets/screenbot2_odY4J7HSZ7.png deleted file mode 100644 index a25a4feabb..0000000000 Binary files a/content/tutorials/projects/love-you-pillow/assets/screenbot2_odY4J7HSZ7.png and /dev/null differ diff --git a/content/tutorials/projects/love-you-pillow/assets/screenbot3_BEJ6rOLq0x.png b/content/tutorials/projects/love-you-pillow/assets/screenbot3_BEJ6rOLq0x.png deleted file mode 100644 index 99d1fcefb1..0000000000 Binary files a/content/tutorials/projects/love-you-pillow/assets/screenbot3_BEJ6rOLq0x.png and /dev/null differ diff --git a/content/tutorials/projects/love-you-pillow/assets/telegram1_M0kZ6yh5MP.jpeg b/content/tutorials/projects/love-you-pillow/assets/telegram1_M0kZ6yh5MP.jpeg deleted file mode 100644 index fdae58c72f..0000000000 Binary files a/content/tutorials/projects/love-you-pillow/assets/telegram1_M0kZ6yh5MP.jpeg and /dev/null differ diff --git a/content/tutorials/projects/love-you-pillow/assets/telegram2_FYOriTKNwu.jpeg b/content/tutorials/projects/love-you-pillow/assets/telegram2_FYOriTKNwu.jpeg deleted file mode 100644 index 7fe307f71e..0000000000 Binary files a/content/tutorials/projects/love-you-pillow/assets/telegram2_FYOriTKNwu.jpeg and /dev/null differ diff --git a/content/tutorials/projects/love-you-pillow/assets/telegram3_lFvK2dkXD8.jpeg b/content/tutorials/projects/love-you-pillow/assets/telegram3_lFvK2dkXD8.jpeg deleted file mode 100644 index 8dbc4f923f..0000000000 Binary files a/content/tutorials/projects/love-you-pillow/assets/telegram3_lFvK2dkXD8.jpeg and /dev/null differ diff --git a/content/tutorials/projects/love-you-pillow/assets/telegram4_slhrT9pUCd.jpeg b/content/tutorials/projects/love-you-pillow/assets/telegram4_slhrT9pUCd.jpeg deleted file mode 100644 index b4acf2f263..0000000000 Binary files a/content/tutorials/projects/love-you-pillow/assets/telegram4_slhrT9pUCd.jpeg and /dev/null differ diff --git a/content/tutorials/projects/love-you-pillow/assets/telegram5_mClwN4Krjw.jpeg b/content/tutorials/projects/love-you-pillow/assets/telegram5_mClwN4Krjw.jpeg deleted file mode 100644 index 460b054332..0000000000 Binary files a/content/tutorials/projects/love-you-pillow/assets/telegram5_mClwN4Krjw.jpeg and /dev/null differ diff --git a/content/tutorials/projects/love-you-pillow/love-you-pillow.md b/content/tutorials/projects/love-you-pillow/love-you-pillow.md deleted file mode 100644 index 34010a5269..0000000000 --- a/content/tutorials/projects/love-you-pillow/love-you-pillow.md +++ /dev/null @@ -1,319 +0,0 @@ ---- -title: "Love You Pillow © CC BY-NC" -description: "Open source is love, and so are hugs!" -coverImage: "assets/pillow-cover_aJCbEB6I6M.png" -tags: [internet of things, iot] -author: "Arduino_Genuino" -difficulty: intermediate -source: "https://create.arduino.cc/projecthub/arduino/love-you-pillow-f08931" ---- - -## Components and Supplies - -- [Arduino MKR IoT Bundle](https://store.arduino.cc/usa/arduino-iot-mkr1000-bundle) - -## Apps and Online Services - -- Telegram - -## About This Project - -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 from a Telegram Bot to whatever chat you choose. - -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. - -In order to create our hug-sending-device we will need the following components: - -- Buzzer -- Aluminium foil -- 1 resistor 5M ohm -- Breadboard -- Wires - -![Hide all the electronics inside](assets/gif-pillow_7A5pB9hbfF.gif) - -![Show your love with a hug!](assets/pillow2-cover_eWFrQi0MOT.png) - -### Learning Goals - -* Introducing Telegram Bots -* Managing capacitive sensors -* Telegram Bots and group chats **#ProTips** -* WiFi best practices **#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 familiarise you with the MKR1000 and IoT. All experiments can be built using the components contained in the MKR IoT Bundle. - -* I Love You Pillow -* [Puzzle Box](https://create.arduino.cc/projecthub/arduino/puzzlebox-c1f374) -* [Pavlov's Cat](https://create.arduino.cc/projecthub/arduino/pavlov-s-cat-7e6577) -* [The Nerd](https://create.arduino.cc/projecthub/arduino/the-nerd-0144f9) -* [Plant Communicator](https://create.arduino.cc/projecthub/arduino/plant-communicator-7ea06f) - -### Introducing Telegram Bots - -[Telegram](https://telegram.org/) is a popular messaging app for both mobile and desktop. Besides letting us chat with our friends it also allows us to create handy and powerful chat-bots! - -A chat-bot is nothing but a contact you can chat with, but instead a person behind it, there is a machine that replies accordingly to the code you wrote. - -The [TelegramBot library](https://github.com/CasaJasmina/TelegramBot-Library) for Arduino gives us an easy way to implement the logic behind the chat-bot. - -### Create Your Bot - -Creating a bot is so easy! - -Just follow these few simple steps or take a look at the documentation [here.](https://core.telegram.org/bots#3-how-do-i-create-a-bot) - -![Step 1: Look for @BotFather](assets/telegram1_M0kZ6yh5MP.jpeg) - - - -![Step 2: Type /newbot to create a new Telegram bot](assets/telegram2_FYOriTKNwu.jpeg) - - - -![Step 3: Type your Bot's name](assets/telegram3_lFvK2dkXD8.jpeg) - - - -![Step 4: Type your Bot's username](assets/telegram4_slhrT9pUCd.jpeg) - - - -![Step 5: Note down your Bot's API token](assets/telegram5_mClwN4Krjw.jpeg) - - - -### Set Up the Board - -**First off make sure we have all the needed libraries.** - -Here's the list of all the libraries we will need: - -* WiFi101 -* TelegramBot -* ArduinoJson -* CapacitiveSensor - -You can easily install them following this simple [guide](https://www.arduino.cc/en/Guide/Libraries). - -In order to use Telegram's API we first need to upload the certificates on the MKR1000. **This applies to most of online services and APIs!** - -Upload the Firmware Updater example from the WiFi101 library and add [api.telegram.org](http://api.telegram.org/) to the domains. - -> examples > WiFi101 > FirmwareUpdater - -**If you are using the Arduino Web Editor this feature is not yet implemented and you need to do this through the** **[Arduino Desktop Application.](https://www.arduino.cc/en/Main/Software)** - -![Open and upload FirmwareUpdater example](assets/screen1_YZntSAAfOf.png) - - -![Click on Tools and select "WiFi101 Firmware updater" from the dropdown menu](assets/screen2_Zzt45ZS9wX.png) - - - -![Add the api.telegram.org domain and upload it to the board](assets/screen3_WAGbYdHcos.png) - - -Let the magic happen! - -**Open the EchoBot example from the TelegramBot library, fill in your WiFi credentials and the API token you received from the BotFather and upload!** - -> example > TelegramBot > EchoBot - -You just created a bot that echoes all your messages. - -### EchoBot and Emoji - -Emojis are everywhere! We will use them to send our love and hugs. Using the EchoBot example is an easy way to see how the bots read your emoji. - -![Send an emoji to the bot and see what is the encoded equivalent](assets/screen_shot_2017-11-24_at_11_44_15_u2yojrJTyi.png) - - -**Unfortunately the way the bot receives the emoji is not the same used to send them.** 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) In order to create a bot that replies to an heart emoji with another heart emoji we will use a code like this: - -```arduino -void loop() { - message m = bot.getUpdates(); // Read new messages - if ( m.chat_id != 0 ){ // Check if there are some updates - Serial.println(m.text); // print the message received - if(m.text == "u2764ufe0f"){ //check if it received an heart emoji - bot.sendMessage(m.chat_id, "\U00002764"); - // Reply to the same chat with the heart emoji - } - } -} -``` - -The result will be: - -![Reply to heart emoji with another heart emoji](assets/screen_shot_2017-11-24_at_12_18_58_KkHjzUq6Bj.png) - - -### Capacitive Sensor - -Enough with Telegram, let's start building our DIY capacitive sensor! - -The [CapacitiveSensor](https://github.com/PaulStoffregen/CapacitiveSensor) library turns two or more Arduino pins into a capacitive sensor, which can sense the electrical capacitance of the human body. All the sensor setup requires is a medium to high value resistor and a piece of aluminum foil. - -**At its most sensitive, the sensor will start to sense a hand or body inches away from the sensor and through different kind of materials**. We will hide our sensor inside the pillow! - -Upload the example sketch, connect the wires and see the result on the console: - -```arduino -#include -CapacitiveSensor foil = CapacitiveSensor(5,4); -// 10M resistor between pins 5 & 4, pin 4 is sensor pin, add a wire and or foil -void setup() -{ - foil.set_CS_AutocaL_Millis(0xFFFFFFFF); // turn off autocalibrate - Serial.begin(9600); -} -void loop() -{ - long start = millis(); - long sensor_value = foil.capacitiveSensor(30); - Serial.print(millis() - start); // check on performance in milliseconds - Serial.print("\t"); // tab character for debug windown spacing - Serial.print(sensor_value); // print sensor output - Serial.println("\t"); // print sensor output 3 - delay(500); // arbitrary delay to limit data to serial port -} -``` - - - -![See the values in the serial monitor](assets/capacitiveexample_3aMZiELbXt.png) - - - - - -We will use `sensor_value` as a threshold to detect hugs! - -### The Heartbeat - -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. - -```arduino -int Buzzer = 8; // Pin attached to the buzzer -void setup(){} -void loop(){ - HeartBeat(); - delay(1000); -} -void HeartBeat(){ - tone(Buzzer, 31, 200); // tone(Pin, Note, Duration); - delay(200); - tone(Buzzer, 31, 400); - delay(200); - noTone(Buzzer); - delay(1000); -} -``` - -For a more complex use of the buzzer and the Tone function take a look at the dropdown menu examples and look for `Digital > ToneMelody` - -## Complete Sketch - - - -## Schematics - -![The schematics.](assets/pillow_layout_UXnVy28bHe.png) -### #ProTip: Chat-Id and Group-Chat - -In order to send messages, a bot needs a **chat-id.** - -The chat id is the unique identifier of a chat between someone and a bot. In order to get the bot to send messages to a specific person you first need that person to text the bot and save the chat-id of that specific chat. - -In this project, the bot will reply only to the very last person who text it no matter who that was. - -**The bots are public, everyone can text a Bot!** - -If you want to include the bot in a group chat you need to disable the privacy mode allowing the bot to read all the messages, otherwise it would only be able to detect commands that start with `/:` - -![Text @BotFather with the /mybots command, and select your bot and Bot Settings](assets/screenbot1_rGlFjCfwKJ.png) - - - -![Select Group Privacy](assets/screenbot2_odY4J7HSZ7.png) - - -![Turn off the Privacy setting](assets/screenbot3_BEJ6rOLq0x.png) - - - -### #ProTip: WiFi Best Practices - -WiFi can be tricky. Sometimes it just turns off for few seconds with apparently no reason at all. This could be a problem for your Arduino since most of the time we run the WiFi connection function only at the beginning of the sketch. - -Online services can be tricky as well, When the Arduino sends a request to a server (Telegram in this case) it waits for a reply. For hundreds of reasons a reply can fail to arrive, keeping the Arduino in an infinite loop. - -**To make your project more stable, you can add a watchdog.** - -A watchdog is a timer that has to be periodically updated, otherwise it will reboot the board. - -You can use these two libraries to add a watchdog to your project: - -* [Adafruit SleepyDog](https://github.com/adafruit/Adafruit_SleepyDog) -* [Adafruit ASF Core](https://github.com/adafruit/Adafruit_ASFcore) has to be downloaded and installed manually from Github - -The EchoBot example will then look like this: - -```arduino -#include -#include -#include -#include -// Initialize Wifi connection to the router -char ssid[] = "xxxx"; // your network SSID (name) -char pass[] = "yyyy"; // your network key -// Initialize Telegram BOT -const char BotToken[] = "xxxx"; -WiFiSSLClient client; -TelegramBot bot (BotToken, client); -void setup() { - Serial.begin(115200); - while (!Serial) {} - delay(3000); - // attempt to connect to Wifi network: - Serial.print("Connecting Wifi: "); - Serial.println(ssid); - while (WiFi.begin(ssid, pass) != WL_CONNECTED) { - Serial.print("."); - delay(500); - } - Serial.println(""); - Serial.println("WiFi connected"); - bot.begin(); - Watchdog.enable(10000); // set the timer to 10 sec -} -void loop() { - Watchdog.reset(); // if this function is not called within 10 seconds the board will reset itself - message m = bot.getUpdates(); // Read new messages - if ( m.chat_id != 0 ){ // Checks if there are some updates - Serial.println(m.text); - bot.sendMessage(m.chat_id, m.text); // Reply to the same chat with the same text - } else { - Serial.println("no new message"); - } -} -``` \ No newline at end of file diff --git a/content/tutorials/projects/make-it-rain-clap-machine/make-it-rain-clap-machine.md b/content/tutorials/projects/make-it-rain-clap-machine/make-it-rain-clap-machine.md index f90b8fba31..3c1414b066 100644 --- a/content/tutorials/projects/make-it-rain-clap-machine/make-it-rain-clap-machine.md +++ b/content/tutorials/projects/make-it-rain-clap-machine/make-it-rain-clap-machine.md @@ -1,5 +1,5 @@ --- -title: "Make-It-Rain Clap Machine © GPL3+" +title: "Make-It-Rain Clap Machine" description: "Just got paid? Perfect! Time to make this fun Make-it-Rain machine. Clap your hands and let the money flow!" coverImage: "assets/fUHXu7JT9QoW85TPFr7P.jpg" tags: [clap, fun, machine] diff --git a/content/tutorials/projects/make-your-iot-cloud-kit-send-you-updates-on-telegram/make-your-iot-cloud-kit-send-you-updates-on-telegram.md b/content/tutorials/projects/make-your-iot-cloud-kit-send-you-updates-on-telegram/make-your-iot-cloud-kit-send-you-updates-on-telegram.md index c680cde6ac..e09640d147 100644 --- a/content/tutorials/projects/make-your-iot-cloud-kit-send-you-updates-on-telegram/make-your-iot-cloud-kit-send-you-updates-on-telegram.md +++ b/content/tutorials/projects/make-your-iot-cloud-kit-send-you-updates-on-telegram/make-your-iot-cloud-kit-send-you-updates-on-telegram.md @@ -1,5 +1,5 @@ --- -title: "Make Your IoT Cloud Kit Send You Updates on Telegram © GPL3+" +title: "Make Your IoT Cloud Kit Send You Updates on Telegram" description: "Read, monitor and get notified about environmental data using Arduino MKR(s), the Environmental Shield, and MKR Relay Proto Shield." coverImage: "assets/blob_VQVTggaLFW.png" tags: [environmental sensing, telegram] diff --git a/content/tutorials/projects/mkr-fox-1200-movement-trigger/mkr-fox-1200-movement-trigger.md b/content/tutorials/projects/mkr-fox-1200-movement-trigger/mkr-fox-1200-movement-trigger.md index 8cc9b0278b..2a9c7b6526 100644 --- a/content/tutorials/projects/mkr-fox-1200-movement-trigger/mkr-fox-1200-movement-trigger.md +++ b/content/tutorials/projects/mkr-fox-1200-movement-trigger/mkr-fox-1200-movement-trigger.md @@ -1,5 +1,5 @@ --- -title: "MKR FOX 1200 Movement Trigger © CC BY-NC" +title: "MKR FOX 1200 Movement Trigger" description: "Use your MKR FOX 1200 as a movement trigger to keep an eye on your belongings." coverImage: "assets/img_0186_a3yjVyo0kX.JPG" tags: [geolocation] diff --git a/content/tutorials/projects/mkr-fox-1200-weather-monitor/mkr-fox-1200-weather-monitor.md b/content/tutorials/projects/mkr-fox-1200-weather-monitor/mkr-fox-1200-weather-monitor.md index 8e453c2881..eef5b33674 100644 --- a/content/tutorials/projects/mkr-fox-1200-weather-monitor/mkr-fox-1200-weather-monitor.md +++ b/content/tutorials/projects/mkr-fox-1200-weather-monitor/mkr-fox-1200-weather-monitor.md @@ -1,5 +1,5 @@ --- -title: "MKR FOX 1200 Weather Monitor © GPL3+" +title: "MKR FOX 1200 Weather Monitor" description: "Turn your MKR FOX 1200 into a battery-powered weather monitor that you can deploy EVERYWHERE. " coverImage: "assets/socials_mkrfox1200_bVlDZFCxco.jpg" tags: [radio, weather] diff --git a/content/tutorials/projects/mkr-zero-weather-data-logger/mkr-zero-weather-data-logger.md b/content/tutorials/projects/mkr-zero-weather-data-logger/mkr-zero-weather-data-logger.md index 80bcf6c047..ca61872cbb 100644 --- a/content/tutorials/projects/mkr-zero-weather-data-logger/mkr-zero-weather-data-logger.md +++ b/content/tutorials/projects/mkr-zero-weather-data-logger/mkr-zero-weather-data-logger.md @@ -1,5 +1,5 @@ --- -title: "MKR Zero Weather Data Logger © GPL3+" +title: "MKR Zero Weather Data Logger" description: "Read temperature and humidity values in a remote location and store the data in an SD card." coverImage: "assets/Weather_Data_Logger_(6_of_10)%20-%20Copy.jpg" tags: [data collection, weather] diff --git a/content/tutorials/projects/pavlov-s-cat-with-mkr-wifi-1010/assets/blob_WbQ9cfPDsT.png b/content/tutorials/projects/pavlov-s-cat-with-mkr-wifi-1010/assets/blob_WbQ9cfPDsT.png deleted file mode 100644 index c82a582930..0000000000 Binary files a/content/tutorials/projects/pavlov-s-cat-with-mkr-wifi-1010/assets/blob_WbQ9cfPDsT.png and /dev/null differ diff --git a/content/tutorials/projects/pavlov-s-cat-with-mkr-wifi-1010/assets/gif-cat_vCx1OHLrzl.gif b/content/tutorials/projects/pavlov-s-cat-with-mkr-wifi-1010/assets/gif-cat_vCx1OHLrzl.gif deleted file mode 100644 index f4a552639d..0000000000 Binary files a/content/tutorials/projects/pavlov-s-cat-with-mkr-wifi-1010/assets/gif-cat_vCx1OHLrzl.gif and /dev/null differ diff --git a/content/tutorials/projects/pavlov-s-cat-with-mkr-wifi-1010/assets/layout_bepper_m4sbv98QTt.png b/content/tutorials/projects/pavlov-s-cat-with-mkr-wifi-1010/assets/layout_bepper_m4sbv98QTt.png deleted file mode 100644 index 593cc6ded6..0000000000 Binary files a/content/tutorials/projects/pavlov-s-cat-with-mkr-wifi-1010/assets/layout_bepper_m4sbv98QTt.png and /dev/null differ diff --git a/content/tutorials/projects/pavlov-s-cat-with-mkr-wifi-1010/assets/layout_complete_ABXhjQhXT8.png b/content/tutorials/projects/pavlov-s-cat-with-mkr-wifi-1010/assets/layout_complete_ABXhjQhXT8.png deleted file mode 100644 index d029747a04..0000000000 Binary files a/content/tutorials/projects/pavlov-s-cat-with-mkr-wifi-1010/assets/layout_complete_ABXhjQhXT8.png and /dev/null differ diff --git a/content/tutorials/projects/pavlov-s-cat-with-mkr-wifi-1010/assets/layout_tyxLnOAQg6.png b/content/tutorials/projects/pavlov-s-cat-with-mkr-wifi-1010/assets/layout_tyxLnOAQg6.png deleted file mode 100644 index 28432a5ca8..0000000000 Binary files a/content/tutorials/projects/pavlov-s-cat-with-mkr-wifi-1010/assets/layout_tyxLnOAQg6.png and /dev/null differ diff --git a/content/tutorials/projects/pavlov-s-cat-with-mkr-wifi-1010/assets/screen_shot_2017-11-23_at_17_06_27_ZUucPxcqfm.png b/content/tutorials/projects/pavlov-s-cat-with-mkr-wifi-1010/assets/screen_shot_2017-11-23_at_17_06_27_ZUucPxcqfm.png deleted file mode 100644 index eb177357b4..0000000000 Binary files a/content/tutorials/projects/pavlov-s-cat-with-mkr-wifi-1010/assets/screen_shot_2017-11-23_at_17_06_27_ZUucPxcqfm.png and /dev/null differ diff --git a/content/tutorials/projects/pavlov-s-cat-with-mkr-wifi-1010/assets/screen_shot_2017-11-26_at_16_27_59_1GTadUzILr.png b/content/tutorials/projects/pavlov-s-cat-with-mkr-wifi-1010/assets/screen_shot_2017-11-26_at_16_27_59_1GTadUzILr.png deleted file mode 100644 index 2ce09a92ea..0000000000 Binary files a/content/tutorials/projects/pavlov-s-cat-with-mkr-wifi-1010/assets/screen_shot_2017-11-26_at_16_27_59_1GTadUzILr.png and /dev/null differ diff --git a/content/tutorials/projects/pavlov-s-cat-with-mkr-wifi-1010/pavlov-s-cat-with-mkr-wifi-1010.md b/content/tutorials/projects/pavlov-s-cat-with-mkr-wifi-1010/pavlov-s-cat-with-mkr-wifi-1010.md deleted file mode 100644 index e8ddd5d17d..0000000000 --- a/content/tutorials/projects/pavlov-s-cat-with-mkr-wifi-1010/pavlov-s-cat-with-mkr-wifi-1010.md +++ /dev/null @@ -1,331 +0,0 @@ ---- -title: "Pavlov's Cat with MKR WiFi 1010 © CC BY-NC" -description: "Time to get Pavlovian on your cat!" -coverImage: "assets/blob_WbQ9cfPDsT.png" -tags: [internet of things] -author: "Arduino_Genuino" -difficulty: intermediate -source: "https://create.arduino.cc/projecthub/Arduino_Genuino/pavlov-s-cat-with-mkr-wifi-1010-9ea418" ---- - -## Components and Supplies - -- [Arduino MKR IoT Bundle 1010](https://store.arduino.cc/arduino-iot-mkr-wifi-1010-bundle) - -## About This Project - -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 MKR IoT Bundle and some cardboard. - -And we all know that cats already love cardboard boxes! Every time the cat hears a certain melody, it receive 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. Once you have reached satisfying statistics, it is time to repurpose the sensor into a wearable. - -Your cat should from then on follow you if you make that beeping sound. - -*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 a messaging service called Telegram, 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. - -**Pro Tip:** You can host a webpage on the MKR WiFi 1010 and display the collected data in a handy table. - - -**Get the cardboard blueprint for this project [here!](https://hacksterio.s3.amazonaws.com/uploads/attachments/387170/pavlovcase_ShVm1OJRIF.dxf -)** - -### Components - -* Servo motor -* Phototransistor -* 220 ohm resistor -* Buzzer - -![The final device.](assets/gif-cat_vCx1OHLrzl.gif) - -### Learning Goals - -In this experiment you will learn how to: - -* Manage Telegram Bots with a custom keyboard -* Set up and manage web server functionality from the MKR WiFi 1010 itself. **#ProTip** - -**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 familiarise you with the MKR WiFi 1010 and IoT. All experiments can be built using the components contained in the MKR IoT Bundle. - -* [I Love You Pillow with MKR WiFI 1010](https://create.arduino.cc/projecthub/Arduino_Genuino/i-love-your-pillow-with-mkr-wifi-1010-84b6da) -* [Puzzle Box with MKR WiFI 1010](https://create.arduino.cc/projecthub/Arduino_Genuino/puzzlebox-with-mkr-wifi-1010-7a39c4) -* Pavlov's Cat with MKR WiFI 1010 -* [The Nerd with MKR WiFI 1010](https://create.arduino.cc/projecthub/Arduino_Genuino/the-nerd-with-mkr-wifi-1010-462cc5) -* [Plant Communicator with MKR WiFI 1010](https://create.arduino.cc/projecthub/Arduino_Genuino/plant-communicator-with-mkr-wifi-1010-efc920) - -### Telegram and Arduino - -[Telegram ](https://telegram.org/)is a popular messaging app for both mobile and desktop. Besides letting us chat with our friends it also allows us to create handy and powerful chat-bots! - -The [TelegramBot library](https://github.com/CasaJasmina/TelegramBot-Library) for Arduino gives us an easy way to implement the logic behind the chat-bot. - -To learn how to create a Bot and manage basic functionalities take a look at the [I Love You Pillow with MKR WiFi 1010](https://create.arduino.cc/projecthub/Arduino_Genuino/i-love-your-pillow-with-mkr-wifi-1010-84b6da) tutorial. You will find the instructions to upload the site certificates for the secure connection in the same project. - -### Create Your Custom Keyboard - -Telegram allows us to create a custom keyboard for fast replies. It means that when you talk to a bot a certain selection of buttons will be displayed instead of the default keyboard. You can easily customize those buttons and improve the user experience of your device.Our custom keyboard looks like this: - -![Custom keyboard](assets/screen_shot_2017-11-26_at_16_27_59_1GTadUzILr.png) - -Custom keyboard - -We will use the first row of buttons to play the melody and dispense food, while the second row of buttons will be used to set the speed of the servo motor and therefore the amount of food to be dispensed. - -**To create a custom keyboard we first need to declare it:** - -```arduino -TelegramKeyboard keyboard_one; -``` - -**Then define the rows:** - -```arduino -const char* row_one[] = {MusicAndFood, MusicNoFood}; -const char* row_two[] = {OnePortion, TwoPortion, ThreePortion}; -``` - -**And finally assign the rows to the keyboard:** - -```arduino -keyboard_one.addRow(row_one, 2); // assign a row to one or more keyboards keyboard_one.addRow(row_two, 3); // second argument is the length of the row -``` - -Remember that an emoji needs to be sent using UNICODE. For instance to send an heart emoji we will use: `\U00002764` - -You can see the full list of unicode emoji codes here. It means that to define our buttons we will use this: - -```arduino -const char* MusicAndFood = "\U0001F3B6 + \U0001F36A"; // Note + Cookie -const char* MusicNoFood = "\U0001F3B6 NO \U0001F36A"; // Note NO Cookie -const char* OnePortion = "\U0001F408"; // CAT -const char* TwoPortion = "\U0001F408 \U0001F408"; // 2 CATS -const char* ThreePortion = "\U0001F408 \U0001F408 \U0001F408"; // 3 CATS -``` - -### Here Is the Full sketch: - -```arduino -#include -#include -#include -const char* ssid = SECRET_SSID; // your network SSID (name) -const char* password = SECRET_PSWD; // your network password -const char BotToken[] = SECRET_BOT_TOKEN; -WiFiSSLClient client; -TelegramBot bot (BotToken, client); -TelegramKeyboard keyboard_one; -String OldChatId = ""; -void setup() { - Serial.begin(115200); - delay(3000); - // attempt to connect to Wifi network: - Serial.print("Connecting Wifi: "); - Serial.println(ssid); - while (WiFi.begin(ssid, password) != WL_CONNECTED) { - Serial.print("."); - delay(500); - } - Serial.println(""); - Serial.println("WiFi connected"); - // choose the emoji you like using UNICODE - // here's the list https://unicode.org/emoji/charts/full-emoji-list.html - const char* MusicAndFood = "\U0001F3B6 + \U0001F36A"; // Note + Cookie - const char* MusicNoFood = "\U0001F3B6 NO \U0001F36A"; // Note NO Cookie - const char* OnePortion = "\U0001F408"; // CAT - const char* TwoPortion = "\U0001F408 \U0001F408"; // 2 CATS - const char* ThreePortion = "\U0001F408 \U0001F408 \U0001F408"; // 3 CATS - // define your row's - const char* row_one[] = {MusicAndFood, MusicNoFood}; - const char* row_two[] = {OnePortion, TwoPortion, ThreePortion}; - keyboard_one.addRow(row_one, 2); // assign a row to one or more keyboards - keyboard_one.addRow(row_two, 3); // second argument is the length of the row - bot.begin(); -} -void loop() { - message m = bot.getUpdates(); // Read new messages - if ( m.chat_id != 0 ) { // Checks if there are some updates - OldChatId = m.chat_id; - Serial.println(m.text); - bot.sendMessage(m.chat_id, "Hello !", keyboard_one); - } - delay(1000); -} -``` - -**Unfortunately the way the bot sends the emojis is not the same used to receive them.** Using the EchoBot example is an easy way to see how bots receive emoji. - -For instance the emoji we will use are received like this: - -```arduino -ud83cudfb6 // Melody -ud83cudf6a // Cookie -ud83dudc08 // Cat -``` - -### 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. - -![Phototransistor wiring.](assets/layout_tyxLnOAQg6.png) - - - -**Note that we used a 220 ohm resistor.** - -To read values from the sensor we will only need a analogRead(A6). 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 -unsigned long timer; -bool startDetecting = true; -int threshold = 200; // arbitrary value -void setup() { - timer = millis(); - Serial.begin(9600); -} -void loop() { - if (startDetecting) { - int value = analogRead(A6); - if (value < threshold) { - Serial.println("cat detected!"); - startDetecting = false; - } - else if (millis() - timer > 120000) { - Serial.println("no cat detected in the past two minutes"); - startDetecting = false; - } - } -} -``` - -**Note that we use the** **`millis()`** **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 accordingly to your light condition. - -### Play the Song - -To play the song we will use the buzzer and the `tone()` function. - -![Buzzer wiring.](assets/layout_bepper_m4sbv98QTt.png) - -We will use a slightly modified version of the standard example **toneMelody.** You can find it in the dropdown menu: - -```arduino -examples > digital > toneMelody. -``` - -### Add the Servo Motor - -The servo is used to open the box and deliver food. - -Note that we use a variable `int PortionAmount = 1;` to set the amount of time the servo has to remain turned 90 degrees. **We will be able to change its value through Telegram.** - -![Servo Wiring.](assets/layout_complete_ABXhjQhXT8.png) - -Attach the servo to pin 7 and upload the this sketch to see it working. - -```arduino -#include -Servo myservo; // create servo object to control a servo -int pos = 0; // variable to store the servo position -int PortionAmount = 1; // Set default amount of food to 1 portion -void setup() { - myservo.attach(7); // attaches the servo on pin 6 to the servo object -} -void loop() { - moveServo(); - delay(2000); -} -void moveServo() { - 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(PortionAmount * 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 - } -}#ProTip: Add a Web Server -``` - - -## Complete Sketch - - - -## Access Point Mode - -One of the most powerful functionalities of the MKR WiFi 1010 is the **Access Point Mode. It allow us to host a web page on the MKR** **WiFi** **1010 that we can access to by using the board IP address and being connected to the same network**. - -We will use this tool to print the data collected by the food dispenser. - -![Web page hosted on the MKR WiFi 1010](assets/screen_shot_2017-11-23_at_17_06_27_ZUucPxcqfm.png) - -Web page hosted on the MKR WiFi 1010 - -**This step requires basic knowledge of HTML and CSS** (or a lot of trust in the example sketch. You can check the basic web sever example at: - -```arduino -> example > WiFi101 > AP_SimpleWebServer -``` - -We will trigger the access point mode by **sending a specific word** to our Telegram Bot, which **will reply with the link to reach the web page.** Then the telegram client will be disconnected and **the web-server is started.** - -```arduino -else if (m.text == "Server") { - IPAddress ip = WiFi.localIP(); - web_server_mode = true; - String message = "To see the webpage go to http://" + IpToString(ip); - bot.sendMessage(m.chat_id, message , keyboard_one); - telegram_client.stop(); - delay(1000); - server.begin(); // start the web server on port 80 -} -``` - -**The web page includes a button that will turn off the web server mode and go back as a telegram client:** - -```arduino -if (currentLine.endsWith("GET /BACKBUTTON")) { // if button pressed - web_server_mode = false; - client.stop(); - delay(1000); - bot.begin(); - bot.sendMessage(OldChatId, "Back online !", keyboard_one); -} -``` - -**Each time the cat detection is ends a new cell of the table is added** with the gathered data: if food was delivered, if the cat showed up within two minutes and how long did it take to reach the dispenser. - -```arduino -AddTableCell(food/noFood, Yes/No, TimeValue); -``` - -Then the String containing all the table cells is updated and integrated in the rest of the main html. - -```arduino -table_cells+=cell; // add new cell -html = html_1 + table_cells + html_2; // add cells to main html -``` - -Check at the final Pro example to see how to integrate all of these new functionalities! - -**Tip:** if you want your data to survive a reset of the board have a look at the Flash Storage library or check the Nerd project! \ No newline at end of file diff --git a/content/tutorials/projects/pavlov-s-cat/assets/buzzers_uG4se7I2lA.png b/content/tutorials/projects/pavlov-s-cat/assets/buzzers_uG4se7I2lA.png deleted file mode 100644 index dc8afbb9e8..0000000000 Binary files a/content/tutorials/projects/pavlov-s-cat/assets/buzzers_uG4se7I2lA.png and /dev/null differ diff --git a/content/tutorials/projects/pavlov-s-cat/assets/gif-cat_vCx1OHLrzl.gif b/content/tutorials/projects/pavlov-s-cat/assets/gif-cat_vCx1OHLrzl.gif deleted file mode 100644 index 10a8b3f6c7..0000000000 Binary files a/content/tutorials/projects/pavlov-s-cat/assets/gif-cat_vCx1OHLrzl.gif and /dev/null differ diff --git a/content/tutorials/projects/pavlov-s-cat/assets/pavlov-cover_SAFuAP2w3x.png b/content/tutorials/projects/pavlov-s-cat/assets/pavlov-cover_SAFuAP2w3x.png deleted file mode 100644 index 15ef54fbd2..0000000000 Binary files a/content/tutorials/projects/pavlov-s-cat/assets/pavlov-cover_SAFuAP2w3x.png and /dev/null differ diff --git a/content/tutorials/projects/pavlov-s-cat/assets/phototransistor_NrTg9CWO4A.png b/content/tutorials/projects/pavlov-s-cat/assets/phototransistor_NrTg9CWO4A.png deleted file mode 100644 index 62da8b4a46..0000000000 Binary files a/content/tutorials/projects/pavlov-s-cat/assets/phototransistor_NrTg9CWO4A.png and /dev/null differ diff --git a/content/tutorials/projects/pavlov-s-cat/assets/screen_shot_2017-11-23_at_17_06_27_ZUucPxcqfm.png b/content/tutorials/projects/pavlov-s-cat/assets/screen_shot_2017-11-23_at_17_06_27_ZUucPxcqfm.png deleted file mode 100644 index d5ec4a80d7..0000000000 Binary files a/content/tutorials/projects/pavlov-s-cat/assets/screen_shot_2017-11-23_at_17_06_27_ZUucPxcqfm.png and /dev/null differ diff --git a/content/tutorials/projects/pavlov-s-cat/assets/screen_shot_2017-11-26_at_16_27_59_1GTadUzILr.png b/content/tutorials/projects/pavlov-s-cat/assets/screen_shot_2017-11-26_at_16_27_59_1GTadUzILr.png deleted file mode 100644 index c194760d62..0000000000 Binary files a/content/tutorials/projects/pavlov-s-cat/assets/screen_shot_2017-11-26_at_16_27_59_1GTadUzILr.png and /dev/null differ diff --git a/content/tutorials/projects/pavlov-s-cat/pavlov-s-cat.md b/content/tutorials/projects/pavlov-s-cat/pavlov-s-cat.md deleted file mode 100644 index 1cea0df2f0..0000000000 --- a/content/tutorials/projects/pavlov-s-cat/pavlov-s-cat.md +++ /dev/null @@ -1,350 +0,0 @@ ---- -title: "Pavlov's Cat © CC BY-NC-SA" -description: "Time to get Pavlovian on your cat! " -coverImage: "assets/pavlov-cover_SAFuAP2w3x.png" -tags: [cat, internet of things, iot, telegram] -author: "Arduino_Genuino" -difficulty: intermediate -source: "https://create.arduino.cc/projecthub/arduino/pavlov-s-cat-7e6577" ---- - -## Components and Supplies - -- [Arduino MKR IoT Bundle](https://store.arduino.cc/usa/arduino-iot-mkr1000-bundle) - -## Apps and Online Services - -- [Telegram](https://telegram.org/) - -## About This Project - -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 MKR IoT Bundle and some cardboard. - -And we all know that cats already love cardboard boxes! - -Every time the cat hears a certain melody, it receive 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. Once you have reached satisfying statistics, it is time to repurpose the sensor into a wearable. Your cat should from then on follow you if you make that beeping sound. - -*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 a messaging service called Telegram, 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. - -**Pro Tip:** You can host a webpage on the MKR1000 and display the collected data in a handy table. - -**Get the cardboard blueprint for this project [here!](https://hacksterio.s3.amazonaws.com/uploads/attachments/387170/pavlovcase_ShVm1OJRIF.dxf -)** - - -### Components - -* Servo motor -* Phototransistor -* 220 ohm resistor -* Buzzer - -![The final device.](assets/gif-cat_vCx1OHLrzl.gif) - -### Learning Goals - -In this experiment you will learn how to: - -* Manage Telegram Bots with a custom keyboard -* Set up and manage web server functionality from the MKR1000 itself. **#ProTip** - -**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 familiarise you with the MKR1000 and IoT. All experiments can be built using the components contained in the MKR IoT Bundle. - -* [I Love You Pillow](https://create.arduino.cc/projecthub/arduino/love-you-pillow-f08931) -* [Puzzle Box](https://create.arduino.cc/projecthub/arduino/puzzlebox-c1f374) -* Pavlov's Cat -* [The Nerd](https://create.arduino.cc/projecthub/arduino/the-nerd-0144f9) -* [Plant Communicator](https://create.arduino.cc/projecthub/arduino/plant-communicator-7ea06f) - -### Telegram and Arduino - -[Telegram ](https://telegram.org/)is a popular messaging app for both mobile and desktop. Besides letting us chat with our friends it also allows us to create handy and powerful chat-bots! - -The [TelegramBot library ](https://github.com/CasaJasmina/TelegramBot-Library)for Arduino gives us an easy way to implement the logic behind the chat-bot. - -To learn how to create a Bot and manage basic functionalities take a look at the [I Love You Pillow](https://create.arduino.cc/projecthub/arduino/love-you-pillow-f08931) tutorial. - -### Create Your Custom Keyboard - -Telegram allows us to create a custom keyboard for fast replies. It means that when you talk to a bot a certain selection of buttons will be displayed instead of the default keyboard. You can easily customize those buttons and improve the user experience of your device. - -Our custom keyboard looks like this: - -![Custom keyboard](assets/screen_shot_2017-11-26_at_16_27_59_1GTadUzILr.png) - - -We will use the first row of buttons to play the melody and dispense food, while the second row of buttons will be used to set the speed of the servo motor and therefore the amount of food to be dispensed. - -**To create a custom keyboard we first need to declare it:** - -```arduino -TelegramKeyboard keyboard_one; -``` - -**Then define the rows:** - -```arduino - const char* row_one[] = {MusicAndFood, MusicNoFood}; - const char* row_two[] = {OnePortion, TwoPortion, ThreePortion}; -``` - -**And finally assign the rows to the keyboard:** - -```arduino -keyboard_one.addRow(row_one, 2); // assign a row to one or more keyboards -keyboard_one.addRow(row_two, 3); // second argument is the length of the row -``` - -Remember that an emoji needs to be sent using UNICODE. 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) It means that to define our buttons we will use this: - -```arduino - const char* MusicAndFood = "\U0001F3B6 + \U0001F36A"; // Note + Cookie - const char* MusicNoFood = "\U0001F3B6 NO \U0001F36A"; // Note NO Cookie - const char* OnePortion = "\U0001F408"; // CAT - const char* TwoPortion = "\U0001F408 \U0001F408"; // 2 CATS - const char* ThreePortion = "\U0001F408 \U0001F408 \U0001F408"; // 3 CATS -``` - -### Here Is the Full sketch: - -```arduino -#include -#include -#include -const char* ssid = SECRET_SSID; // your network SSID (name) -const char* password = SECRET_PSWD; // your network password -const char BotToken[] = SECRET_BOT_TOKEN; -WiFiSSLClient client; -TelegramBot bot (BotToken, client); -TelegramKeyboard keyboard_one; -String OldChatId = ""; -void setup() { - Serial.begin(115200); - delay(3000); - // attempt to connect to Wifi network: - Serial.print("Connecting Wifi: "); - Serial.println(ssid); - while (WiFi.begin(ssid, password) != WL_CONNECTED) { - Serial.print("."); - delay(500); - } - Serial.println(""); - Serial.println("WiFi connected"); - // choose the emoji you like using UNICODE - // here's the list https://unicode.org/emoji/charts/full-emoji-list.html - const char* MusicAndFood = "\U0001F3B6 + \U0001F36A"; // Note + Cookie - const char* MusicNoFood = "\U0001F3B6 NO \U0001F36A"; // Note NO Cookie - const char* OnePortion = "\U0001F408"; // CAT - const char* TwoPortion = "\U0001F408 \U0001F408"; // 2 CATS - const char* ThreePortion = "\U0001F408 \U0001F408 \U0001F408"; // 3 CATS - // define your row's - const char* row_one[] = {MusicAndFood, MusicNoFood}; - const char* row_two[] = {OnePortion, TwoPortion, ThreePortion}; - keyboard_one.addRow(row_one, 2); // assign a row to one or more keyboards - keyboard_one.addRow(row_two, 3); // second argument is the length of the row - bot.begin(); -} -void loop() { - message m = bot.getUpdates(); // Read new messages - if ( m.chat_id != 0 ) { // Checks if there are some updates - OldChatId = m.chat_id; - Serial.println(m.text); - bot.sendMessage(m.chat_id, "Hello !", keyboard_one); - } - delay(1000); -} -``` - -**Unfortunately the way the bot sends the emojis is not the same used to receive them.** Using the EchoBot example is an easy way to see how bots receive emoji. - -For instance the emoji we will use are received like this: - -```arduino -ud83cudfb6 // Melody -ud83cudf6a // Cookie -ud83dudc08 // Cat -``` - -### 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. - -![Phototransistor wiring](assets/phototransistor_NrTg9CWO4A.png) - -Phototransistor wiring - -**Note that we used a 220 ohm resistor.** - -To read values from the sensor we will only need a `analogRead(A6).` - -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 -unsigned long timer; -bool startDetecting = true; -int threshold=200; // arbitrary value -void setup(){ -timer=millis() -Serial.begin(9600); -} -void loop(){ -if (startDetecting) { - int value = analogRead(A6); - if (value < threshold) { - Serial.println("cat detected!"); - startDetecting = false; - } - else if (millis() - timer > 120000) { - Serial.println("no cat detected in the past two minutes"); - startDetecting = false; - } - } -} -``` - -**Note that we use the** **`millis()`** **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 accordingly to your light condition. - -### Play the Song - -To play the song we will use the buzzer and the `tone() `function. - -![Buzzer Wiring](assets/buzzers_uG4se7I2lA.png) - - - -We will use a slightly modified version of the standard example **toneMelody.** You can find it in the dropdown menu: - -```arduino -examples > digital > toneMelody. -``` - -### Add the Servo Motor - -The servo is used to open the box and deliver food. - -Note that we use a variable `int PortionAmount = 1;`to set the amount of time the servo has to remain turned 90 degrees. **We will be able to change its value through Telegram.** - -![Servo Wiring.](assets/../wiringcatfeeder_e6IEC1QTWo%20(1).png) - -Attach the servo to pin 7 and upload the this sketch to see it working. - -```arduino -#include -Servo myservo; // create servo object to control a servo -int pos = 0; // variable to store the servo position -int PortionAmount = 1; // Set default amount of food to 1 portion -void setup() { - myservo.attach(7); // attaches the servo on pin 6 to the servo object -} -void loop() { - moveServo(); - delay(2000); -} -void moveServo() { - 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(PortionAmount * 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 - } -} -``` - -## Complete Sketch - - - - - - - -### #ProTip: Add a Web Server - -One of the most powerful functionalities of the MKR1000 is the **Access Point Mode.** - -**It allow us to host a web page on the MKR1000 that we can access to by using the board IP address and being connected to the same network**. - -We will use this tool to print the data collected by the food dispenser. - -![Web page hosted on the mkr1000](assets/screen_shot_2017-11-23_at_17_06_27_ZUucPxcqfm.png) - -Web page hosted on the mkr1000 - -**This step requires basic knowledge of HTML and CSS** (or a lot of trust in the example sketch. You can check the basic web sever example at: - -```arduino -> example > WiFi101 > AP_SimpleWebServer -``` - -We will trigger the access point mode by **sending a specific word** to our Telegram Bot, which **will reply with the link to reach the web page.** Then the telegram client will be disconnected and **the web-server is started.** - -```arduino -else if(m.text == "Server"){ - IPAddress ip = WiFi.localIP(); - web_server_mode=true; - String message = "To see the webpage go to http://"+IpToString(ip); - bot.sendMessage(m.chat_id, message , keyboard_one); - telegram_client.stop(); - delay(1000); - server.begin(); // start the web server on port 80 - } -``` - -**The web page includes a button that will turn off the web server mode and go back as a telegram client:** - -```arduino -if (currentLine.endsWith("GET /BACKBUTTON")) { // if button pressed - web_server_mode=false; - client.stop(); - delay(1000); - bot.begin(); - bot.sendMessage(OldChatId, "Back online !", keyboard_one); - } -``` - -**Each time the cat detection is ends a new cell of the table is added** with the gathered data: if food was delivered, if the cat showed up within two minutes and how long did it take to reach the dispenser. - -```arduino -AddTableCell(food/noFood, Yes/No, TimeValue); -``` - -Then the String containing all the table cells is updated and integrated in the rest of the main html. - -```arduino - table_cells+=cell; // add new cell - html = html_1 + table_cells + html_2; // add cells to main html -``` - -Check at the final Pro example to see how to integrate all of these new functionalities! - -**Tip:** if you want your data to survive a reset of the board have a look at the [Flash Storage](https://github.com/cmaglie/FlashStorage) library or check the [Nerd](https://create.arduino.cc/projecthub/67621/the-nerd-0144f9) project! - -## #ProTips Code - - diff --git a/content/tutorials/projects/pavlov-s-cat/wiringcatfeeder_e6IEC1QTWo (1).png b/content/tutorials/projects/pavlov-s-cat/wiringcatfeeder_e6IEC1QTWo (1).png deleted file mode 100644 index 427b74a31a..0000000000 Binary files a/content/tutorials/projects/pavlov-s-cat/wiringcatfeeder_e6IEC1QTWo (1).png and /dev/null differ diff --git a/content/tutorials/projects/plant-communicator-with-mkr-wifi-1010/assets/blob_xie6J4O6wE.png b/content/tutorials/projects/plant-communicator-with-mkr-wifi-1010/assets/blob_xie6J4O6wE.png deleted file mode 100644 index f64b7bae10..0000000000 Binary files a/content/tutorials/projects/plant-communicator-with-mkr-wifi-1010/assets/blob_xie6J4O6wE.png and /dev/null differ diff --git a/content/tutorials/projects/plant-communicator-with-mkr-wifi-1010/assets/layouat_complete_mRWD8rFHqj.png b/content/tutorials/projects/plant-communicator-with-mkr-wifi-1010/assets/layouat_complete_mRWD8rFHqj.png deleted file mode 100644 index 9e783caed0..0000000000 Binary files a/content/tutorials/projects/plant-communicator-with-mkr-wifi-1010/assets/layouat_complete_mRWD8rFHqj.png and /dev/null differ diff --git a/content/tutorials/projects/plant-communicator-with-mkr-wifi-1010/assets/layout_simple_kkIX3wtyAi.png b/content/tutorials/projects/plant-communicator-with-mkr-wifi-1010/assets/layout_simple_kkIX3wtyAi.png deleted file mode 100644 index 9d88e82615..0000000000 Binary files a/content/tutorials/projects/plant-communicator-with-mkr-wifi-1010/assets/layout_simple_kkIX3wtyAi.png and /dev/null differ diff --git a/content/tutorials/projects/plant-communicator-with-mkr-wifi-1010/assets/mail_84XpcdsaVR.png b/content/tutorials/projects/plant-communicator-with-mkr-wifi-1010/assets/mail_84XpcdsaVR.png deleted file mode 100644 index 80c5792445..0000000000 Binary files a/content/tutorials/projects/plant-communicator-with-mkr-wifi-1010/assets/mail_84XpcdsaVR.png and /dev/null differ diff --git a/content/tutorials/projects/plant-communicator-with-mkr-wifi-1010/assets/screen_lgwckabe1j_fTFMNfMckG.png b/content/tutorials/projects/plant-communicator-with-mkr-wifi-1010/assets/screen_lgwckabe1j_fTFMNfMckG.png deleted file mode 100644 index f037bcd1eb..0000000000 Binary files a/content/tutorials/projects/plant-communicator-with-mkr-wifi-1010/assets/screen_lgwckabe1j_fTFMNfMckG.png and /dev/null differ diff --git a/content/tutorials/projects/plant-communicator-with-mkr-wifi-1010/assets/screen_shot_2017-11-27_at_21_04_41_tyEJH5iWxT.png b/content/tutorials/projects/plant-communicator-with-mkr-wifi-1010/assets/screen_shot_2017-11-27_at_21_04_41_tyEJH5iWxT.png deleted file mode 100644 index 63ba70ec91..0000000000 Binary files a/content/tutorials/projects/plant-communicator-with-mkr-wifi-1010/assets/screen_shot_2017-11-27_at_21_04_41_tyEJH5iWxT.png and /dev/null differ diff --git a/content/tutorials/projects/plant-communicator-with-mkr-wifi-1010/assets/screen_shot_2017-11-27_at_21_07_10_foyha7p9zk_8jBf7oU9nk.png b/content/tutorials/projects/plant-communicator-with-mkr-wifi-1010/assets/screen_shot_2017-11-27_at_21_07_10_foyha7p9zk_8jBf7oU9nk.png deleted file mode 100644 index 12d6067f44..0000000000 Binary files a/content/tutorials/projects/plant-communicator-with-mkr-wifi-1010/assets/screen_shot_2017-11-27_at_21_07_10_foyha7p9zk_8jBf7oU9nk.png and /dev/null differ diff --git a/content/tutorials/projects/plant-communicator-with-mkr-wifi-1010/assets/screen_shot_2017-11-27_at_21_13_39_TbarFrhjur.png b/content/tutorials/projects/plant-communicator-with-mkr-wifi-1010/assets/screen_shot_2017-11-27_at_21_13_39_TbarFrhjur.png deleted file mode 100644 index 3227caa7c6..0000000000 Binary files a/content/tutorials/projects/plant-communicator-with-mkr-wifi-1010/assets/screen_shot_2017-11-27_at_21_13_39_TbarFrhjur.png and /dev/null differ diff --git a/content/tutorials/projects/plant-communicator-with-mkr-wifi-1010/assets/screen_shot_2017-11-27_at_22_03_05_dq7yRw9jUZ.png b/content/tutorials/projects/plant-communicator-with-mkr-wifi-1010/assets/screen_shot_2017-11-27_at_22_03_05_dq7yRw9jUZ.png deleted file mode 100644 index cca4dc20bd..0000000000 Binary files a/content/tutorials/projects/plant-communicator-with-mkr-wifi-1010/assets/screen_shot_2017-11-27_at_22_03_05_dq7yRw9jUZ.png and /dev/null differ diff --git a/content/tutorials/projects/plant-communicator-with-mkr-wifi-1010/assets/zapier1_OkPVqOZT1l.png b/content/tutorials/projects/plant-communicator-with-mkr-wifi-1010/assets/zapier1_OkPVqOZT1l.png deleted file mode 100644 index 263a576d69..0000000000 Binary files a/content/tutorials/projects/plant-communicator-with-mkr-wifi-1010/assets/zapier1_OkPVqOZT1l.png and /dev/null differ diff --git a/content/tutorials/projects/plant-communicator-with-mkr-wifi-1010/assets/zapier2_b5vEJicvs0.png b/content/tutorials/projects/plant-communicator-with-mkr-wifi-1010/assets/zapier2_b5vEJicvs0.png deleted file mode 100644 index d976f5377c..0000000000 Binary files a/content/tutorials/projects/plant-communicator-with-mkr-wifi-1010/assets/zapier2_b5vEJicvs0.png and /dev/null differ diff --git a/content/tutorials/projects/plant-communicator-with-mkr-wifi-1010/assets/zapier3_1N8ISI2Swv.png b/content/tutorials/projects/plant-communicator-with-mkr-wifi-1010/assets/zapier3_1N8ISI2Swv.png deleted file mode 100644 index cfd385c9a7..0000000000 Binary files a/content/tutorials/projects/plant-communicator-with-mkr-wifi-1010/assets/zapier3_1N8ISI2Swv.png and /dev/null differ diff --git a/content/tutorials/projects/plant-communicator-with-mkr-wifi-1010/assets/zapier4_BUVdjn172D.png b/content/tutorials/projects/plant-communicator-with-mkr-wifi-1010/assets/zapier4_BUVdjn172D.png deleted file mode 100644 index ff716d44c9..0000000000 Binary files a/content/tutorials/projects/plant-communicator-with-mkr-wifi-1010/assets/zapier4_BUVdjn172D.png and /dev/null differ diff --git a/content/tutorials/projects/plant-communicator-with-mkr-wifi-1010/assets/zapier5ok_JtWfezrF19.png b/content/tutorials/projects/plant-communicator-with-mkr-wifi-1010/assets/zapier5ok_JtWfezrF19.png deleted file mode 100644 index 7c879216ae..0000000000 Binary files a/content/tutorials/projects/plant-communicator-with-mkr-wifi-1010/assets/zapier5ok_JtWfezrF19.png and /dev/null differ diff --git a/content/tutorials/projects/plant-communicator-with-mkr-wifi-1010/assets/zapier_2_1_YOaXuJr2Fz.png b/content/tutorials/projects/plant-communicator-with-mkr-wifi-1010/assets/zapier_2_1_YOaXuJr2Fz.png deleted file mode 100644 index 275715d129..0000000000 Binary files a/content/tutorials/projects/plant-communicator-with-mkr-wifi-1010/assets/zapier_2_1_YOaXuJr2Fz.png and /dev/null differ diff --git a/content/tutorials/projects/plant-communicator-with-mkr-wifi-1010/assets/zapier_2_2_IjBQz3YIbs.png b/content/tutorials/projects/plant-communicator-with-mkr-wifi-1010/assets/zapier_2_2_IjBQz3YIbs.png deleted file mode 100644 index 1e908544f5..0000000000 Binary files a/content/tutorials/projects/plant-communicator-with-mkr-wifi-1010/assets/zapier_2_2_IjBQz3YIbs.png and /dev/null differ diff --git a/content/tutorials/projects/plant-communicator-with-mkr-wifi-1010/assets/zapier_2_3_kEv5xkJsvr.png b/content/tutorials/projects/plant-communicator-with-mkr-wifi-1010/assets/zapier_2_3_kEv5xkJsvr.png deleted file mode 100644 index 9f288f1379..0000000000 Binary files a/content/tutorials/projects/plant-communicator-with-mkr-wifi-1010/assets/zapier_2_3_kEv5xkJsvr.png and /dev/null differ diff --git a/content/tutorials/projects/plant-communicator-with-mkr-wifi-1010/assets/zapier_2_4_vmQUz4X493.png b/content/tutorials/projects/plant-communicator-with-mkr-wifi-1010/assets/zapier_2_4_vmQUz4X493.png deleted file mode 100644 index d17b760a65..0000000000 Binary files a/content/tutorials/projects/plant-communicator-with-mkr-wifi-1010/assets/zapier_2_4_vmQUz4X493.png and /dev/null differ diff --git a/content/tutorials/projects/plant-communicator-with-mkr-wifi-1010/assets/zapier_2_5_wfYADfuHKT.png b/content/tutorials/projects/plant-communicator-with-mkr-wifi-1010/assets/zapier_2_5_wfYADfuHKT.png deleted file mode 100644 index 3d65f230f6..0000000000 Binary files a/content/tutorials/projects/plant-communicator-with-mkr-wifi-1010/assets/zapier_2_5_wfYADfuHKT.png and /dev/null differ diff --git a/content/tutorials/projects/plant-communicator-with-mkr-wifi-1010/assets/zapier_2_6_5w0ucMIvoG.png b/content/tutorials/projects/plant-communicator-with-mkr-wifi-1010/assets/zapier_2_6_5w0ucMIvoG.png deleted file mode 100644 index f8f0ca6034..0000000000 Binary files a/content/tutorials/projects/plant-communicator-with-mkr-wifi-1010/assets/zapier_2_6_5w0ucMIvoG.png and /dev/null differ diff --git a/content/tutorials/projects/plant-communicator-with-mkr-wifi-1010/assets/zapier_2_7_rCW1fw8BHb.png b/content/tutorials/projects/plant-communicator-with-mkr-wifi-1010/assets/zapier_2_7_rCW1fw8BHb.png deleted file mode 100644 index 0a6aab1c09..0000000000 Binary files a/content/tutorials/projects/plant-communicator-with-mkr-wifi-1010/assets/zapier_2_7_rCW1fw8BHb.png and /dev/null differ diff --git a/content/tutorials/projects/plant-communicator-with-mkr-wifi-1010/assets/zapier_2_8_L5Lm4HyjHb.png b/content/tutorials/projects/plant-communicator-with-mkr-wifi-1010/assets/zapier_2_8_L5Lm4HyjHb.png deleted file mode 100644 index e586190cfc..0000000000 Binary files a/content/tutorials/projects/plant-communicator-with-mkr-wifi-1010/assets/zapier_2_8_L5Lm4HyjHb.png and /dev/null differ diff --git a/content/tutorials/projects/plant-communicator-with-mkr-wifi-1010/assets/zapier_html_1_YEi9NUpiUC.png b/content/tutorials/projects/plant-communicator-with-mkr-wifi-1010/assets/zapier_html_1_YEi9NUpiUC.png deleted file mode 100644 index e3e583521f..0000000000 Binary files a/content/tutorials/projects/plant-communicator-with-mkr-wifi-1010/assets/zapier_html_1_YEi9NUpiUC.png and /dev/null differ diff --git a/content/tutorials/projects/plant-communicator-with-mkr-wifi-1010/assets/zapier_html_2_Imnnsi71FO.png b/content/tutorials/projects/plant-communicator-with-mkr-wifi-1010/assets/zapier_html_2_Imnnsi71FO.png deleted file mode 100644 index 10d27a44c1..0000000000 Binary files a/content/tutorials/projects/plant-communicator-with-mkr-wifi-1010/assets/zapier_html_2_Imnnsi71FO.png and /dev/null differ diff --git a/content/tutorials/projects/plant-communicator-with-mkr-wifi-1010/assets/zapiertest_qTAGAv6bmo.png b/content/tutorials/projects/plant-communicator-with-mkr-wifi-1010/assets/zapiertest_qTAGAv6bmo.png deleted file mode 100644 index 7ec7c417ec..0000000000 Binary files a/content/tutorials/projects/plant-communicator-with-mkr-wifi-1010/assets/zapiertest_qTAGAv6bmo.png and /dev/null differ diff --git a/content/tutorials/projects/plant-communicator-with-mkr-wifi-1010/plant-communicator-with-mkr-wifi-1010.md b/content/tutorials/projects/plant-communicator-with-mkr-wifi-1010/plant-communicator-with-mkr-wifi-1010.md deleted file mode 100644 index 9c30eaeea3..0000000000 --- a/content/tutorials/projects/plant-communicator-with-mkr-wifi-1010/plant-communicator-with-mkr-wifi-1010.md +++ /dev/null @@ -1,532 +0,0 @@ ---- -title: "Plant Communicator with MKR WiFi 1010 © CC BY-NC" -description: "Ever wished you could talk with your plants?" -coverImage: "assets/blob_xie6J4O6wE.png" -tags: [garden, internet of things] -author: "Arduino_Genuino" -difficulty: advanced -source: "https://create.arduino.cc/projecthub/Arduino_Genuino/plant-communicator-with-mkr-wifi-1010-efc920" ---- - -## Components and Supplies - -- [Arduino MKR IoT Bundle 1010](https://store.arduino.cc/arduino-iot-mkr-wifi-1010-bundle) - -## Apps and Online Services - -- [ThingSpeak API](https://github.com/iobridge/ThingSpeak) -- [Zapier](https://zapier.com/) - -## About This Project - -### Introduction - -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 your plants alive can be quite the challenge as they are very bad at communication. One way to keep them happy is to bring your plants with you, but maybe you don't want to lug around with that big-ole-cactus or fern sticking out of your 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 MKR IoT Bundle components to create a device that remotely surveys the well being of any plant instead. - -### In a Nutshell - -In this experiment you will learn how to protect your plants and make sure they survive as well as using Arduino magic. - -By monitoring moisture, temperature and light, you can make sure that your plants are happy. - -It can send emails and graphs on a daily basis and notify you of its needs. - -### Components - -* TMP36 temperature sensor -* Phototransistor -* DIY moisture sensor - -### Learning Goals - -* Introducing Zapier internet service -* Sending HTTP requests -* Managing Real Time Clock and alarms -* Building a DIY moisture sensor -* Plotting values with thingSpeak **#ProTips** -* Style your email with HTML and CSS **#ProTips** -* Test APIs with PostMan **#ProTips** - -### Want to Know More? - -This tutorial is part of a series of experiments that familiarise you with the MKR WiFI 1010 and IoT. All experiments can be built using the components contained in the MKR IoT Bundle. - -* [Love You Pillow with MKR WiFi 1010](https://create.arduino.cc/projecthub/Arduino_Genuino/i-love-your-pillow-with-mkr-wifi-1010-84b6da) -* [Puzzle Box with MKR WiFi 1010](https://create.arduino.cc/projecthub/Arduino_Genuino/puzzlebox-with-mkr-wifi-1010-7a39c4) -* [Pavlov's Cat with MKR WiFi 1010](https://create.arduino.cc/projecthub/Arduino_Genuino/pavlov-s-cat-with-mkr-wifi-1010-9ea418) -* [The Nerd with MKR WiFi 1010](https://create.arduino.cc/projecthub/Arduino_Genuino/the-nerd-with-mkr-wifi-1010-462cc5) -* Plant Communicator with MKR WiFi 1010 - -### Set up Zapier - -[Zapier ](https://zapier.com/app/explore)is an online automation tool that can easily manage the APIs of other apps for us. It is a great tool to combine multiple tasks or if the app we want to use has complex API that cannot be managed by an Arduino. - -In our case we will use it to send an email with the data retrieved from the Arduino. - -Follow this few simple steps to create your own zap! - -![Create your Zapier account or log in and Make a new Zap](assets/zapier1_OkPVqOZT1l.png) - - - -![Search for Webhooks by Zapier and then select Catch Hook](assets/zapier2_b5vEJicvs0.png) - - - -![Start customising your hook adding the parameters we will send from Arduino](assets/zapier3_1N8ISI2Swv.png) - - - -![Select and copy the Custom Webhook URL](assets/zapier4_BUVdjn172D.png) - - -In order to proceed we need to test our *hook* first copying the given URL, then selecting the Test and Review button that appears when you press Continue*.* Add these parameters to the URL: - -```html -Custom_Webhook_URL?temperature=0&moisture=0&light=0&warning=0 -``` - -Now just copy and paste this URL on a new browser page. You should see a response like this: - -![Pasting the URL formed with our additional parameters into a web browser should produce a result as the one above.](assets/zapiertest_qTAGAv6bmo.png) - - - -![The successful test of the hook is also registered by Zapier](assets/zapier5ok_JtWfezrF19.png) - - - -Congratulations! You just sent an **http request!** - -**This is exactly the what we will do with our Arduino board.** But instead of pasting that URL into a browser page we will send it directly to the Zapier server. Also we will modify the values of the parameters that are now set to zero with our sensors values. - -*For a more advanced way to test and work with API have a look at the* **#ProTip** *at the bottom of the page.* - -After you tested your request you can proceed creating the Zap. - -Proceed in the Edit with the **Do This...** - -![We create the Zap selecting Gmail from the Apps](assets/zapier_2_1_YOaXuJr2Fz.png) - - - -![We want to send an email as action triggered by the webhook](assets/zapier_2_2_IjBQz3YIbs.png) - - - -![When the action is selected we can continue](assets/zapier_2_3_kEv5xkJsvr.png) - - - -![We start filling up the various felds. The first one is the Gmail sender email account](assets/zapier_2_4_vmQUz4X493.png) - - - -![Following the Gmail authorisation step, we proceed with the recipient's email address](assets/zapier_2_5_wfYADfuHKT.png) - - - -![If we select Plain Text for the Body Type, we can proceed with the text shown here.](assets/zapier_2_6_5w0ucMIvoG.png) - - - To access the Catch Hook strings we need to click on the icon in the top right corner of the text input field and this opens a drop down list with the available queries. - -![Check that all the required fields are filled up and also that the body.](assets/zapier_2_7_rCW1fw8BHb.png) - -![As soon as you finish the edit you can proceed with the test and review.](assets/zapier_2_8_L5Lm4HyjHb.png) - - -Check your mailbox to see the generated email from Zapier. It will be from the account you used in the first step of gmail configuration. - -### Set up the Board - -In order to implement all the functionalities we are going to use the following libraries: - -* WiFiNINA // to connect to internet and scan the networks -* RTCZero // to manage time triggered events - -You can download them from the library manager as explained in [this guide](https://www.arduino.cc/en/Guide/Libraries). - -### Sending HTTP Request - -We are now ready to send the HTTP request from the Arduino board.For now we will set an arbitrary value to our parameter that later on will be substituted with real sensor values. - -```arduino -float temperature = 22; -int moisture = 150; -int light = 40; -String warning = "This is a warning message"; -warning.replace(" ", "%20"); -``` - -Note that **the string has to be encoded**, since blank spaces cannot be sent in an HTTP request. All blank spaces are substituted with the encoded equivalent *`%20`* - -After setting up our parameters we will call the `send_email()` function, which will convert all of them into Strings and **will rebuild the same URL that we used before** to then post it to the Zapier server. - -**Fill in this sketch with your WiFi credential and the piece of URL that you received from Zapier and upload.** - -```arduino -#include -#include -const char* ssid = SECRET_SSID; // your network SSID (name) -const char* password = SECRET_PSWD; // your network password -String httpsRequest = SECRET_REQUEST; // your Zapier URL -const char* host = "hooks.zapier.com"; -WiFiSSLClient client; -void setup() { - Serial.begin(9600); - while (!Serial); - delay(2000); - Serial.print("Connecting Wifi: "); - Serial.println(ssid); - while (WiFi.begin(ssid, password) != WL_CONNECTED) { - Serial.print("."); - delay(500); - } - Serial.println(""); - Serial.println("WiFi connected"); -} -void loop() { - float temperature = 22; - int moisture = 150; - int light = 40; - String warning = "This is a warning message"; - warning.replace(" ", "%20"); - send_email(temperature, moistue, light, warning ); - delay(20000) -} -void send_email(float temperature, int moisture, int light, String warning) { - // convert values to String - String _temperature = String(temperature); - String _moisture = String(moisture); - String _light = String(light); - String _warning = warning; - if (client.connect(host, 443)) { - client.println("POST " + httpsRequest + "?temperature=" + _temperature + "&moisture=" + _moisture + "&light=" + _light + "&warning=" + _warning + " HTTP/1.1"); - client.println("Host: " + String(host)); - client.println("Connection: close"); - client.println(); - delay(1000); - while (client.available()) { // Print on the console the answer of the server - char c = client.read(); - Serial.write(c); - } - client.stop(); // Disconnect from the server - } - else { - Serial.println("Failed to connect to client"); - } -} -``` - -It will send an email to the address you choose every 20 seconds. - -**Be careful with the requests, Zapier allow you only 100 free request per month.** - -### RTC and Alarms - -We can use the Real Time clock of the MKR WiFi 1010 to send an email every day at a certain hour. - -This sketch will set the time and date at 16:00 of December 4th 2017 **and then trigger an alarm every day at 16:01.** - -Note that since the alarm is attached to an *interrupt* function **we cannot include any delays**, but we can use boolean variable to trigger actions in the loop() - -```arduino -#include -RTCZero rtc; // create RTC object -/* Change these values to set the current initial time */ -const byte seconds = 0; -const byte minutes = 0; -const byte hours = 16; -/* Change these values to set the current initial date */ -const byte day = 4; -const byte month = 12; -const byte year = 17; -bool email_already_sent = false; -void setup() { - Serial.begin(9600); - while (!Serial); - delay(2000); - rtc.begin(); // initialize RTC 24H format - rtc.setTime(hours, minutes, seconds); - rtc.setDate(day, month, year); - rtc.setAlarmTime(16, 1, 0); // Set the time for the Arduino to send the email - rtc.enableAlarm(rtc.MATCH_HHMMSS); - rtc.attachInterrupt(alarmMatch); -} -void loop() { - if (!email_already_sent) { - // send_email(); - email_already_sent = true; - } -} -void alarmMatch() { // triggered when the alarm goes on - Serial.println("Alarm Match!"); - email_already_sent = false; -} -``` - -### DIY Soil Moisture Sensor - -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.**Using the **1 Mega Ohm resistor** and two wires, we can create our DIY soil moisture sensor! - -![Soil moisture sensor wiring.](assets/layout_simple_kkIX3wtyAi.png) - -Uploading the following sketch you can start reading the values of the sensor, we suggest you **start testing it first in a dry soil** and and note down the value you read. - -**That value will be used to set a threshold** so that the Arduino will know when your plants need water and send you an **emergency email.** - -```arduino -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 soil -int threeshold = 800; -void setup() { - Serial.begin(9600); - while (!Serial); - delay(2000); -} -void loop() { - Serial.println(get_average_moisture()); - delay(5000); -} -int get_average_moisture() { // make an average of 10 values to be more accurate - int tempValue = 0; // variable to temporarily store moisture value - for (int a = 0; a < 10; a++) { - tempValue += analogRead(moisturePin); - delay(100); - } - return tempValue / 10; -} -``` - -### Add Temperature and Light Sensor - -See the schematic below to wire up the two sensors. We will use these two functions to read values from the sensors: - -```arduino -float get_temperature() { - int reading = analogRead(A1); - float voltage = reading * 3.3; - voltage /= 1024.0; - // Print tempeature 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; -} -int get_light() { - int light_value = analogRead(A0); - return light_value; -} -``` - -Note that you can use the Fahrenheit units by returning `temperatureF` instead of `temperatureC` - -![Complete Circuit](assets/layouat_complete_mRWD8rFHqj.png) - -## Complete Sketch - - - - -### #ProTip: Plot Values Using ThingSpeak - -For all of you control freaks here is the instructions to plot all the data collected in a beautiful graph like this: - -![Temperature graph](assets/screen_shot_2017-11-27_at_21_13_39_TbarFrhjur.png) - - -We will use the ThingSpeak platform to plot out graphs, s follow these steps to get started. - -![Connect to ThingSpeak and create an account](assets/screen_shot_2017-11-27_at_21_04_41_tyEJH5iWxT.png) - - -![Create a new channel and fill in the names of the values you want to plot](assets/screen_shot_2017-11-27_at_21_07_10_foyha7p9zk_8jBf7oU9nk.png) - - -![Save the Channel ID and the Read and Write keys](assets/screen_lgwckabe1j_fTFMNfMckG.png) - - -Download the [ThingSpeak](https://github.com/mathworks/thingspeak-arduino) library and let's get started. This sketch below will upload sensors values to the cloud every minute, just fill in you WiFi credentials and the API keys of you channel and upload. - -```arduino -#include -#include -#include "ThingSpeak.h" -const char* ssid = SECRET_SSID; // your network SSID (name) -const char* password = SECRET_PSWD; // your network password -WiFiClient ThingSpeakClient; -unsigned long myChannelNumber = 356392; -const char * myWriteAPIKey = SECRET_WRITE_API; -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; -void setup() { - Serial.begin(9600); - while (!Serial); - delay(2000); - Serial.print("Connecting Wifi: "); - Serial.println(ssid); - while (WiFi.begin(ssid, password) != WL_CONNECTED) { - Serial.print("."); - delay(500); - } - Serial.println(""); - Serial.println("WiFi connected"); - ThingSpeak.begin(ThingSpeakClient); -} -void loop() { - ThingSpeak.setField(1, get_light()); - ThingSpeak.setField(2, get_temperature()); - ThingSpeak.setField(3, get_average_moisture()); - ThingSpeak.writeFields(myChannelNumber, myWriteAPIKey); - Serial.println("message sent to cloud"); - delay(60000); // send values every 1 minute -} -float get_temperature() { - int reading = analogRead(tempPin); - float voltage = reading * 3.3; - voltage /= 1024.0; - // Print tempeature 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; -} -int get_average_moisture() { // make an average of 10 values to be more accurate - int tempValue = 0; // variable to temporarily store moisture value - for (int a = 0; a < 10; a++) { - tempValue += analogRead(moisturePin); - delay(10); - } - return tempValue / 10; -} -int get_light() { - int light_value = analogRead(A0); - return light_value; -} -``` - -In the *complete Pro sketch below* you can see how to attach this upload to an RTC alarm that gets triggered every minute. - -Unfortunately Gmail doesn't let us embed **graphs** and **iframes** in the body of the email, but we can send the link via email in a beautiful button, see the tip below. - -We chose ThingSpeak, but there are tons of alternatives out there! Take a look a [Dweet.io](http://dweet.io/) and [freeboard.io](http://freeboard.io/) for instance. - -### #ProTip: Style Your Email - -Zapier allow us to **embed some html and css code in the body** of the email. We can use that to send pretty stylised email like this: - -![Stylized email body](assets/mail_84XpcdsaVR.png) - - -To achieve this result just change **the body type to html** on the Zapier interface and add your custom HTML and CSS. - -![To get a fancy looking email paste the hTML code below and also change the Body Type to Html](assets/zapier_html_1_YEi9NUpiUC.png) - - - -![Edit the four query strings clicking on them and selecting the right one from the list that appears](assets/zapier_html_2_Imnnsi71FO.png) - - - -**Copy and paste this template:** - -```html - - - - - - - -
-

HELLO !

-

Here's your daily update about your garden ☘

-
♨ Temperature: {{querystring__temperature}} C
-
☔ Moisture: {{_querystring__moisture}}
-
☀ Light: {{querystring__light}}
-
{{querystring__warning}}
- -
SEE THE GRAPH
-
-
- - -``` - -### #ProTip: Test API with PostMan - -Working with HTTP request can be hard, luckily there are a lot of tools that can help us building the URL we need. Postman is a great example: - -![Postman.](assets/screen_shot_2017-11-27_at_22_03_05_dq7yRw9jUZ.png) - -Just paste the initial URL given by Zapier, add parameters and send it. It will print out the response from the server and compose the URL for you. \ No newline at end of file diff --git a/content/tutorials/projects/plant-communicator/assets/garden-cover_ms4x6BGsMA.png b/content/tutorials/projects/plant-communicator/assets/garden-cover_ms4x6BGsMA.png deleted file mode 100644 index 905e425a7d..0000000000 Binary files a/content/tutorials/projects/plant-communicator/assets/garden-cover_ms4x6BGsMA.png and /dev/null differ diff --git a/content/tutorials/projects/plant-communicator/assets/gardenmonitor_Mqqe6fUoSN.png b/content/tutorials/projects/plant-communicator/assets/gardenmonitor_Mqqe6fUoSN.png deleted file mode 100644 index e8a34ef20b..0000000000 Binary files a/content/tutorials/projects/plant-communicator/assets/gardenmonitor_Mqqe6fUoSN.png and /dev/null differ diff --git a/content/tutorials/projects/plant-communicator/assets/mail_84XpcdsaVR.png b/content/tutorials/projects/plant-communicator/assets/mail_84XpcdsaVR.png deleted file mode 100644 index 705d1633a7..0000000000 Binary files a/content/tutorials/projects/plant-communicator/assets/mail_84XpcdsaVR.png and /dev/null differ diff --git a/content/tutorials/projects/plant-communicator/assets/screen_lgwcKABE1j.png b/content/tutorials/projects/plant-communicator/assets/screen_lgwcKABE1j.png deleted file mode 100644 index 65fae06aad..0000000000 Binary files a/content/tutorials/projects/plant-communicator/assets/screen_lgwcKABE1j.png and /dev/null differ diff --git a/content/tutorials/projects/plant-communicator/assets/screen_shot_2017-11-27_at_17_24_58_FkMkrog3li.png b/content/tutorials/projects/plant-communicator/assets/screen_shot_2017-11-27_at_17_24_58_FkMkrog3li.png deleted file mode 100644 index 0f096bcdf5..0000000000 Binary files a/content/tutorials/projects/plant-communicator/assets/screen_shot_2017-11-27_at_17_24_58_FkMkrog3li.png and /dev/null differ diff --git a/content/tutorials/projects/plant-communicator/assets/screen_shot_2017-11-27_at_17_25_01_ObCjpnEni8.png b/content/tutorials/projects/plant-communicator/assets/screen_shot_2017-11-27_at_17_25_01_ObCjpnEni8.png deleted file mode 100644 index 74f88da39f..0000000000 Binary files a/content/tutorials/projects/plant-communicator/assets/screen_shot_2017-11-27_at_17_25_01_ObCjpnEni8.png and /dev/null differ diff --git a/content/tutorials/projects/plant-communicator/assets/screen_shot_2017-11-27_at_17_25_26_2UcMrls6fx.png b/content/tutorials/projects/plant-communicator/assets/screen_shot_2017-11-27_at_17_25_26_2UcMrls6fx.png deleted file mode 100644 index d375ea4dd3..0000000000 Binary files a/content/tutorials/projects/plant-communicator/assets/screen_shot_2017-11-27_at_17_25_26_2UcMrls6fx.png and /dev/null differ diff --git a/content/tutorials/projects/plant-communicator/assets/screen_shot_2017-11-27_at_21_04_41_tyEJH5iWxT.png b/content/tutorials/projects/plant-communicator/assets/screen_shot_2017-11-27_at_21_04_41_tyEJH5iWxT.png deleted file mode 100644 index f038114ae6..0000000000 Binary files a/content/tutorials/projects/plant-communicator/assets/screen_shot_2017-11-27_at_21_04_41_tyEJH5iWxT.png and /dev/null differ diff --git a/content/tutorials/projects/plant-communicator/assets/screen_shot_2017-11-27_at_21_07_10_FOYhA7P9zK.png b/content/tutorials/projects/plant-communicator/assets/screen_shot_2017-11-27_at_21_07_10_FOYhA7P9zK.png deleted file mode 100644 index a764f16507..0000000000 Binary files a/content/tutorials/projects/plant-communicator/assets/screen_shot_2017-11-27_at_21_07_10_FOYhA7P9zK.png and /dev/null differ diff --git a/content/tutorials/projects/plant-communicator/assets/screen_shot_2017-11-27_at_21_13_39_TbarFrhjur.png b/content/tutorials/projects/plant-communicator/assets/screen_shot_2017-11-27_at_21_13_39_TbarFrhjur.png deleted file mode 100644 index 6c383d30ba..0000000000 Binary files a/content/tutorials/projects/plant-communicator/assets/screen_shot_2017-11-27_at_21_13_39_TbarFrhjur.png and /dev/null differ diff --git a/content/tutorials/projects/plant-communicator/assets/screen_shot_2017-11-27_at_22_03_05_dq7yRw9jUZ.png b/content/tutorials/projects/plant-communicator/assets/screen_shot_2017-11-27_at_22_03_05_dq7yRw9jUZ.png deleted file mode 100644 index 7f30a82b43..0000000000 Binary files a/content/tutorials/projects/plant-communicator/assets/screen_shot_2017-11-27_at_22_03_05_dq7yRw9jUZ.png and /dev/null differ diff --git a/content/tutorials/projects/plant-communicator/assets/soil_bxflVXhezy.png b/content/tutorials/projects/plant-communicator/assets/soil_bxflVXhezy.png deleted file mode 100644 index 78f87adc8a..0000000000 Binary files a/content/tutorials/projects/plant-communicator/assets/soil_bxflVXhezy.png and /dev/null differ diff --git a/content/tutorials/projects/plant-communicator/assets/zapier1_EbwvfZM7zt.png b/content/tutorials/projects/plant-communicator/assets/zapier1_EbwvfZM7zt.png deleted file mode 100644 index 263a576d69..0000000000 Binary files a/content/tutorials/projects/plant-communicator/assets/zapier1_EbwvfZM7zt.png and /dev/null differ diff --git a/content/tutorials/projects/plant-communicator/assets/zapier2_bXxylXyUZh.png b/content/tutorials/projects/plant-communicator/assets/zapier2_bXxylXyUZh.png deleted file mode 100644 index d976f5377c..0000000000 Binary files a/content/tutorials/projects/plant-communicator/assets/zapier2_bXxylXyUZh.png and /dev/null differ diff --git a/content/tutorials/projects/plant-communicator/assets/zapier3_yyONMbzUGx.png b/content/tutorials/projects/plant-communicator/assets/zapier3_yyONMbzUGx.png deleted file mode 100644 index cfd385c9a7..0000000000 Binary files a/content/tutorials/projects/plant-communicator/assets/zapier3_yyONMbzUGx.png and /dev/null differ diff --git a/content/tutorials/projects/plant-communicator/assets/zapier4_3NPnQlhj3b.png b/content/tutorials/projects/plant-communicator/assets/zapier4_3NPnQlhj3b.png deleted file mode 100644 index ff716d44c9..0000000000 Binary files a/content/tutorials/projects/plant-communicator/assets/zapier4_3NPnQlhj3b.png and /dev/null differ diff --git a/content/tutorials/projects/plant-communicator/assets/zapier5ok_CjPi08qKFG.png b/content/tutorials/projects/plant-communicator/assets/zapier5ok_CjPi08qKFG.png deleted file mode 100644 index 7c879216ae..0000000000 Binary files a/content/tutorials/projects/plant-communicator/assets/zapier5ok_CjPi08qKFG.png and /dev/null differ diff --git a/content/tutorials/projects/plant-communicator/assets/zapier_2_1_QOTJCKNm6N.png b/content/tutorials/projects/plant-communicator/assets/zapier_2_1_QOTJCKNm6N.png deleted file mode 100644 index 275715d129..0000000000 Binary files a/content/tutorials/projects/plant-communicator/assets/zapier_2_1_QOTJCKNm6N.png and /dev/null differ diff --git a/content/tutorials/projects/plant-communicator/assets/zapier_2_2_KLQOdpbOKz.png b/content/tutorials/projects/plant-communicator/assets/zapier_2_2_KLQOdpbOKz.png deleted file mode 100644 index 1e908544f5..0000000000 Binary files a/content/tutorials/projects/plant-communicator/assets/zapier_2_2_KLQOdpbOKz.png and /dev/null differ diff --git a/content/tutorials/projects/plant-communicator/assets/zapier_2_3_psTCPMTU12.png b/content/tutorials/projects/plant-communicator/assets/zapier_2_3_psTCPMTU12.png deleted file mode 100644 index 9f288f1379..0000000000 Binary files a/content/tutorials/projects/plant-communicator/assets/zapier_2_3_psTCPMTU12.png and /dev/null differ diff --git a/content/tutorials/projects/plant-communicator/assets/zapier_2_4_hKYhJ5caoM.png b/content/tutorials/projects/plant-communicator/assets/zapier_2_4_hKYhJ5caoM.png deleted file mode 100644 index d17b760a65..0000000000 Binary files a/content/tutorials/projects/plant-communicator/assets/zapier_2_4_hKYhJ5caoM.png and /dev/null differ diff --git a/content/tutorials/projects/plant-communicator/assets/zapier_2_5_JVSHQOm2ef.png b/content/tutorials/projects/plant-communicator/assets/zapier_2_5_JVSHQOm2ef.png deleted file mode 100644 index 3d65f230f6..0000000000 Binary files a/content/tutorials/projects/plant-communicator/assets/zapier_2_5_JVSHQOm2ef.png and /dev/null differ diff --git a/content/tutorials/projects/plant-communicator/assets/zapier_2_6_eZmBe7LTAT.png b/content/tutorials/projects/plant-communicator/assets/zapier_2_6_eZmBe7LTAT.png deleted file mode 100644 index f8f0ca6034..0000000000 Binary files a/content/tutorials/projects/plant-communicator/assets/zapier_2_6_eZmBe7LTAT.png and /dev/null differ diff --git a/content/tutorials/projects/plant-communicator/assets/zapier_2_7_9ptHyeBn9i.png b/content/tutorials/projects/plant-communicator/assets/zapier_2_7_9ptHyeBn9i.png deleted file mode 100644 index 0a6aab1c09..0000000000 Binary files a/content/tutorials/projects/plant-communicator/assets/zapier_2_7_9ptHyeBn9i.png and /dev/null differ diff --git a/content/tutorials/projects/plant-communicator/assets/zapier_2_8_pVg9EnAnNq.png b/content/tutorials/projects/plant-communicator/assets/zapier_2_8_pVg9EnAnNq.png deleted file mode 100644 index e586190cfc..0000000000 Binary files a/content/tutorials/projects/plant-communicator/assets/zapier_2_8_pVg9EnAnNq.png and /dev/null differ diff --git a/content/tutorials/projects/plant-communicator/assets/zapier_html_1_ws5TkJpfgD.png b/content/tutorials/projects/plant-communicator/assets/zapier_html_1_ws5TkJpfgD.png deleted file mode 100644 index e3e583521f..0000000000 Binary files a/content/tutorials/projects/plant-communicator/assets/zapier_html_1_ws5TkJpfgD.png and /dev/null differ diff --git a/content/tutorials/projects/plant-communicator/assets/zapier_html_2_xBV7qhNiAg.png b/content/tutorials/projects/plant-communicator/assets/zapier_html_2_xBV7qhNiAg.png deleted file mode 100644 index 10d27a44c1..0000000000 Binary files a/content/tutorials/projects/plant-communicator/assets/zapier_html_2_xBV7qhNiAg.png and /dev/null differ diff --git a/content/tutorials/projects/plant-communicator/assets/zapiertest_5z3q3AodIq.png b/content/tutorials/projects/plant-communicator/assets/zapiertest_5z3q3AodIq.png deleted file mode 100644 index 7ec7c417ec..0000000000 Binary files a/content/tutorials/projects/plant-communicator/assets/zapiertest_5z3q3AodIq.png and /dev/null differ diff --git a/content/tutorials/projects/plant-communicator/plant-communicator.md b/content/tutorials/projects/plant-communicator/plant-communicator.md deleted file mode 100644 index 8909d2f956..0000000000 --- a/content/tutorials/projects/plant-communicator/plant-communicator.md +++ /dev/null @@ -1,575 +0,0 @@ ---- -title: "Plant Communicator © CC BY-NC-SA" -description: "Ever wished you could talk with your plants?" -coverImage: "assets/garden-cover_ms4x6BGsMA.png" -tags: [internet of things, iot, monitoring] -author: "Arduino_Genuino" -difficulty: advanced -source: "https://create.arduino.cc/projecthub/arduino/plant-communicator-7ea06f" ---- - -## Components and Supplies - -- [Arduino MKR IoT Bundle](https://store.arduino.cc/usa/arduino-iot-mkr1000-bundle) - -## Apps and Online Services - -- [Zapier](https://zapier.com/) -- [ThingSpeak API](https://github.com/iobridge/ThingSpeak) - -## About This Project - -### Introduction - -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 your plants alive can be quite the challenge as they are very bad at communication. - -One way to keep them happy is to bring your plants with you, but maybe you don't want to lug around with that big-ole-cactus or fern sticking out of your 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 MKR IoT Bundle components to create a device that remotely surveys the well being of any plant instead. - -### In a nutshell: - -In this experiment you will learn how to protect your plants and make sure they survive as well as using Arduino magic. - -By monitoring moisture, temperature and light, you can make sure that your plants are happy. It can send emails and graphs on a daily basis and notify you of its needs. - -### Components - -* TMP36 temperature sensor -* Phototransistor -* DIY moisture sensor - -### Learning Goals - -* Introducing Zapier internet service -* Sending HTTP requests -* Managing Real Time Clock and alarms -* Building a DIY moisture sensor -* Plotting values with thingSpeak **#ProTips** -* Style your email with HTML and CSS **#ProTips** -* Test APIs with PostMan **#ProTips** - -### Want to Know More? - -This tutorial is part of a series of experiments that familiarise you with the MKR1000 and IoT. All experiments can be built using the components contained in the MKR IoT Bundle. - -* [Love You Pillow](https://create.arduino.cc/projecthub/arduino/love-you-pillow-f08931) -* [Puzzle Box](https://create.arduino.cc/projecthub/arduino/puzzlebox-c1f374) -* [Pavlov's Cat](https://create.arduino.cc/projecthub/arduino/pavlov-s-cat-7e6577) -* [The Nerd](https://create.arduino.cc/projecthub/arduino/the-nerd-0144f9) -* Plant Communicator - -### Set up Zapier - -[Zapier](https://zapier.com/app/explore) is an online automation tool that can easily manage the APIs of other apps for us. It is a great tool to combine multiple tasks or if the app we want to use has complex API that cannot be managed by an Arduino. - -In our case we will use it to send an email with the data retrieved from the Arduino. - -Follow this few simple steps to create your own zap! - -![Create an account in Zapier and log in, then Make a new Zap](assets/zapier1_EbwvfZM7zt.png) - - - -![Search for Webhooks by Zapier and then select Catch Hook](assets/zapier2_bXxylXyUZh.png) - - - -![Start customising your hook adding the parameters we will send from Arduino ](assets/zapier3_yyONMbzUGx.png) - - - -![Select and copy the Custom Webhook URL](assets/zapier4_3NPnQlhj3b.png) - - -In order to proceed we need to test our hook first copying the given URL, then selecting the Test and Review button that appears when you press Continue. Add these parameters to the URL: - -`custom_webhook_URL?temperature=0&moisture=0&light=0&warning=0 ` - -Now just copy and paste this URL on a new browser page. - -You should see a response like this: - -![Pasting the URL formed with our additional parameters into a web browser, we should see this page](assets/zapiertest_5z3q3AodIq.png) - - - -![Zapier confirms everything went fine with our request](assets/zapier5ok_CjPi08qKFG.png) - - -Congratulations! You just sent an **http request!** - -**This is exactly the what we will do with our Arduino board.** But instead of pasting that URL into a browser page we will send it directly to the Zapier server. Also we will modify the values of the parameters that are now set to zero with our sensors values. - -*For a more advanced way to test and work with API have a look at the **#ProTip** at the bottom of the page. - -After you tested your request you can proceed creating the Zap. - -Proceed in the Edit with the **Do This...** - -![We create the Zap selecting Gmail from the available apps](assets/zapier_2_1_QOTJCKNm6N.png) - - - -![We want to send an email as action triggered by the webhook](assets/zapier_2_2_KLQOdpbOKz.png) - - - -![When the action is selected, we can continue](assets/zapier_2_3_psTCPMTU12.png) - - - -![We start filling up the various fields. The first is the Gmail sender account](assets/zapier_2_4_hKYhJ5caoM.png) - - - -![Following the authorisation step with Google, we go ahead with the recipient email address ](assets/zapier_2_5_JVSHQOm2ef.png) - - - -![If we chose plain text for the body type, we can add the text as shown here.](assets/zapier_2_6_eZmBe7LTAT.png) - -To access the catch hook strings, we need to click on the con on the top right of the input field that opens up the dropdown as shown in this picture. - -![Check that all the required fields are filled up and also that the Body is like the one shown](assets/zapier_2_7_9ptHyeBn9i.png) - - - -![As soon as you finish the edit, you can proceed with the test, that will end with this page](assets/zapier_2_8_pVg9EnAnNq.png) - - -Check your mailbox to see the generated email from Zapier. It will be from the account you used in the first step of gmail configuration. - -### Set up the Board - -In order to implement all the functionalities we are going to use the following libraries: - -* WiFi101 // to connect to internet and scan the networks -* RTCZero // to manage time triggered events - -You can download them from the library manager as explained in [this guide.](https://www.arduino.cc/en/Guide/Libraries) - -In order to use Zapier's API we first need to **upload the certificates** on the MKR1000. **This applies to most of online services and APIs!** - -Upload the Firmware Updater example from the WiFi101 library and add **hooks.zapier.com** to the domains. - -```arduino -> examples > WiFi101 > FirmwareUpdater -``` - -**If you are using the Arduino Web Editor this feature is not yet implemented and you need to do this through the** **[Arduino Desktop Application.](https://www.arduino.cc/en/Main/Software)** - -![Upload FirmwareUpdater example](assets/screen_shot_2017-11-27_at_17_24_58_FkMkrog3li.png) - - - -![Select WiFi101 Firmware Updater from the Tool dropdown menu](assets/screen_shot_2017-11-27_at_17_25_01_ObCjpnEni8.png) - - - -![Add hooks.zapier.com to the domains and upload certificates](assets/screen_shot_2017-11-27_at_17_25_26_2UcMrls6fx.png) - - -### Sending HTTP Request - -We are now ready to send the HTTP request from the Arduino board. - -For now we will set an arbitrary value to our parameter that later on will be substituted with real sensor values. - -```arduino - float temperature = 22; - int moisture = 150; - int light = 40; - String warning = "This is a warning message"; - warning.replace(" ", "%20"); -``` - -Note that **the string has to be encoded**, since blank spaces cannot be sent in an HTTP request. All blank spaces are substituted with the encoded equivalent *`%20`* - -After setting up our parameters we will call the `send_email()` function, which will convert all of them into Strings and **will rebuild the same URL that we used before** to then post it to the Zapier server. - -**Fill in this sketch with your WiFi credential and the piece of URL that you received from Zapier and upload.** - -```arduino -#include -#include -const char* ssid = SECRET_SSID; // your network SSID (name) -const char* password = SECRET_PSWD; // your network password -String httpsRequest = SECRET_REQUEST; // your Zapier URL -const char* host = "hooks.zapier.com"; -WiFiSSLClient client; -void setup() { - Serial.begin(9600); - while (!Serial); - delay(2000); - Serial.print("Connecting Wifi: "); - Serial.println(ssid); - while (WiFi.begin(ssid, password) != WL_CONNECTED) { - Serial.print("."); - delay(500); - } - Serial.println(""); - Serial.println("WiFi connected"); -} -void loop() { - float temperature = 22; - int moisture = 150; - int light = 40; - String warning = "This is a warning message"; - warning.replace(" ", "%20"); - send_email(temperature, moistue, light, warning ); - delay(20000) -} -void send_email(float temperature, int moisture, int light, String warning) { - // convert values to String - String _temperature = String(temperature); - String _moisture = String(moisture); - String _light = String(light); - String _warning = warning; - if (client.connect(host, 443)) { - client.println("POST " + httpsRequest + "?temperature=" + _temperature + "&moisture=" + _moisture + "&light=" + _light + "&warning=" + _warning + " HTTP/1.1"); - client.println("Host: " + String(host)); - client.println("Connection: close"); - client.println(); - delay(1000); - while (client.available()) { // Print on the console the answer of the server - char c = client.read(); - Serial.write(c); - } - client.stop(); // Disconnect from the server - } - else { - Serial.println("Failed to connect to client"); - } -} -``` - -It will send an email to the address you choose every 20 seconds. - -**Be careful with the requests, Zapier allow you only 100 free request per month.** - -### RTC and Alarms - -We can use the Real Time clock of the MKR1000 to send an email every day at a certain hour. - -This sketch will set the time and date at 16:00 of December 4th 2017 **and then trigger an alarm every day at 16:01.** - -Note that since the alarm is attached to an *interrupt* function **we cannot include any delays**, but we can use boolean variable to trigger actions in the `loop()` - -```arduino -#include -RTCZero rtc; // create RTC object -/* Change these values to set the current initial time */ -const byte seconds = 0; -const byte minutes = 0; -const byte hours = 16; -/* Change these values to set the current initial date */ -const byte day = 4; -const byte month = 12; -const byte year = 17; -bool email_already_sent = false; -void setup() { - Serial.begin(9600); - while (!Serial); - delay(2000); - rtc.begin(); // initialize RTC 24H format - rtc.setTime(hours, minutes, seconds); - rtc.setDate(day, month, year); - rtc.setAlarmTime(16, 1, 0); // Set the time for the Arduino to send the email - rtc.enableAlarm(rtc.MATCH_HHMMSS); - rtc.attachInterrupt(alarmMatch); -} -void loop() { - if (!email_already_sent) { - // send_email(); - email_already_sent = true; - } -} -void alarmMatch() { // triggered when the alarm goes on - Serial.println("Alarm Match!"); - email_already_sent = false; -} -``` - -### DIY Soil Moisture Sensor - -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.** - -Using the **1 Mega Ohm resistor** and two wires, we can create our DIY soil moisture sensor! - -![Soil moisture sensor wiring.](assets/soil_bxflVXhezy.png) - - -Uploading the following sketch you can start reading the values of the sensor, we suggest you **start testing it first in a dry soil** and and note down the value you read. - -**That value will be used to set a threshold** so that the Arduino will know when your plants need water and send you an **emergency email.** - -```arduino -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 soil -int threeshold = 800; -void setup() { - Serial.begin(9600); - while (!Serial); - delay(2000); -} -void loop() { - Serial.println(get_average_moisture()); - delay(5000); -} -int get_average_moisture() { // make an average of 10 values to be more accurate - int tempValue = 0; // variable to temporarily store moisture value - for (int a = 0; a < 10; a++) { - tempValue += analogRead(moisturePin); - delay(100); - } - return tempValue / 10; -} -``` - -### Add Temperature and Light Sensor - -See the schematic below to wire up the two sensors. We will use these two functions to read values from the sensors: - -```arduino -float get_temperature(){ - int reading = analogRead(A1); - float voltage = reading * 3.3; - voltage /= 1024.0; -// Print tempeature 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; -} -int get_light(){ - int light_value=analogRead(A0); - return light_value; -} -``` - -Note that you can use the Fahrenheit units by returning `temperatureF` instead of `temperatureC` - -![Complete circuit.](assets/gardenmonitor_Mqqe6fUoSN.png) - -## Complete Sketch - - - - -### #ProTip: Plot Values Using ThingSpeak - -For all of you control freaks, here is the instructions to plot all the data collected in a beautiful graph like this: - -![Temperature graph](assets/screen_shot_2017-11-27_at_21_13_39_TbarFrhjur.png) - - - -We will use the [ThingSpeak](https://thingspeak.com/) platform to plot out graphs, follow these steps to get started. - -![Connect to ThingSpeak and create an account.](assets/screen_shot_2017-11-27_at_21_04_41_tyEJH5iWxT.png) - - - -![Create a new channel and fill in the name of the values you want to plot.](assets/screen_shot_2017-11-27_at_21_07_10_FOYhA7P9zK.png) - - - -![Save the channel ID and the Write and Read keys.](assets/screen_lgwcKABE1j.png) - - - -Download the [ThingSpeak](https://github.com/mathworks/thingspeak-arduino) library and let's get started. This sketch below will upload sensors values to the cloud every minute, just fill in you WiFi credentials and the API keys of you channel and upload. - -```arduino -#include -#include -#include "ThingSpeak.h" -const char* ssid = SECRET_SSID; // your network SSID (name) -const char* password = SECRET_PSWD; // your network password -WiFiClient ThingSpeakClient; -unsigned long myChannelNumber = 356392; -const char * myWriteAPIKey = SECRET_WRITE_API; -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; -void setup() { - Serial.begin(9600); - while (!Serial); - delay(2000); - Serial.print("Connecting Wifi: "); - Serial.println(ssid); - while (WiFi.begin(ssid, password) != WL_CONNECTED) { - Serial.print("."); - delay(500); - } - Serial.println(""); - Serial.println("WiFi connected"); - ThingSpeak.begin(ThingSpeakClient); -} -void loop() { - ThingSpeak.setField(1, get_light()); - ThingSpeak.setField(2, get_temperature()); - ThingSpeak.setField(3, get_average_moisture()); - ThingSpeak.writeFields(myChannelNumber, myWriteAPIKey); - Serial.println("message sent to cloud"); - delay(60000); // send values every 1 minute -} -float get_temperature() { - int reading = analogRead(tempPin); - float voltage = reading * 3.3; - voltage /= 1024.0; - // Print tempeature 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; -} -int get_average_moisture() { // make an average of 10 values to be more accurate - int tempValue = 0; // variable to temporarily store moisture value - for (int a = 0; a < 10; a++) { - tempValue += analogRead(moisturePin); - delay(10); - } - return tempValue / 10; -} -int get_light() { - int light_value = analogRead(A0); - return light_value; -} -``` - -In the *complete Pro sketch below* you can see how to attach this upload to an RTC alarm that gets triggered every minute. - -Unfortunately Gmail doesn't let us embed **graphs** and **iframes** in the body of the email, but we can send the link via email in a beautiful button, see the tip below. - -We chose ThingSpeak, but there are tons of alternatives out there! Take a look a [Dweet.io](http://dweet.io/) and [freeboard.io](http://freeboard.io/) for instance. - - - - -### #ProTip: Style Your Email - -Zapier allow us to **embed some html and css code in the body** of the email. We can use that to send pretty stylised email like this: - -![Stylised email's body](assets/mail_84XpcdsaVR.png) - - -To achieve this result just change **the body type to html** on the Zapier interface and add your custom HTML and CSS. - -![To get a fancy looking email paste the HTML code below and also change body type to HTML](assets/zapier_html_1_ws5TkJpfgD.png) - - -![Edit the four query strings clicking on them and selecting the right one from the list that appears](assets/zapier_html_2_xBV7qhNiAg.png) - - - -**Copy and paste this template:** - -```html - - - - - - - -
-

HELLO !

-

Here's your daily update about your garden ☘

-
♨ Temperature: {{querystring__temperature}} C
-
☔ Moisture: {{_querystring__moisture}}
-
☀ Light: {{querystring__light}}
-
{{querystring__warning}}
- -
SEE THE GRAPH
-
-
- - -``` - -## #ProTip: Test API with PostMan - -Working with HTTP request can be hard, luckily there are a lot of tools that can help us building the URL we need. - -[Postman](https://www.getpostman.com/) is a great example: - -![Postman.](assets/screen_shot_2017-11-27_at_22_03_05_dq7yRw9jUZ.png) - -Just paste the initial URL given by Zapier, add parameters and send it. It will print out the response from the server and compose the URL for you. - - -### Complete ProTip Sketch - - diff --git a/content/tutorials/projects/puzzlebox-with-mkr-wifi-1010/assets/blob_4avNRfZk59.png b/content/tutorials/projects/puzzlebox-with-mkr-wifi-1010/assets/blob_4avNRfZk59.png deleted file mode 100644 index 474b37aec0..0000000000 Binary files a/content/tutorials/projects/puzzlebox-with-mkr-wifi-1010/assets/blob_4avNRfZk59.png and /dev/null differ diff --git a/content/tutorials/projects/puzzlebox-with-mkr-wifi-1010/assets/blynk_5_gNFkiBCYlv.png b/content/tutorials/projects/puzzlebox-with-mkr-wifi-1010/assets/blynk_5_gNFkiBCYlv.png deleted file mode 100644 index 190e26af5c..0000000000 Binary files a/content/tutorials/projects/puzzlebox-with-mkr-wifi-1010/assets/blynk_5_gNFkiBCYlv.png and /dev/null differ diff --git a/content/tutorials/projects/puzzlebox-with-mkr-wifi-1010/assets/gif-box_Wdk5vQ4rJT.gif b/content/tutorials/projects/puzzlebox-with-mkr-wifi-1010/assets/gif-box_Wdk5vQ4rJT.gif deleted file mode 100644 index eb89f26d2d..0000000000 Binary files a/content/tutorials/projects/puzzlebox-with-mkr-wifi-1010/assets/gif-box_Wdk5vQ4rJT.gif and /dev/null differ diff --git a/content/tutorials/projects/puzzlebox-with-mkr-wifi-1010/assets/layout_bepper_bb_sJTsqIGHTz.png b/content/tutorials/projects/puzzlebox-with-mkr-wifi-1010/assets/layout_bepper_bb_sJTsqIGHTz.png deleted file mode 100644 index 908dd089c3..0000000000 Binary files a/content/tutorials/projects/puzzlebox-with-mkr-wifi-1010/assets/layout_bepper_bb_sJTsqIGHTz.png and /dev/null differ diff --git a/content/tutorials/projects/puzzlebox-with-mkr-wifi-1010/assets/layout_monitor_bb_ogGfttXnUX.png b/content/tutorials/projects/puzzlebox-with-mkr-wifi-1010/assets/layout_monitor_bb_ogGfttXnUX.png deleted file mode 100644 index 5f3c0adc54..0000000000 Binary files a/content/tutorials/projects/puzzlebox-with-mkr-wifi-1010/assets/layout_monitor_bb_ogGfttXnUX.png and /dev/null differ diff --git a/content/tutorials/projects/puzzlebox-with-mkr-wifi-1010/assets/layout_motor_bb_bCPITLm4ud.png b/content/tutorials/projects/puzzlebox-with-mkr-wifi-1010/assets/layout_motor_bb_bCPITLm4ud.png deleted file mode 100644 index 2dd76ee24b..0000000000 Binary files a/content/tutorials/projects/puzzlebox-with-mkr-wifi-1010/assets/layout_motor_bb_bCPITLm4ud.png and /dev/null differ diff --git a/content/tutorials/projects/puzzlebox-with-mkr-wifi-1010/assets/layout_trimmer_bb_UPgHIciUTk.png b/content/tutorials/projects/puzzlebox-with-mkr-wifi-1010/assets/layout_trimmer_bb_UPgHIciUTk.png deleted file mode 100644 index 2748d8c35e..0000000000 Binary files a/content/tutorials/projects/puzzlebox-with-mkr-wifi-1010/assets/layout_trimmer_bb_UPgHIciUTk.png and /dev/null differ diff --git a/content/tutorials/projects/puzzlebox-with-mkr-wifi-1010/assets/qr_puzzle_box_nNhmfBdADE.jpg b/content/tutorials/projects/puzzlebox-with-mkr-wifi-1010/assets/qr_puzzle_box_nNhmfBdADE.jpg deleted file mode 100644 index 3e3e798feb..0000000000 Binary files a/content/tutorials/projects/puzzlebox-with-mkr-wifi-1010/assets/qr_puzzle_box_nNhmfBdADE.jpg and /dev/null differ diff --git a/content/tutorials/projects/puzzlebox-with-mkr-wifi-1010/assets/rgb_caoc21qy77_5TJdvy376M.jpg b/content/tutorials/projects/puzzlebox-with-mkr-wifi-1010/assets/rgb_caoc21qy77_5TJdvy376M.jpg deleted file mode 100644 index 8dd663badc..0000000000 Binary files a/content/tutorials/projects/puzzlebox-with-mkr-wifi-1010/assets/rgb_caoc21qy77_5TJdvy376M.jpg and /dev/null differ diff --git a/content/tutorials/projects/puzzlebox-with-mkr-wifi-1010/assets/rgbled_s82wJXGcnF.png b/content/tutorials/projects/puzzlebox-with-mkr-wifi-1010/assets/rgbled_s82wJXGcnF.png deleted file mode 100644 index 5fb2300b84..0000000000 Binary files a/content/tutorials/projects/puzzlebox-with-mkr-wifi-1010/assets/rgbled_s82wJXGcnF.png and /dev/null differ diff --git a/content/tutorials/projects/puzzlebox-with-mkr-wifi-1010/assets/screen_shot_2017-11-26_at_13_41_19_TmeYuaaIBs.png b/content/tutorials/projects/puzzlebox-with-mkr-wifi-1010/assets/screen_shot_2017-11-26_at_13_41_19_TmeYuaaIBs.png deleted file mode 100644 index 0227f96565..0000000000 Binary files a/content/tutorials/projects/puzzlebox-with-mkr-wifi-1010/assets/screen_shot_2017-11-26_at_13_41_19_TmeYuaaIBs.png and /dev/null differ diff --git a/content/tutorials/projects/puzzlebox-with-mkr-wifi-1010/puzzlebox-with-mkr-wifi-1010.md b/content/tutorials/projects/puzzlebox-with-mkr-wifi-1010/puzzlebox-with-mkr-wifi-1010.md deleted file mode 100644 index 835a3d8217..0000000000 --- a/content/tutorials/projects/puzzlebox-with-mkr-wifi-1010/puzzlebox-with-mkr-wifi-1010.md +++ /dev/null @@ -1,501 +0,0 @@ ---- -title: "PuzzleBox with MKR WiFi 1010 © CC BY-NC" -description: "Protect your valuables with a puzzle!" -coverImage: "assets/blob_4avNRfZk59.png" -tags: [internet of things] -author: "Arduino_Genuino" -source: "https://create.arduino.cc/projecthub/Arduino_Genuino/puzzlebox-with-mkr-wifi-1010-7a39c4" ---- - -## Components and Supplies - -- [Arduino MKR IoT Bundle 1010](https://store.arduino.cc/arduino-iot-mkr-wifi-1010-bundle) - -## Apps and Online Services - -- [Blynk](https://www.blynk.cc/getting-started) - -## About This Project - -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 puzzlebox using the components from the MKR 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 you 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 online app [Blynk](http://www.blynk.cc/). An LED will help you guess, giving you colour feedbacks: the closer you are the warmer the colour. When the right combination is guessed the buzzer will start playing a song while the servo will open the box. In order to create our puzzle box we will need the following components: - -* Buzzer -* RGB LED -* 3 potentiometers -* LCD screen -* Servo motor - -![The puzzlebox.](assets/gif-box_Wdk5vQ4rJT.gif) - -### Learning Goals - -* Introducing Blynk internet platform -* Wiring and using the LCD screen -* Playing Star Wars theme with the buzzer - -### Want to Know More? - -This tutorial is part of a series of experiments that familiarise you with the MKR WiFi 1010 and IoT. All experiments can be built using the components contained in the MKR IoT Bundle. - -* [I Love You Pillow with MKR WiFi 1010](https://create.arduino.cc/projecthub/Arduino_Genuino/i-love-your-pillow-with-mkr-wifi-1010-84b6da) -* Puzzle Box with MKR WiFi 1010 -* [Pavlov's Cat with MKR WiFi 1010](https://create.arduino.cc/projecthub/Arduino_Genuino/pavlov-s-cat-with-mkr-wifi-1010-9ea418) -* [The Nerd with MKR WiFi 1010](https://create.arduino.cc/projecthub/Arduino_Genuino/the-nerd-with-mkr-wifi-1010-462cc5) -* [Plant communicator with MKR WiFi 1010](https://create.arduino.cc/projecthub/Arduino_Genuino/plant-communicator-with-mkr-wifi-1010-efc920) - -### Introducing Blynk - -[Blynk ](http://www.blynk.cc/)is a popular mobile app for Internet of Things, it allows us to easily control our internet connected Arduino from everywhere, anytime.It was founded on Kickstarter and quickly became one of the most used apps in this field, thanks to both its awesome documentation and its simplicity. - -### Getting Started with Blynk - -Creating a new project is really easy; to save your time and ease your first contact with Blynk, we have prepared the QR code below. Open Blynk and use the QR code icon that is on the top right of the interface. Automatically you will see the widgets we have prepared as a Project - -![Download Blynk from the Appstore or Google Play.](assets/blynk_5_gNFkiBCYlv.png) - -![Scan this QR with the Blynk app on your smartphone](assets/qr_puzzle_box_nNhmfBdADE.jpg) - - -After you successfully created the new project you should create and send to yourself via mail the **Auth Token.** It is a unique identifier which is needed to connect your hardware to your smartphone. Every new project you create will have its own Auth Token. In order to connect the Arduino to the app we will need to install the Blynk library. If you are using the Arduino Web Editor the library will be automatically downloaded when you include it in the sketch, otherwise you can download that from the library manager.Now we are ready to go. **Upload this sketch** and play with the sliders to see the result: - -```arduino -#include -#include -const char* ssid = SECRET_SSID; // your network SSID (name) -const char* password = SECRET_PSWD; // your network password -char auth[] = SECRET_TOKEN; // your Blynk API token -// Variables to store the combination value -// Set the initial combination to ( 1 1 1 ) -int SliderValueOne = 1; -int SliderValueTwo = 1; -int SliderValueThree = 1; -// Blynk functions to retrieve values -BLYNK_WRITE(V1) { - SliderValueOne = param.asInt(); // assigning incoming value from pin V1 to a variable - } - BLYNK_WRITE(V2) { - SliderValueTwo = param.asInt(); // assigning incoming value from pin V1 to a variable - } BLYNK_WRITE(V3) { - SliderValueThree = param.asInt(); // assigning incoming value from pin V1 to a variable - } -void setup() { - Serial.begin(9600); - Blynk.begin(auth, ssid, password); // start Blynk functionalities and connect to WiFi -} -void loop() { - // Variambles to temporarily store the combination - int Temp_Slider_One_value = SliderValueOne; - int Temp_Slider_Two_value = SliderValueTwo; - int Temp_Slider_Three_value = SliderValueThree; - Blynk.run(); - // poll new combination values from the online app - // check if combination values are changed and print them on the console - if(Temp_Slider_One_value != SliderValueOne || Temp_Slider_Two_value != SliderValueTwo || Temp_Slider_Three_value != SliderValueThree){ - Serial.print("New combination: "); - Serial.print(SliderValueOne); - Serial.print(" "); - Serial.print(SliderValueTwo); - Serial.print(" "); - Serial.println(SliderValueThree); - } - } -``` - -![Upload the sketch and open the serial monitor.](assets/screen_shot_2017-11-26_at_13_41_19_TmeYuaaIBs.png) - -### Using the LCD Screen - -Time to connect the screen! The LCD screen is easy to use but requires a lot of wires, so be ready to test your patience. - -![LCD Wiring](assets/layout_monitor_bb_ogGfttXnUX.png) - - - -Note that we are using the 5V power supply and a 220 Ohm resistor.The brightness can be regulated changing the output value of the Analog pin 3 from 0 to 255 with 0 being the maximum value. - -```arduino -analogWrite(A3, 0); -``` - -Now we can upload the example sketch and see if everything is working fine. - -```arduino -// include the library code: -#include -// initialize the library by associating any needed LCD interface pin -// with the arduino pin number it is connected to -const int rs = 12, en = 11, d4 = 2, d5 = 3, d6 = 4, d7 = 5; -LiquidCrystal lcd(rs, en, d4, d5, d6, d7); -void setup() { - analogWrite(A3, 0); // 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() { - // set the cursor to column 0, line 1 - // (note: line 1 is the second row, since counting begins with 0): - lcd.setCursor(0, 1); - lcd.print(millis() / 1000); - } -``` - -### Add Potentiometers - -To read the value of the potentiometers we will only need an analogRead() on the correct pin. We are connecting them to Analog pin 0, 1, 2. - -![Potentiometer wiring](assets/layout_trimmer_bb_UPgHIciUTk.png) - -Potentiometer wiring - -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, - -```arduino - int PotOne = map(analogRead(A0), 0, 1023, 0, 9); -``` - -You can use this example code to print on the LCD screen the values of the potentiometers. - -```arduino -#include -// LCD screen pins -const int rs = 12, en = 11, -LiquidCrystal lcd(rs, en, d4, d5, d6, d7); -void setup() { - analogWrite(A3, 0); // set the brightness of the LCD screen to the maximum value - Serial.begin(9600); - lcd.begin(16, 2); // begin LCD screen with 16 columns and 2 rows - } -void loop() { - int PotOne = map(analogRead(A0), 0, 1023, 0, 9); - int PotTwo = map(analogRead(A1), 0, 1023, 0, 9); - int PotThree = map(analogRead(A2), 0, 1023, 0, 9); - lcd.setCursor(0, 0); - lcd.print(PotOne); - lcd.setCursor(2, 0); - lcd.print(PotTwo); - lcd.setCursor(4, 0); - lcd.print(PotThree); -The story -``` - -### Add the 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.png) - - - -![RGB LED wiring](assets/rgb_caoc21qy77_5TJdvy376M.jpg) - - - -You can use this example sketch to see the RGB in action! - -```arduino -// RGB LED pins -int redPin = 6; -int greenPin = 8; -int bluePin = 7; -void setup() { - pinMode(redPin, OUTPUT); - pinMode(greenPin, OUTPUT); - pinMode(bluePin, OUTPUT); - Serial.begin(9600); - } -void loop() { - setColor(0, 0, 255); // blue - delay(1000); - setColor(0, 255, 255); // aqua - delay(1000); - setColor(255, 255, 0); // yellow - delay(1000); - setColor(255, 0, 0); // Red - delay(1000); - } -// Send RGB values to the LED pins -void setColor(int red, int green, int blue){ - analogWrite(redPin, red); - analogWrite(greenPin, green); - analogWrite(bluePin, blue); -} -``` - -### Connect It to Blynk - -Now we are ready to put things together: connect the board to Blynk, the potentiometer to the LCD screen and make the LED blink green when the combination is correct. - -* Note that we will use the function `giveColorFeedback()` to set the colour of the LED when the absolute value of each potentiometer is closer than a certain threshold to the correct combination. - -```arduino -void giveColorFeedback(int PotOne, int PotTwo, int PotThree){...} -``` - -* We will also use these variable to store the values sent from the app and therefore the combination. - -```arduino -int SliderValueOne = 1; -int SliderValueTwo = 1; -int SliderValueThree = 1; -``` - -Note that the initial value is set to 1, it will change only if you modify the values of the sliders on the app. **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 to see it in action: - -```arduino -#include -#include -#include -#include -// RGB LED pins -int redPin = 6; -int greenPin = 8; -int bluePin = 7; -const char* ssid = SECRET_SSID; // your network SSID (name) -const char* password = SECRET_PSWD; // your network password -char auth[] = SECRET_TOKEN; // your Blynk API token -// LCD screen pins -const int rs = 12, - en = 11, - d4 = 2, - d5 = 3, - d6 = 4, - d7 = 5; -bool start = true; -// Variables to store the combination value -// Set the initial combination to ( 1 1 1 ) -int SliderValueOne = 1; -int SliderValueTwo = 1; -int SliderValueThree = 1; -// Blynk functions to retrieve values -BLYNK_WRITE(V1) { - SliderValueOne = param.asInt(); // assigning incoming value from pin V1 to a variable -} -BLYNK_WRITE(V2) { - SliderValueTwo = param.asInt(); // assigning incoming value from pin V1 to a variable -} -BLYNK_WRITE(V3) { - SliderValueThree = param.asInt(); // assigning incoming value from pin V1 to a variable -} -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); - lcd.begin(16, 2); // begin LCD screen with 16 columns and 2 rows - Blynk.begin(auth, ssid, password); // start Blynk functionalities -} -void loop() { - // Variambles to temporarily store the combination - int Temp_Slider_One_value = SliderValueOne; - int Temp_Slider_Two_value = SliderValueTwo; - int Temp_Slider_Three_value = SliderValueThree; - Blynk.run(); // poll new combination values from the online app - // check if combination values are changed and print them on the console - if (Temp_Slider_One_value != SliderValueOne || Temp_Slider_Two_value != SliderValueTwo || Temp_Slider_Three_value != SliderValueThree) { - Serial.print("New combination: "); - Serial.print(SliderValueOne); - Serial.print(" "); - Serial.print(SliderValueTwo); - Serial.print(" "); - Serial.println(SliderValueThree); - } - int PotOne = map(analogRead(A0), 0, 1023, 0, 9); - int PotTwo = map(analogRead(A1), 0, 1023, 0, 9); - int PotThree = map(analogRead(A2), 0, 1023, 0, 9); - lcd.setCursor(0, 0); - lcd.print(PotOne); - lcd.setCursor(2, 0); - lcd.print(PotTwo); - lcd.setCursor(4, 0); - lcd.print(PotThree); - if (start) { - giveColorFeedback(PotOne, PotTwo, PotThree); - if (PotOne == SliderValueOne && PotTwo == SliderValueTwo && PotThree == SliderValueThree) { - blinkGreenLed(); - start = false; - } - } - if (!start) { - if (PotOne == 0 && PotTwo == 0 && PotThree == 0) { - start = true; - } - } -} -// 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 - SliderValueOne) <= 1 && abs(PotTwo - SliderValueTwo) <= 1 && abs(PotThree - SliderValueThree) <= 1 ) { - // Red - setColor(255, 0, 0); - } - else if (abs(PotOne - SliderValueOne) <= 3 && abs(PotTwo - SliderValueTwo) <= 3 && abs(PotThree - SliderValueThree) <= 3 ) { - // yellow - setColor(255, 255, 0); - } - else if (abs(PotOne - SliderValueOne) <= 4 && abs(PotTwo - SliderValueTwo) <= 4 && abs(PotThree - SliderValueThree) <= 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); - } -} -// Send RGB values to the LED pins -void setColor(int red, int green, int blue) { - analogWrite(redPin, red); - analogWrite(greenPin, green); - analogWrite(bluePin, blue); -} -``` - -### Add the Buzzer - -We will use the buzzer to play a melody when the box is opened. More precisely we will play the **Star Wars theme song!**Connecting the buzzer is simple: - -![Buzzer wiring](assets/layout_bepper_bb_sJTsqIGHTz.png) - - -Upload this example code and listen: - -```arduino -const int c = 261; -const int d = 294; -const int e = 329; -const int f = 349; -const int g = 391; -const int gS = 415; -const int a = 440; -const int aS = 455; -const int b = 466; -const int cH = 523; -const int cSH = 554; -const int dH = 587; -const int dSH = 622; -const int eH = 659; -const int fH = 698; -const int fSH = 740; -const int gH = 784; -const int gSH = 830; -const int aH = 880; -int counter = 0; -#define buzzerPin 1 -void setup() { - pinMode(buzzerPin, OUTPUT); - Serial.begin(9600); -} -void loop() { - play_jingle(); - delay(3000); -} -void play_jingle() -{ - beep(a, 500); - beep(a, 500); - beep(a, 500); - beep(f, 350); - beep(cH, 150); - beep(a, 500); - beep(f, 350); - beep(cH, 150); - beep(a, 650); - delay(500); - beep(eH, 500); - beep(eH, 500); - beep(eH, 500); - beep(fH, 350); - beep(cH, 150); - beep(gS, 500); - beep(f, 350); - beep(cH, 150); - beep(a, 650); - delay(500); -} -void beep(int note, int duration) -{ - //Play tone on buzzerPin - tone(buzzerPin, note, duration); - //Stop tone on buzzerPin - noTone(buzzerPin); - delay(50); - //Increment counter - counter++; -} -``` - -### Add the Servo Motor - -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. - -![Servo wiring.](assets/layout_motor_bb_bCPITLm4ud.png) - -In order to turn it 90 degrees we will use the following functions: - -```arduino -#include -int pos = 0; // variable to store the servo position -Servo myservo; // create servo object to control a servo -void setup() { - myservo.attach(9); // attaches the servo on pin 9 to the servo object - myservo.write(pos); // set the servo in position 0 -} -void loop() { - open_the_box(); - delay(2000); - close_the_box(); - delay(2000); -} -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 - } -} -``` - -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. - -## Complete Sketch - - - - - -### Build Your Puzzle Box - -It wouldn't be a box without a box, so download the case file [here](https://hacksterio.s3.amazonaws.com/uploads/attachments/387834/puzzlebox_Onm7enatcK.pdf) and use it as guide to build your own. - -Note that we used a 2mm cardboard. \ No newline at end of file diff --git a/content/tutorials/projects/puzzlebox/assets/blynk_1_mydos9zumA.png b/content/tutorials/projects/puzzlebox/assets/blynk_1_mydos9zumA.png deleted file mode 100644 index f3823d0d73..0000000000 Binary files a/content/tutorials/projects/puzzlebox/assets/blynk_1_mydos9zumA.png and /dev/null differ diff --git a/content/tutorials/projects/puzzlebox/assets/blynk_2_bGeyr6QFEe.png b/content/tutorials/projects/puzzlebox/assets/blynk_2_bGeyr6QFEe.png deleted file mode 100644 index 7bc3743195..0000000000 Binary files a/content/tutorials/projects/puzzlebox/assets/blynk_2_bGeyr6QFEe.png and /dev/null differ diff --git a/content/tutorials/projects/puzzlebox/assets/blynk_3_2qZr1YRDOJ.png b/content/tutorials/projects/puzzlebox/assets/blynk_3_2qZr1YRDOJ.png deleted file mode 100644 index 49a87e21eb..0000000000 Binary files a/content/tutorials/projects/puzzlebox/assets/blynk_3_2qZr1YRDOJ.png and /dev/null differ diff --git a/content/tutorials/projects/puzzlebox/assets/blynk_4_8igoWwsHxx.png b/content/tutorials/projects/puzzlebox/assets/blynk_4_8igoWwsHxx.png deleted file mode 100644 index 1c4f5d7c28..0000000000 Binary files a/content/tutorials/projects/puzzlebox/assets/blynk_4_8igoWwsHxx.png and /dev/null differ diff --git a/content/tutorials/projects/puzzlebox/assets/blynk_5_gNFkiBCYlv.png b/content/tutorials/projects/puzzlebox/assets/blynk_5_gNFkiBCYlv.png deleted file mode 100644 index 5e1bb032d3..0000000000 Binary files a/content/tutorials/projects/puzzlebox/assets/blynk_5_gNFkiBCYlv.png and /dev/null differ diff --git a/content/tutorials/projects/puzzlebox/assets/blynk_6_o8GGp4DLhD.png b/content/tutorials/projects/puzzlebox/assets/blynk_6_o8GGp4DLhD.png deleted file mode 100644 index 9508d583f6..0000000000 Binary files a/content/tutorials/projects/puzzlebox/assets/blynk_6_o8GGp4DLhD.png and /dev/null differ diff --git a/content/tutorials/projects/puzzlebox/assets/blynk_7_8j46kGlNfH.png b/content/tutorials/projects/puzzlebox/assets/blynk_7_8j46kGlNfH.png deleted file mode 100644 index ba6603ef5b..0000000000 Binary files a/content/tutorials/projects/puzzlebox/assets/blynk_7_8j46kGlNfH.png and /dev/null differ diff --git a/content/tutorials/projects/puzzlebox/assets/blynk_8_nzxXklL0e8.png b/content/tutorials/projects/puzzlebox/assets/blynk_8_nzxXklL0e8.png deleted file mode 100644 index 6d3a269c12..0000000000 Binary files a/content/tutorials/projects/puzzlebox/assets/blynk_8_nzxXklL0e8.png and /dev/null differ diff --git a/content/tutorials/projects/puzzlebox/assets/blynk_9_40yOZtY2JL.png b/content/tutorials/projects/puzzlebox/assets/blynk_9_40yOZtY2JL.png deleted file mode 100644 index e6c413cd7f..0000000000 Binary files a/content/tutorials/projects/puzzlebox/assets/blynk_9_40yOZtY2JL.png and /dev/null differ diff --git a/content/tutorials/projects/puzzlebox/assets/box-cover_RPYKV9OQC6.png b/content/tutorials/projects/puzzlebox/assets/box-cover_RPYKV9OQC6.png deleted file mode 100644 index 83b7bcaab3..0000000000 Binary files a/content/tutorials/projects/puzzlebox/assets/box-cover_RPYKV9OQC6.png and /dev/null differ diff --git a/content/tutorials/projects/puzzlebox/assets/buzzer_jVDTQg6qbJ.png b/content/tutorials/projects/puzzlebox/assets/buzzer_jVDTQg6qbJ.png deleted file mode 100644 index ffea6b9f71..0000000000 Binary files a/content/tutorials/projects/puzzlebox/assets/buzzer_jVDTQg6qbJ.png and /dev/null differ diff --git a/content/tutorials/projects/puzzlebox/assets/gif-box_Wdk5vQ4rJT.gif b/content/tutorials/projects/puzzlebox/assets/gif-box_Wdk5vQ4rJT.gif deleted file mode 100644 index 0c387d601c..0000000000 Binary files a/content/tutorials/projects/puzzlebox/assets/gif-box_Wdk5vQ4rJT.gif and /dev/null differ diff --git a/content/tutorials/projects/puzzlebox/assets/lcd_GkulgjldV3.png b/content/tutorials/projects/puzzlebox/assets/lcd_GkulgjldV3.png deleted file mode 100644 index 6e2ec4dd48..0000000000 Binary files a/content/tutorials/projects/puzzlebox/assets/lcd_GkulgjldV3.png and /dev/null differ diff --git a/content/tutorials/projects/puzzlebox/assets/potentiomers_1L76RX6oLl.png b/content/tutorials/projects/puzzlebox/assets/potentiomers_1L76RX6oLl.png deleted file mode 100644 index 6ae3e3179a..0000000000 Binary files a/content/tutorials/projects/puzzlebox/assets/potentiomers_1L76RX6oLl.png and /dev/null differ diff --git a/content/tutorials/projects/puzzlebox/assets/puzzlebox_wDO3aYMmZo.png b/content/tutorials/projects/puzzlebox/assets/puzzlebox_wDO3aYMmZo.png deleted file mode 100644 index 30b4e4fb98..0000000000 Binary files a/content/tutorials/projects/puzzlebox/assets/puzzlebox_wDO3aYMmZo.png and /dev/null differ diff --git a/content/tutorials/projects/puzzlebox/assets/rgb_caoc21qY77.png b/content/tutorials/projects/puzzlebox/assets/rgb_caoc21qY77.png deleted file mode 100644 index 36a533c58d..0000000000 Binary files a/content/tutorials/projects/puzzlebox/assets/rgb_caoc21qY77.png and /dev/null differ diff --git a/content/tutorials/projects/puzzlebox/assets/rgbled_s82wJXGcnF.png b/content/tutorials/projects/puzzlebox/assets/rgbled_s82wJXGcnF.png deleted file mode 100644 index 71e76d0b14..0000000000 Binary files a/content/tutorials/projects/puzzlebox/assets/rgbled_s82wJXGcnF.png and /dev/null differ diff --git a/content/tutorials/projects/puzzlebox/assets/screen_shot_2017-11-26_at_13_41_19_TmeYuaaIBs.png b/content/tutorials/projects/puzzlebox/assets/screen_shot_2017-11-26_at_13_41_19_TmeYuaaIBs.png deleted file mode 100644 index 6bd1bfaeb3..0000000000 Binary files a/content/tutorials/projects/puzzlebox/assets/screen_shot_2017-11-26_at_13_41_19_TmeYuaaIBs.png and /dev/null differ diff --git a/content/tutorials/projects/puzzlebox/assets/servo_Qvitu33zI9.png b/content/tutorials/projects/puzzlebox/assets/servo_Qvitu33zI9.png deleted file mode 100644 index 84b6f0512d..0000000000 Binary files a/content/tutorials/projects/puzzlebox/assets/servo_Qvitu33zI9.png and /dev/null differ diff --git a/content/tutorials/projects/puzzlebox/puzzlebox.md b/content/tutorials/projects/puzzlebox/puzzlebox.md deleted file mode 100644 index f845bc1c5d..0000000000 --- a/content/tutorials/projects/puzzlebox/puzzlebox.md +++ /dev/null @@ -1,559 +0,0 @@ ---- -title: "PuzzleBox © CC BY-NC" -description: "Protect your valuables with a puzzle!" -coverImage: "assets/box-cover_RPYKV9OQC6.png" -tags: [internet of things, iot] -author: "Arduino_Genuino" -difficulty: intermediate -source: "https://create.arduino.cc/projecthub/arduino/puzzlebox-c1f374" ---- - -## Components and Supplies - -- [Arduino MKR IoT Bundle](https://store.arduino.cc/usa/arduino-iot-mkr1000-bundle) - -## Apps and Online Services - -- [Blynk](https://www.blynk.cc/getting-started) - -## About This Project - -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 puzzlebox using the components from the MKR 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 you 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 online app [Blynk](http://www.blynk.cc/). An LED will help you guess, giving you colour feedbacks: the closer you are the warmer the colour. - -When the right combination is guessed the buzzer will start playing a song while the servo will open the box. - -In order to create our puzzle box we will need the following components: - -* Buzzer -* RGB LED -* 3 potentiometers -* LCD screen -* Servo motor - -![The puzzlebox.](assets/gif-box_Wdk5vQ4rJT.gif) - -### Learning Goals - -* Introducing [Blynk ](http://www.blynk.cc/)internet platform -* Wiring and using the LCD screen -* Playing Star Wars theme with the buzzer - -### Want to Know More? - -This tutorial is part of a series of experiments that familiarise you with the MKR1000 and IoT. All experiments can be built using the components contained in the MKR IoT Bundle. - -* [I Love You Pillow](https://create.arduino.cc/projecthub/arduino/love-you-pillow-f08931) -* Puzzle Box -* [Pavlov's Cat](https://create.arduino.cc/projecthub/arduino/pavlov-s-cat-7e6577) -* [The Nerd](https://create.arduino.cc/projecthub/arduino/the-nerd-0144f9) -* [Plant communicator](https://create.arduino.cc/projecthub/arduino/plant-communicator-7ea06f) - -### Introducing Blynk - -[Blynk](http://www.blynk.cc/) is a popular mobile app for Internet of Things, it allows us to easily control our internet connected Arduino from everywhere, anytime. - -It was founded on [Kickstarter](https://www.kickstarter.com/projects/167134865/blynk-build-an-app-for-your-arduino-project-in-5-m) and quickly became one of the most used apps in this field, thanks to both its [awesome documentation](http://docs.blynk.cc/) and its simplicity. - -### Getting Started with Blynk - -Creating a new project is really easy, just follow these few simple steps or take a look at the [official getting started](http://docs.blynk.cc/#getting-started) by Blynk. - -![Download the app](assets/blynk_5_gNFkiBCYlv.png) - - - -![Create an account](assets/blynk_4_8igoWwsHxx.png) - - -![New Project](assets/blynk_6_o8GGp4DLhD.png) - - -![Give it a name and select MKR1000 as a device](assets/blynk_1_mydos9zumA.png) - - -![Click on the + icon](assets/blynk_2_bGeyr6QFEe.png) - - -![Add 3 slider widget](assets/blynk_3_2qZr1YRDOJ.png) - - -![Click on the slider and set the value from 0 to 9](assets/blynk_7_8j46kGlNfH.png) - - -![Select a different Virtual pin for each slider](assets/blynk_9_40yOZtY2JL.png) - - -![Play the project by clicking the Top-Right play icon](assets/blynk_8_nzxXklL0e8.png) - - -After you successfully created a new project you should also receive via mail the **Auth Token.** It is a unique identifier which is needed to connect your hardware to your smartphone. Every new project you create will have its own Auth Token. - -In order to connect the Arduino to the app we will need to install the [Blynk library. ](https://github.com/blynkkk/blynk-library)If you are using the Arduino Web Editor the library will be automatically downloaded when you include it in the sketch, otherwise you can download that from the[ library manager.](https://www.arduino.cc/en/Guide/Libraries) - -Now we are ready to go. **Upload this sketch** and play with the sliders to see the result: - -```arduino -#include -#include -const char* ssid = SECRET_SSID; // your network SSID (name) -const char* password = SECRET_PSWD; // your network password -char auth[] = SECRET_TOKEN; // your Blynk API token -// Variables to store the combination value -// Set the initial combination to ( 1 1 1 ) -int SliderValueOne = 1; -int SliderValueTwo = 1; -int SliderValueThree = 1; -// Blynk functions to retrieve values -BLYNK_WRITE(V1) { - SliderValueOne = param.asInt(); // assigning incoming value from pin V1 to a variable -} -BLYNK_WRITE(V2) { - SliderValueTwo = param.asInt(); // assigning incoming value from pin V1 to a variable -} -BLYNK_WRITE(V3) { - SliderValueThree = param.asInt(); // assigning incoming value from pin V1 to a variable -} -void setup() { - Serial.begin(9600); - Blynk.begin(auth, ssid, password); // start Blynk functionalities and connect to WiFi -} -void loop() { - // Variambles to temporarily store the combination - int Temp_Slider_One_value = SliderValueOne; - int Temp_Slider_Two_value = SliderValueTwo; - int Temp_Slider_Three_value = SliderValueThree; - Blynk.run(); // poll new combination values from the online app - // check if combination values are changed and print them on the console - if(Temp_Slider_One_value != SliderValueOne || Temp_Slider_Two_value != SliderValueTwo || Temp_Slider_Three_value != SliderValueThree){ - Serial.print("New combination: "); - Serial.print(SliderValueOne); - Serial.print(" "); - Serial.print(SliderValueTwo); - Serial.print(" "); - Serial.println(SliderValueThree); - } -} -``` - -![Print on the Serial monitor the combination when it's changed.](assets/screen_shot_2017-11-26_at_13_41_19_TmeYuaaIBs.png) - - - -### Using the LCD Screen - -Time to connect the screen! - -The LCD screen is easy to use but requires a lot of wires, so be ready to prove your patience. - -![LCD Screen wiring.](assets/lcd_GkulgjldV3.png) - - -Note that we are using the 5V power supply and a 220 Ohm resistor. - -The brightness can be regulated changing the output value of the Analog pin 3 from 0 to 255 with 0 being the maximum value. - -```arduino -analogWrite(A3, 0); -``` - -Now we can upload the example sketch and see if everything is working fine. - -```arduino -// include the library code: -#include -// initialize the library by associating any needed LCD interface pin -// with the arduino pin number it is connected to -const int rs = 12, en = 11, d4 = 2, d5 = 3, d6 = 4, d7 = 5; -LiquidCrystal lcd(rs, en, d4, d5, d6, d7); -void setup() { - analogWrite(A3, 0); // 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() { - // set the cursor to column 0, line 1 - // (note: line 1 is the second row, since counting begins with 0): - lcd.setCursor(0, 1); - // print the number of seconds since reset: - lcd.print(millis() / 1000); -} -``` - -### Add Potentiometers - -To read the value of the potentiometers we will only need an `analogRead() `on the correct pin. We are connecting them to Analog pin 0 , 1 , 2. - -![Potentiometers wiring.](assets/potentiomers_1L76RX6oLl.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, - -```arduino - int PotOne = map(analogRead(A0), 0, 1023, 0, 9); -``` - -You can use this example code to print on the LCD screen the values of the potentiometers. - -```arduino -#include -// 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() { - analogWrite(A3, 0); // set the brightness of the LCD screen to the maximum value - Serial.begin(9600); - lcd.begin(16, 2); // begin LCD screen with 16 columns and 2 rows -} -void loop() { - int PotOne = map(analogRead(A0), 0, 1023, 0, 9); - int PotTwo = map(analogRead(A1), 0, 1023, 0, 9); - int PotThree = map(analogRead(A2), 0, 1023, 0, 9); - lcd.setCursor(0, 0); - lcd.print(PotOne); - lcd.setCursor(2, 0); - lcd.print(PotTwo); - lcd.setCursor(4, 0); - lcd.print(PotThree); -} -``` - -### Add the 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. - -![LED pins.](assets/rgbled_s82wJXGcnF.png) - - - -![LED wiring.](assets/rgb_caoc21qY77.png) - - -You can use this example sketch to see the RGB in action! - -```arduino -// RGB LED pins -int redPin = 6; -int greenPin = 8; -int bluePin = 7; -void setup() { - pinMode(redPin, OUTPUT); - pinMode(greenPin, OUTPUT); - pinMode(bluePin, OUTPUT); - Serial.begin(9600); -} -void loop() { - setColor(0, 0, 255); // blue - delay(1000); - setColor(0, 255, 255); // aqua - delay(1000); - setColor(255, 255, 0); // yellow - delay(1000); - setColor(255, 0, 0); // Red - delay(1000); -} -// Send RGB values to the LED pins -void setColor(int red, int green, int blue){ - analogWrite(redPin, red); - analogWrite(greenPin, green); - analogWrite(bluePin, blue); -} -``` - -### Connect It to Blynk - -Now we are ready to put things together: connect the board to Blynk, the potentiometer to the LCD screen and make the LED blink green when the combination is correct. - -* Note that we will use the function `giveColorFeedback()`to set the colour of the LED when the absolute value of each potentiometer is closer than a certain threshold to the correct combination. - -```arduino -void giveColorFeedback(int PotOne, int PotTwo, int PotThree){...} -``` - -* We will also use these variable to store the values sent from the app and therefore the combination. - -```arduino -int SliderValueOne = 1; -int SliderValueTwo = 1; -int SliderValueThree = 1; -``` - -Note that the initial value is set to 1, it will change only if you modify the values of the sliders on the app. **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 to see it in action: - -```arduino -#include -#include -#include -#include -// RGB LED pins -int redPin = 6; -int greenPin = 8; -int bluePin = 7; -const char* ssid = SECRET_SSID; // your network SSID (name) -const char* password = SECRET_PSWD; // your network password -char auth[] = SECRET_TOKEN; // your Blynk API token -// LCD screen pins -const int rs = 12, - en = 11, - d4 = 2, - d5 = 3, - d6 = 4, - d7 = 5; -bool start = true; -// Variables to store the combination value -// Set the initial combination to ( 1 1 1 ) -int SliderValueOne = 1; -int SliderValueTwo = 1; -int SliderValueThree = 1; -// Blynk functions to retrieve values -BLYNK_WRITE(V1) { - SliderValueOne = param.asInt(); // assigning incoming value from pin V1 to a variable -} -BLYNK_WRITE(V2) { - SliderValueTwo = param.asInt(); // assigning incoming value from pin V1 to a variable -} -BLYNK_WRITE(V3) { - SliderValueThree = param.asInt(); // assigning incoming value from pin V1 to a variable -} -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); - lcd.begin(16, 2); // begin LCD screen with 16 columns and 2 rows - Blynk.begin(auth, ssid, password); // start Blynk functionalities -} -void loop() { - // Variambles to temporarily store the combination - int Temp_Slider_One_value = SliderValueOne; - int Temp_Slider_Two_value = SliderValueTwo; - int Temp_Slider_Three_value = SliderValueThree; - Blynk.run(); // poll new combination values from the online app - // check if combination values are changed and print them on the console - if(Temp_Slider_One_value != SliderValueOne || Temp_Slider_Two_value != SliderValueTwo || Temp_Slider_Three_value != SliderValueThree){ - Serial.print("New combination: "); - Serial.print(SliderValueOne); - Serial.print(" "); - Serial.print(SliderValueTwo); - Serial.print(" "); - Serial.println(SliderValueThree); - } - int PotOne = map(analogRead(A0), 0, 1023, 0, 9); - int PotTwo = map(analogRead(A1), 0, 1023, 0, 9); - int PotThree = map(analogRead(A2), 0, 1023, 0, 9); - lcd.setCursor(0, 0); - lcd.print(PotOne); - lcd.setCursor(2, 0); - lcd.print(PotTwo); - lcd.setCursor(4, 0); - lcd.print(PotThree); - if (start) { - giveColorFeedback(PotOne, PotTwo, PotThree); - if (PotOne == SliderValueOne && PotTwo == SliderValueTwo && PotThree == SliderValueThree) { - blinkGreenLed(); - start = false; - } - } - if(!start) { - if(PotOne == 0 && PotTwo == 0 && PotThree == 0){ - start = true; - } - } -} -// 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 - SliderValueOne) <= 1 && abs(PotTwo - SliderValueTwo) <= 1 && abs(PotThree - SliderValueThree) <= 1 ) { - // Red - setColor(255, 0, 0); - } - else if (abs(PotOne - SliderValueOne) <= 3 && abs(PotTwo - SliderValueTwo) <= 3 && abs(PotThree - SliderValueThree) <= 3 ) { - // yellow - setColor(255, 255, 0); - } - else if (abs(PotOne - SliderValueOne) <= 4 && abs(PotTwo - SliderValueTwo) <= 4 && abs(PotThree - SliderValueThree) <= 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); - } -} -// Send RGB values to the LED pins -void setColor(int red, int green, int blue){ - analogWrite(redPin, red); - analogWrite(greenPin, green); - analogWrite(bluePin, blue); -} -``` - -### Add the Buzzer - -We will use the buzzer to play a melody when the box is opened. More precisely we will play the **Star Wars theme song!** - -Connecting the buzzer is simple: - -![Buzzer wiring.](assets/buzzer_jVDTQg6qbJ.png) - - - -Upload this example code and listen: - -```arduino -const int c = 261; -const int d = 294; -const int e = 329; -const int f = 349; -const int g = 391; -const int gS = 415; -const int a = 440; -const int aS = 455; -const int b = 466; -const int cH = 523; -const int cSH = 554; -const int dH = 587; -const int dSH = 622; -const int eH = 659; -const int fH = 698; -const int fSH = 740; -const int gH = 784; -const int gSH = 830; -const int aH = 880; -int counter = 0; -#define buzzerPin 1 -void setup() { - pinMode(buzzerPin, OUTPUT); - Serial.begin(9600); -} -void loop() { - play_jingle(); - delay(3000); -} -void play_jingle() -{ - beep(a, 500); - beep(a, 500); - beep(a, 500); - beep(f, 350); - beep(cH, 150); - beep(a, 500); - beep(f, 350); - beep(cH, 150); - beep(a, 650); - delay(500); - beep(eH, 500); - beep(eH, 500); - beep(eH, 500); - beep(fH, 350); - beep(cH, 150); - beep(gS, 500); - beep(f, 350); - beep(cH, 150); - beep(a, 650); - delay(500); -} -void beep(int note, int duration) -{ - //Play tone on buzzerPin - tone(buzzerPin, note, duration); - //Stop tone on buzzerPin - noTone(buzzerPin); - delay(50); - //Increment counter - counter++; -} -``` - -### Add the Servo Motor - -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. - -![Servo wiring.](assets/servo_Qvitu33zI9.png) - - - -In order to turn it 90 degrees we will use the following functions: - -```arduino -#include -int pos = 0; // variable to store the servo position -Servo myservo; // create servo object to control a servo -void setup() { - myservo.attach(9); // attaches the servo on pin 9 to the servo object - myservo.write(pos); // set the servo in position 0 -} -void loop() { - open_the_box(); - delay(2000); - close_the_box(); - delay(2000); -} -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 - } -} -``` - -## Complete Circuit - -![Complete circuit.](assets/puzzlebox_wDO3aYMmZo.png) - -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. - -## Complete Sketch - - - - -### Build Your Puzzle Box - -It wouldn't be a box without a box, so download the case file [here](https://hacksterio.s3.amazonaws.com/uploads/attachments/387834/puzzlebox_Onm7enatcK.pdf) and use it as guide to build your own. - -Note that we used a 2mm cardboard. \ No newline at end of file diff --git a/content/tutorials/projects/scheduled-relays/scheduled-relays.md b/content/tutorials/projects/scheduled-relays/scheduled-relays.md index 45c36cccad..94ebf69de4 100644 --- a/content/tutorials/projects/scheduled-relays/scheduled-relays.md +++ b/content/tutorials/projects/scheduled-relays/scheduled-relays.md @@ -1,5 +1,5 @@ --- -title: "Scheduled Relays © GPL3+" +title: "Scheduled Relays" description: "This project will show you how to schedule to drive the outputs on a MKR Relay Proto Shield using a MKR1000!" coverImage: "assets/tsx00003_iso_YCZrEamvd2.jpg" tags: [relay] diff --git a/content/tutorials/projects/smart-dumpster/smart-dumpster.md b/content/tutorials/projects/smart-dumpster/smart-dumpster.md index e503c52d81..3d025640a0 100644 --- a/content/tutorials/projects/smart-dumpster/smart-dumpster.md +++ b/content/tutorials/projects/smart-dumpster/smart-dumpster.md @@ -1,5 +1,5 @@ --- -title: "Smart Dumpster © CC BY-NC" +title: "Smart Dumpster" description: "Monitor a dumpster's status with flame, movement, and fill level sensors connected to a MKR NB 1500." coverImage: "assets/blob_XBhvp3tw65.png" tags: [data collection, environmental sensing, greener planet] diff --git a/content/tutorials/projects/the-nerd-with-mkr-wifi-1010/assets/blob_02cBBhx4lK.png b/content/tutorials/projects/the-nerd-with-mkr-wifi-1010/assets/blob_02cBBhx4lK.png deleted file mode 100644 index a8c4ece493..0000000000 Binary files a/content/tutorials/projects/the-nerd-with-mkr-wifi-1010/assets/blob_02cBBhx4lK.png and /dev/null differ diff --git a/content/tutorials/projects/the-nerd-with-mkr-wifi-1010/assets/nerd-cover_WBovgDSgMQ.png b/content/tutorials/projects/the-nerd-with-mkr-wifi-1010/assets/nerd-cover_WBovgDSgMQ.png deleted file mode 100644 index d5fcb316c8..0000000000 Binary files a/content/tutorials/projects/the-nerd-with-mkr-wifi-1010/assets/nerd-cover_WBovgDSgMQ.png and /dev/null differ diff --git a/content/tutorials/projects/the-nerd-with-mkr-wifi-1010/assets/nerd_layout_4zXSceF6X7.png b/content/tutorials/projects/the-nerd-with-mkr-wifi-1010/assets/nerd_layout_4zXSceF6X7.png deleted file mode 100644 index 1627f66424..0000000000 Binary files a/content/tutorials/projects/the-nerd-with-mkr-wifi-1010/assets/nerd_layout_4zXSceF6X7.png and /dev/null differ diff --git a/content/tutorials/projects/the-nerd-with-mkr-wifi-1010/the-nerd-with-mkr-wifi-1010.md b/content/tutorials/projects/the-nerd-with-mkr-wifi-1010/the-nerd-with-mkr-wifi-1010.md deleted file mode 100644 index 59de5b6dad..0000000000 --- a/content/tutorials/projects/the-nerd-with-mkr-wifi-1010/the-nerd-with-mkr-wifi-1010.md +++ /dev/null @@ -1,358 +0,0 @@ ---- -title: "The Nerd with MKR WiFi 1010 © CC BY-NC" -description: "Help keep your IoT pet alive via the Internet!" -coverImage: "assets/blob_02cBBhx4lK.png" -tags: [internet of things] -author: "Arduino_Genuino" -difficulty: advanced -source: "https://create.arduino.cc/projecthub/Arduino_Genuino/the-nerd-with-mkr-wifi-1010-462cc5" ---- - -## Components and Supplies - -- [Arduino MKR IoT Bundle 1010](https://store.arduino.cc/arduino-iot-mkr-wifi-1010-bundle) - -## About This Project - -### If You Had an IoT Pet, What Would It Eat? WiFi SSIDs, of Course! - -The Nerd is a wireless electronic pet that survives by collecting WiFi SSIDs along with some rest and sunlight. In order for it to thrive, you must balance offline and online mode with light and darkness to ensure that it has a proper daily eat-sleep-Nerd routine. If it is out of WiFi for too long, it will communicate an SOS in Morse code using its built-in piezo speaker. The longer it is offline, the more it will beep. - -![The Nerd.](assets/nerd-cover_WBovgDSgMQ.png) - -### In a Nutshell - -The Nerd will wake up each half hour to scan the networks around it. If it detects new networks, it will store them and go back to sleep in low power mode (to save battery life). Otherwise it will complain by making noise with the buzzer until you either feed it or put it in the dark. It will also understand when it's at home by connecting to your wifi network. When at home the Nerd will be able to connect to internet and get the current time and date. If not fed for more than two days, it will die dramatically, making a lot of noise. - -### Components - -* RGB LED -* Phototransistor -* Buzzer -* Battery -* 220 Ohm resistor - -### Learning Goals - -* Managing full WiFi functionalities -* Storing data in Flash Memory -* Managing time and Real Time Clock -* Managing Low Power mode - -### Want to Know More? - -This tutorial is part of a series of experiments that familiarise you with the MKR1010 and IoT. All experiments can be built using the components contained in the MKR IoT Bundle. - -* [I Love You Pillow with MKR WiFi 1010](https://create.arduino.cc/projecthub/Arduino_Genuino/i-love-your-pillow-with-mkr-wifi-1010-84b6da) -* [Puzzle Box with MKR WiFi 1010](https://create.arduino.cc/projecthub/Arduino_Genuino/puzzlebox-with-mkr-wifi-1010-7a39c4) -* [Pavlov's Cat with MKR WiFi 1010](https://create.arduino.cc/projecthub/Arduino_Genuino/pavlov-s-cat-with-mkr-wifi-1010-9ea418) -* The Nerd with MKR WiFi 1010 -* [Plant Communicator with MKR WiFi 1010](https://create.arduino.cc/projecthub/Arduino_Genuino/plant-communicator-with-mkr-wifi-1010-efc920) - -### Set up the Board - -In order to implement all the functionalities we are going to use the following libraries: - -* WiFiNINA // to connect to internet and scan the networks -* FlashStorage // to save values so that they don't get erased at each reboot -* RTCZero // to manage time triggered events -* ArduinoLowPower // to save battery power -* WiFiUdp // to get the time and date from internet - -You can download them from the library manager as explained in this guide. - -### Schematics - -![The schematics.](assets/nerd_layout_4zXSceF6X7.png) - -### Scanning WiFi Networks - -The Nerd is hungry for networks!Scanning network is pretty easy, **just upload this example sketch** or go to *> examples > WiFiNINA > ScanNetworksAdvanced* for a more extended version. - -```arduino -#include -#include -void setup() - { - //Initialize serial and wait for port to open: - Serial.begin(9600); - while (!Serial) { - ; // wait for serial port to connect. Needed for native USB port only - } // scan for existing networks: - Serial.println(); - Serial.println("Scanning available networks..."); - listNetworks(); - } - void loop() - { - delay(10000); // scan for existing networks: - Serial.println("Scanning available networks..."); - listNetworks(); - } - void listNetworks() - { // scan for nearby networks: - Serial.println("** Scan Networks **"); - int numSsid = WiFi.scanNetworks(); - if (numSsid == -1) - { - Serial.println("Couldn't get a WiFi connection"); - while (true); - } // print the list of networks seen: - Serial.print("number of available networks: "); - Serial.println(numSsid); - // print the network number and name for each network found: - for (int thisNet = 0; thisNet < numSsid; thisNet++) { - Serial.print(thisNet + 1); - Serial.print(" SSID: "); - Serial.println(WiFi.SSID(thisNet)); - Serial.flush(); - } - Serial.println(); - } -``` - -### Store Values in Flash Memory - -Surely you don't want the Nerd to die each time it goes out of battery!To avoid this behaviour we will save some variables (as the food amount) in the Flash memory so **that they can be retrieved even after the board has been turned off and turned on again.**You can understand the basic functionalities by using : - -*example > FlashStorage > FlashStoreAndRetrieve* - -**We will save the names of the networks** so that the Nerd will eat them only once, also we will use the array in which these SSIDs are saved to count the amount of food it ate during the day.Values saved on the Flash memory will survive a reset of the board but not the upload of a new sketch. **Each time you upload a new sketch the flash memory will be emptied as well.This sketch will scan the networks and save the SSID in the flash memory.** - -```arduino -#include -#include -#include -#define MAGIC_NUMBER 0x7423 // arbitrary number to double check the saved SSID -#define MaxNet 30 // max amount of network to be saved -int PosToBeSaved = 0; // Variable used to navigate the array of networks -int daily_amount_of_food = 12; // The amount of food per day needed to survive -// Struct of variable to be saved in flash memory -typedef struct { - int magic; - boolean valid[MaxNet]; - char SSIDs[MaxNet][100]; - } Networks; - FlashStorage(my_flash_store, Networks); - Networks values; - void setup() { - Serial.begin(115200); - while(!Serial); // wait until the Serial montior has be opened - delay(2000); - values = my_flash_store.read(); - if (values.magic == MAGIC_NUMBER) { // If token is correct print saved networks - Serial.println("saved data:"); - Serial.println(""); - for (int a = 0; a < MaxNet; a++) { - if (values.valid[a]) { - Serial.println(values.SSIDs[a]); - } else { - PosToBeSaved = a; - } - } - } - } - void loop() { // Temporarily save the number of networks - int networks_already_saved = PosToBeSaved; - getNetwork(); - if (PosToBeSaved >= daily_amount_of_food) { - Serial.println("Enough food for today"); - } - delay(5000); - } - // Feed the Nerd with networks's SSID - void getNetwork() { // scan for nearby networks: - Serial.println("\n*Scan Networks*\n"); - int numSsid = WiFi.scanNetworks(); - delay(1000); - if (numSsid == -1) { - Serial.println("There are no WiFi networks here.."); - } else { - Serial.print("number of available networks: "); - Serial.println(numSsid); - // print the network number and name for each network found: - for (int thisNet = 0; thisNet < numSsid; thisNet++) { - Serial.print("SSID: "); - Serial.println(WiFi.SSID(thisNet)); - delay(500); - char* net = WiFi.SSID(thisNet); - bool canBeSaved = true; - // check if the network has already been saved - for (int a = 0; a < PosToBeSaved ; a++) { - if (values.valid[a]) { - if (strncmp(net, values.SSIDs[a], 100) == 0 || strnlen(net, 100) == 0) { - Serial.println("Not saved"); - canBeSaved = false; - } - } - } - // Store ssid name - if (canBeSaved && PosToBeSaved < MaxNet) { - if (strlen(net) + 1 < 100 && strlen(net) > 0) { - memset(values.SSIDs[PosToBeSaved], 0, sizeof(values.SSIDs[PosToBeSaved])); // set all characters to zero - memcpy(values.SSIDs[PosToBeSaved], net, strlen(net) + 1); // copy "net" to values.SSDs[thisNet] - values.valid[PosToBeSaved] = true; - values.magic = MAGIC_NUMBER; - my_flash_store.write(values); - Serial.println(String(values.SSIDs[PosToBeSaved]) + " saved in position " + String(PosToBeSaved)); - PosToBeSaved ++; - } - else { - Serial.println(" network skipped"); - } - } - } - } - } -``` - -Note how we defined a maximum amount of networks that can be saved, so to avoid memory space issues: - -```arduino -#define MaxNet 30 -int PosToBeSaved = 0; -``` - -has been used to navigate the array in which networks names are saved and to measure the amount of food already eaten. - -### Managing Time - -We can combine the functionalities of the Real Time Clock (RTC) with the WiFi to **get the current time and date** and then set the inner clock of the board. In this way **we can trigger time based events** in a long timeframe without using the `millis()` function which can be tricky when you have to convert milliseconds into days.We will get the time from a **Network Time Protocol** (NTP) time server and then set the RTC with it. Note that the time received is in *epoch format*, which is the amount of seconds since January 1th 1970.You can run the basic sketch from *example > WiFiNINA> WiFiUdpNtpClient* **In the sketch below we are putting things together: the scan networks functionalities and the Time related ones.** - -* `bool atHome = false; ` is used to trigger the WiFi connection and therefore the request to the server to get the time. -* `check_home() ` is used to scan all the available networks and see if one of them is the *home WiFi network.* -* `connect_WiFi()` is then called, it will connect the board to WiFi, trigger the request to the server and print the current time. -* `rtc.setEpoch(epoch + GMT);` is used to start the RTC with the current time in epoch format, modify the GMT variable to adjust the time to your current time zone. - -```arduino -#include -#include -#include -#define MAGIC_NUMBER 0x7423 // arbitrary number to double check the saved SSID -#define MaxNet 30 // max amount of network to be saved -int PosToBeSaved = 0; // Variable used to navigate the array of networks -int daily_amount_of_food = 12; // The amount of food per day needed to survive -// Struct of variable to be saved in flash memory -typedef struct { - int magic; - boolean valid[MaxNet]; - char SSIDs[MaxNet][100]; - } Networks; - FlashStorage(my_flash_store, Networks); - Networks values; - void setup() { - Serial.begin(115200); - while(!Serial); // wait until the Serial montior has be opened - delay(2000); - values = my_flash_store.read(); // Read values from flash memory - if (values.magic == MAGIC_NUMBER) { - Serial.println("saved data:"); - Serial.println(""); - for (int a = 0; a < MaxNet; a++) { - if (values.valid[a]) { - Serial.println(values.SSIDs[a]); - } else { - PosToBeSaved = a; - } - } - } - } - void loop() { // Temporarily save the number of networks - int networks_already_saved = PosToBeSaved; - getNetwork(); - if (PosToBeSaved >= daily_amount_of_food) { - Serial.println("Enough food for today"); - } - delay(5000); - } - // Feed the Nerd with networks's SSID -void getNetwork() { // scan for nearby networks: - Serial.println("\n*Scan Networks*\n"); - int numSsid = WiFi.scanNetworks(); - delay(1000); - if (numSsid == -1) { - Serial.println("There are no WiFi networks here.."); - } else { - Serial.print("number of available networks: "); - Serial.println(numSsid); - // print the network number and name for each network found: - for (int thisNet = 0; thisNet < numSsid; thisNet++) { - Serial.print("SSID: "); - Serial.println(WiFi.SSID(thisNet)); - delay(500); - char* net = WiFi.SSID(thisNet); - bool canBeSaved = true; - // check if the network has already been saved - for (int a = 0; a < PosToBeSaved ; a++) { - if (values.valid[a]) { - if (strncmp(net, values.SSIDs[a], 100) == 0 || strnlen(net, 100) == 0) { - Serial.println("Not saved"); - canBeSaved = false; - } - } - } - // Store ssid name - if (canBeSaved && PosToBeSaved < MaxNet) { - if (strlen(net) + 1 < 100 && strlen(net) > 0) { - memset(values.SSIDs[PosToBeSaved], 0, sizeof(values.SSIDs[PosToBeSaved])); - memcpy(values.SSIDs[PosToBeSaved], net, strlen(net) + 1); - values.valid[PosToBeSaved] = true; - values.magic = MAGIC_NUMBER; - my_flash_store.write(values); - Serial.println(String(values.SSIDs[PosToBeSaved]) + " saved in position " + String(PosToBeSaved)); - PosToBeSaved ++; - } - else { - Serial.println(" network skipped"); - } - } - } - } - } -``` - -**Implementing the current time allow us to use a simple function like this to manage the life and death of the Nerd:** - -```arduino - if(rtc.getEpoch() - values.last_time_fed >= 86400*2){ - // complain and eventually die :( - } -``` - -Where `86400` is the number of seconds in one day, `values.last_time_fed ` is the stored value of the time in *epoch format* in which the Nerd has last been fed and `rtc.getEpoch()` return the current time in *epoch format*. - -### Low Power Mode - -We can use the low power mode to make our board go *to sleep.* Meaning that it will disable most of its functionalities (including WiFi) to save battery power.Since we want the Nerd to wake up regularly, **we can easily set a timer:** - -```arduino -#include "ArduinoLowPower.h" -int sleeping_time = 5000; // 5 seconds -bool awake = true; -void setup() { - Serial.begin(9600); - LowPower.attachInterruptWakeup(RTC_ALARM_WAKEUP, WakeUp, CHANGE); - pinMode(LED_BUILTIN, OUTPUT); - } - void loop() { - if (awake) { - digitalWrite(LED_BUILTIN, HIGH); - delay(500); - digitalWrite(LED_BUILTIN, LOW); - delay(500); - } - awake = false; - Serial.println("going to sleep"); - LowPower.sleep(sleeping_time); - } - void WakeUp() { - Serial.println("awake"); - awake = true; - } -``` - -Note that the `WakeUp()` function is attached to an interrupt, meaning that **it cannot contain any code that includes delays.** But we can set a boolean variable to trigger events in the loop. - -## Complete Sketch - - diff --git a/content/tutorials/projects/the-nerd/assets/nerd-cover_WBovgDSgMQ.png b/content/tutorials/projects/the-nerd/assets/nerd-cover_WBovgDSgMQ.png deleted file mode 100644 index d5fcb316c8..0000000000 Binary files a/content/tutorials/projects/the-nerd/assets/nerd-cover_WBovgDSgMQ.png and /dev/null differ diff --git a/content/tutorials/projects/the-nerd/assets/nerd_layout_J5wekzZoE8.png b/content/tutorials/projects/the-nerd/assets/nerd_layout_J5wekzZoE8.png deleted file mode 100644 index 2b42e5223e..0000000000 Binary files a/content/tutorials/projects/the-nerd/assets/nerd_layout_J5wekzZoE8.png and /dev/null differ diff --git a/content/tutorials/projects/the-nerd/the-nerd.md b/content/tutorials/projects/the-nerd/the-nerd.md deleted file mode 100644 index 364e37bd15..0000000000 --- a/content/tutorials/projects/the-nerd/the-nerd.md +++ /dev/null @@ -1,529 +0,0 @@ ---- -title: "The Nerd © CC BY-NC-SA" -description: "Help keep your IoT pet alive via the Internet! " -coverImage: "assets/nerd-cover_WBovgDSgMQ.png" -tags: [internet of things, iot] -author: "Arduino_Genuino" -difficulty: advanced -source: "https://create.arduino.cc/projecthub/arduino/the-nerd-0144f9" ---- - -## Components and Supplies - -- [Arduino MKR IoT Bundle](https://store.arduino.cc/usa/arduino-iot-mkr1000-bundle) - -## About This Project - -### If you had an IoT pet, what would it eat? WiFi SSIDs, of course! - -The Nerd is a wireless electronic pet that survives by collecting WiFi SSIDs along with some rest and sunlight. - -In order for it to thrive, you must balance offline and online mode with light and darkness to ensure that it has a proper daily eat-sleep-Nerd routine. - -If it is out of WiFi for too long, it will communicate an SOS in Morse code using its built-in piezo speaker. The longer it is offline, the more it will beep. - -![The Nerd.](assets/nerd-cover_WBovgDSgMQ.png) - -### In a Nutshell - -The Nerd will wake up each half hour to scan the networks around it. If it detects new networks, it will store them and go back to sleep in low power mode (to save battery life). Otherwise it will complain by making noise with the buzzer until you either feed it or put it in the dark. - -It will also understand when it's at home by connecting to your wifi network. When at home the Nerd will be able to connect to internet and get the current time and date. - -If not fed for more than two days, it will die dramatically, making a lot of noise. - -### Components - -* RGB LED -* Phototransistor -* Buzzer -* Battery -* 220 Ohm resistor - -### Learning Goals - -* Managing full WiFi functionalities -* Storing data in Flash Memory -* Managing time and Real Time Clock -* Managing Low Power mode - -### Want to Know More? - -This tutorial is part of a series of experiments that familiarise you with the MKR1000 and IoT. All experiments can be built using the components contained in the MKR IoT Bundle. - -* [I Love You Pillow](https://create.arduino.cc/projecthub/arduino/love-you-pillow-f08931) -* [Puzzle Box](https://create.arduino.cc/projecthub/arduino/puzzlebox-c1f374) -* [Pavlov's Cat](https://create.arduino.cc/projecthub/arduino/pavlov-s-cat-7e6577) -* The Nerd -* [Plant Communicator](https://create.arduino.cc/projecthub/arduino/plant-communicator-7ea06f) - -### Set up the Board - -In order to implement all the functionalities we are going to use the following libraries: - -* WiFi101 // to connect to internet and scan the networks -* FlashStorage // to save values so that they don't get erased at each reboot -* RTCZero // to manage time triggered events -* ArduinoLowPower // to save battery power -* WiFiUdp // to get the time and date from internet - - -You can download them from the library manager as explained in [this guide.](https://www.arduino.cc/en/Guide/Libraries) - -### Schematics - -![The schematics.](assets/nerd_layout_J5wekzZoE8.png) - -### The Nerd Casing - -You can find the blueprint for the casing **[here!](https://hacksterio.s3.amazonaws.com/uploads/attachments/387847/thenerdcase_qxpRK4ni5M.pdf)** - -### Scanning WiFi Networks - -The Nerd is hungry for networks! - -Scanning network is pretty easy, **just upload this example sketch** or go to *> examples > WiFi101 > ScanNetworksAdvanced* for a more extended version. - -```arduino -#include -#include -void setup() { - //Initialize serial and wait for port to open: - Serial.begin(9600); - while (!Serial) { - ; // wait for serial port to connect. Needed for native USB port only - } - // scan for existing networks: - Serial.println(); - Serial.println("Scanning available networks..."); - listNetworks(); -} -void loop() { - delay(10000); - // scan for existing networks: - Serial.println("Scanning available networks..."); - listNetworks(); -} -void listNetworks() { - // scan for nearby networks: - Serial.println("** Scan Networks **"); - int numSsid = WiFi.scanNetworks(); - if (numSsid == -1) - { - Serial.println("Couldn't get a WiFi connection"); - while (true); - } - // print the list of networks seen: - Serial.print("number of available networks: "); - Serial.println(numSsid); - // print the network number and name for each network found: - for (int thisNet = 0; thisNet < numSsid; thisNet++) { - Serial.print(thisNet + 1); - Serial.print(" SSID: "); - Serial.println(WiFi.SSID(thisNet)); - Serial.flush(); - } - Serial.println(); -} -``` - -### Store Values in Flash Memory - -Surely you don't want the Nerd to die each time it goes out of battery! - -To avoid this behaviour we will save some variables (as the food amount) in the Flash memory so **that they can be retrieved even after the board has been turned off and turned on again.** - -You can understand the basic functionalities by using : - *example > FlashStorage > FlashStoreAndRetrieve* - -**We will save the names of the networks** so that the Nerd will eat them only once, also we will use the array in which these SSIDs are saved to count the amount of food it ate during the day. - -Values saved on the Flash memory will survive a reset of the board but not the upload of a new sketch. **Each time you upload a new sketch the flash memory will be emptied as well.** - -**This sketch will scan the networks and save the SSID in the flash memory.** - -```arduino -#include -#include -#include -#define MAGIC_NUMBER 0x7423 // arbitrary number to double check the saved SSID -#define MaxNet 30 // max amount of network to be saved -int PosToBeSaved = 0; // Variable used to navigate the array of networks -int daily_amount_of_food = 12; // The amount of food per day needed to survive -// Struct of variable to be saved in flash memory -typedef struct { - int magic; - boolean valid[MaxNet]; - char SSIDs[MaxNet][100]; -} Networks; -FlashStorage(my_flash_store, Networks); -Networks values; -void setup() { - Serial.begin(115200); - while(!Serial); // wait until the Serial montior has be opened - delay(2000); - values = my_flash_store.read(); // Read values from flash memory - if (values.magic == MAGIC_NUMBER) { // If token is correct print saved networks - Serial.println("saved data:"); - Serial.println(""); - for (int a = 0; a < MaxNet; a++) { - if (values.valid[a]) { - Serial.println(values.SSIDs[a]); - } else { - PosToBeSaved = a; - } - } - } -} -void loop() { - // Temporarily save the number of networks - int networks_already_saved = PosToBeSaved; - getNetwork(); - if (PosToBeSaved >= daily_amount_of_food) { - Serial.println("Enough food for today"); - } - delay(5000); -} -// Feed the Nerd with networks's SSID -void getNetwork() { - // scan for nearby networks: - Serial.println("\n*Scan Networks*\n"); - int numSsid = WiFi.scanNetworks(); - delay(1000); - if (numSsid == -1) - { - Serial.println("There are no WiFi networks here.."); - } else { - Serial.print("number of available networks: "); - Serial.println(numSsid); - // print the network number and name for each network found: - for (int thisNet = 0; thisNet < numSsid; thisNet++) { - Serial.print("SSID: "); - Serial.println(WiFi.SSID(thisNet)); - delay(500); - char* net = WiFi.SSID(thisNet); - bool canBeSaved = true; - // check if the network has already been saved - for (int a = 0; a < PosToBeSaved ; a++) { - if (values.valid[a]) { - if (strncmp(net, values.SSIDs[a], 100) == 0 || strnlen(net, 100) == 0) { - Serial.println("Not saved"); - canBeSaved = false; - } - } - } - // Store ssid name - if (canBeSaved && PosToBeSaved < MaxNet) { - if (strlen(net) + 1 < 100 && strlen(net) > 0) { // check if the SSID name fits 100 bytes - memset(values.SSIDs[PosToBeSaved], 0, sizeof(values.SSIDs[PosToBeSaved])); // set all characters to zero - memcpy(values.SSIDs[PosToBeSaved], net, strlen(net) + 1); // copy "net" to values.SSDs[thisNet] - values.valid[PosToBeSaved] = true; - values.magic = MAGIC_NUMBER; - my_flash_store.write(values); - Serial.println(String(values.SSIDs[PosToBeSaved]) + " saved in position " + String(PosToBeSaved)); - PosToBeSaved ++; - } - else { - Serial.println(" network skipped"); - } - } - } - } -} -``` - -Note how we defined a maximum amount of networks that can be saved, so to avoid memory space issues: - -```arduino -#define MaxNet 30 -int PosToBeSaved = 0; -``` - -has been used to navigate the array in which networks names are saved and to measure the amount of food already eaten. - -### Managing Time - -We can combine the functionalities of the Real Time Clock (RTC) with the WiFi to **get the current time and date** and then set the inner clock of the board. In this way **we can trigger time based events** in a long timeframe without using the `millis()`function which can be tricky when you have to convert milliseconds into days. - -We will get the time from a **Network Time Protocol** (NTP) time server and then set the RTC with it. Note that the time received is in *epoch format*, which is the amount of seconds since January 1th 1970. - -You can run the basic sketch from *example > WiFi101 > WiFiUdpNtpClient* - -**In the sketch below we are putting things together: the scan networks functionalities and the Time related ones.** - -* `bool atHome = false;`is used to trigger the WiFi connection and therefore the request to the server to get the time. -* `check_home() `is used to scan all the available networks and see if one of them is the *home WiFi network.* -* `connect_WiFi()`is then called, it will connect the board to WiFi, trigger the request to the server and print the current time. -* `rtc.setEpoch(epoch + GMT); `is used to start the RTC with the current time in epoch format, modify the GMT variable to adjust the time to your current time zone. - -```arduino -#include -#include -#include -#include -#include -WiFiUDP udp; -WiFiUDP Udp; -RTCZero rtc; -#define MAGIC_NUMBER 0x7423 // arbitrary number to double check the saved SSID -#define MaxNet 30 // max amount of network to be saved -const char* home_ssid = SECRET_SSID; // your network SSID (name) -const char* password = SECRET_PSWD; // your network password -int PosToBeSaved = 0; // Variable used to navigate the array of networks -int daily_amount_of_food = 12; // The amount of food per day needed to survive -bool atHome = false; -// Struct of variable to be saved in flash memory -typedef struct { - int magic; - boolean valid[MaxNet]; - char SSIDs[MaxNet][100]; - int alive_days; - int last_time_feeded; -} Networks; -FlashStorage(my_flash_store, Networks); -Networks values; -void setup() { - Serial.begin(115200); - delay(2000); - rtc.begin(); // enable real time clock functionalities - values = my_flash_store.read(); // Read values from flash memory - if (values.magic == MAGIC_NUMBER) { // If token is correct print saved networks - Serial.println("saved data:"); - Serial.println(""); - for (int a = 0; a < MaxNet; a++) { - if (values.valid[a]) { - Serial.println(values.SSIDs[a]); - } else { - PosToBeSaved = a; - } - } - } -} -void loop() { - if(!atHome) check_home(); - // Temporarily save the number of networks - int networks_already_saved = PosToBeSaved; - getNetwork(); -if (PosToBeSaved >= daily_amount_of_food) { - Serial.println("Enough food for today"); -} -} -void check_home() { - int numSsid = WiFi.scanNetworks(); - if (numSsid != -1) { - for (int thisNet = 0; thisNet < numSsid; thisNet++) { - delay(100); - if (strncmp(WiFi.SSID(thisNet), home_ssid, 100) == 0) { - Serial.println("Yay, I'm home \n"); - atHome = true; - connect_WiFi(); - } - } - } -} -void connect_WiFi() { - if (WiFi.status() != WL_CONNECTED) { - while (WiFi.begin(home_ssid, password) != WL_CONNECTED) { - delay(500); - } - Serial.println("WiFi connected \n"); - GetCurrentTime(); - printTime(); - } -} -// Feed the Nerd with networks's SSID -void getNetwork() { - // scan for nearby networks: - Serial.println("*Scan Networks*"); - int numSsid = WiFi.scanNetworks(); - delay(1000); - if (numSsid == -1) - { - Serial.println("There are no WiFi networks here.."); - } else { - Serial.print("number of available networks: "); - Serial.println(numSsid); - // print the network number and name for each network found: - for (int thisNet = 0; thisNet < numSsid; thisNet++) { - Serial.print("SSID: "); - Serial.println(WiFi.SSID(thisNet)); - delay(500); - char* net = WiFi.SSID(thisNet); - bool canBeSaved = true; - // check if the network has already been saved - for (int a = 0; a < PosToBeSaved ; a++) { - if (values.valid[a]) { - if (strncmp(net, values.SSIDs[a], 100) == 0 || strnlen(net, 100) == 0) { - Serial.println("Not saved"); - canBeSaved = false; - } - } - } - // Store ssid name - if (canBeSaved && PosToBeSaved < MaxNet) { - if (strlen(net) + 1 < 100 && strlen(net) > 0) { // check if the SSID name fits 100 bytes - memset(values.SSIDs[PosToBeSaved], 0, sizeof(values.SSIDs[PosToBeSaved])); // set all characters to zero - memcpy(values.SSIDs[PosToBeSaved], net, strlen(net) + 1); // copy "net" to values.SSDs[thisNet] - values.valid[PosToBeSaved] = true; - values.last_time_feeded = rtc.getEpoch(); - values.magic = MAGIC_NUMBER; - my_flash_store.write(values); - Serial.println(String(values.SSIDs[PosToBeSaved]) + " saved in position " + String(PosToBeSaved)); - PosToBeSaved ++; - } - else { - Serial.println(" network skipped"); - } - } - } - } -} -/************************************************* - Start an UDP connection to get the time in unix, - then set the real time clock (rtc) -************************************************/ -unsigned int localPort = 2390; // local port to listen for UDP packets -IPAddress timeServer(129, 6, 15, 28); // time.nist.gov NTP server -const int NTP_PACKET_SIZE = 48; // NTP time stamp is in the first 48 bytes of the message -byte packetBuffer[ NTP_PACKET_SIZE]; //buffer to hold incoming and outgoing packets -const int GMT = 1 * 60 * 60; //change this to adapt it to your time zone hours*minutes*seconds -unsigned long epoch; -void GetCurrentTime() { - int numberOfTries = 0, maxTries = 6; - do { - epoch = readLinuxEpochUsingNTP(); - numberOfTries++; - } - while ((epoch == 0) || (numberOfTries > maxTries)); - if (numberOfTries > maxTries) { - Serial.print("NTP unreachable!!"); - while (1); - } - else { - Serial.print("Epoch received: "); - Serial.println(epoch); - rtc.setEpoch(epoch + GMT); - Serial.println(); - } -} -unsigned long readLinuxEpochUsingNTP() -{ - Udp.begin(localPort); - sendNTPpacket(timeServer); // send an NTP packet to a time server - // wait to see if a reply is available - delay(1000); - if ( Udp.parsePacket() ) { - Serial.println("NTP time received"); - // We've received a packet, read the data from it - Udp.read(packetBuffer, NTP_PACKET_SIZE); // read the packet into the buffer - //the timestamp starts at byte 40 of the received packet and is four bytes, - // or two words, long. First, esxtract the two words: - unsigned long highWord = word(packetBuffer[40], packetBuffer[41]); - unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]); - // combine the four bytes (two words) into a long integer - // this is NTP time (seconds since Jan 1 1900): - unsigned long secsSince1900 = highWord << 16 | lowWord; - // now convert NTP time into everyday time: - // Unix time starts on Jan 1 1970. In seconds, that's 2208988800: - const unsigned long seventyYears = 2208988800UL; - // subtract seventy years: - Udp.stop(); - return (secsSince1900 - seventyYears); - } - else { - Udp.stop(); - return 0; - } -} -// send an NTP request to the time server at the given address -unsigned long sendNTPpacket(IPAddress & address) -{ - // set all bytes in the buffer to 0 - memset(packetBuffer, 0, NTP_PACKET_SIZE); - // Initialize values needed to form NTP request - // (see URL above for details on the packets) - packetBuffer[0] = 0b11100011; // LI, Version, Mode - packetBuffer[1] = 0; // Stratum, or type of clock - packetBuffer[2] = 6; // Polling Interval - packetBuffer[3] = 0xEC; // Peer Clock Precision - // 8 bytes of zero for Root Delay & Root Dispersion - packetBuffer[12] = 49; - packetBuffer[13] = 0x4E; - packetBuffer[14] = 49; - packetBuffer[15] = 52; - // all NTP fields have been given values, now - // you can send a packet requesting a timestamp: - Udp.beginPacket(address, 123); //NTP requests are to port 123 - Udp.write(packetBuffer, NTP_PACKET_SIZE); - Udp.endPacket(); -} -void printTime() { - // Print date... - Serial.print(rtc.getDay()); - Serial.print(" / "); - Serial.print(rtc.getMonth()); - Serial.print(" / "); - Serial.print(rtc.getYear()); - Serial.print("\t"); - // ...and time - print2digits(rtc.getHours()); - Serial.print(": "); - print2digits(rtc.getMinutes()); - Serial.print(": "); - print2digits(rtc.getSeconds()); - Serial.println(""); -} -void print2digits(int number) { - if (number < 10) { - Serial.print("0"); - } - Serial.print(number); -``` - -**Implementing the current time allow us to use a simple function like this to manage the life and death of the Nerd:** - -```arduino - if(rtc.getEpoch() - values.last_time_fed >= 86400*2){ - // complain and eventually die :( - } -``` - -Where `86400`is the number of seconds in one day, `values.last_time_fed`is the stored value of the time in *epoch format* in which the Nerd has last been fed and `rtc.getEpoch()`return the current time in *epoch format*. - -### Low Power Mode - -We can use the low power mode to make our board go *to sleep.* Meaning that it will disable most of its functionalities (including WiFi) to save battery power. - -Since we want the Nerd to wake up regularly, **we can easily set a timer:** - -```arduino -#include "ArduinoLowPower.h" -int sleeping_time = 5000; // 5 seconds -bool awake = true; -void setup() { - Serial.begin(9600); - LowPower.attachInterruptWakeup(RTC_ALARM_WAKEUP, WakeUp, CHANGE); - pinMode(LED_BUILTIN, OUTPUT); -} -void loop() { - if (awake) { - digitalWrite(LED_BUILTIN, HIGH); - delay(500); - digitalWrite(LED_BUILTIN, LOW); - delay(500); - } - awake = false; - Serial.println("going to sleep"); - LowPower.sleep(sleeping_time); -} -void WakeUp() { - Serial.println("awake"); - awake = true; -} -``` - -Note that the `WakeUp()`function is attached to an interrupt, meaning that **it cannot contain any code that includes delays.** But we can set s boolean variable so to trigger events in the loop. - -## Complete Sketch - -