Plant Communicator with the Arduino IoT Bundle

Ever wished you could talk with your plants?

Components and Supplies

Apps and Online Services

About This Project

Create a plant communicator with the help of the Arduino Cloud!

As the English poet William Wordsworth once said:

"Your mind is the garden, your thoughts are the seeds, the harvest can be either flowers or weeds."

Keeping our plants alive can be quite the challenge as there’s a lack of clear communication between us and plants. One way to keep them happy is to bring our plants with us, but maybe we don't want to lug around with that big-ole-cactus or fern sticking out of our winter jacket pockets. Also, most plants dislike the cold. After spending months trying to communicate with our Spider Plant, we gave up and used the IoT Bundle components together with the Arduino Cloud to create a device that remotely surveys the well being of any plant instead.

In a Nutshell

In this experiment we will learn how to protect our plants and make sure they survive as well as using Arduino magic. By monitoring moisture, temperature and light, we can make sure that our plants are happy.

By the end of this project, your plant will communicate its needs with you visually and show you how it's currently doing through the Arduino IoT CLoud.

Components

  • TMP36 temperature sensor
  • Phototransistor
  • DIY moisture sensor

Note: to achieve all the functions demonstrated in this project, you would need a subscription to the Arduino Cloud. The project can be carried without an Arduino Cloud subscription by removing one of the variables (Light, Temperature, or moisture).

Learning Goals

  • Introducing the Arduino Cloud
  • Introducing the Arduino IoT Cloud Remote app
  • Building a DIY moisture sensor
  • Creating an Arduino Cloud Dashboard

Want to Know More?

This tutorial is part of a series of experiments that familiarize you with the Arduino RP2040 and IoT. All experiments can be built using the components contained in the IoT Bundle.

Setting up the Arduino Cloud

If you are new to the Arduino Cloud, check out our Getting Started Guide.

Template

To connect your board to the Arduino Cloud, we will use the Plant Communicator Template. This template installs a specific sketch on your board and creates a dashboard that allows you to interact with your board: you don't need to write any code at all!

See the image below to understand how to set it up.

Thing overview
Thing overview

We will start by setting up the Arduino Cloud by following the steps below:

  • Login to your Arduino Create account
  • Creating a Thing
  • Attaching a Device
  • Adding Variables
  • Adding Network credentials

Setting up the Arduino Cloud

Setting up the Arduino Cloud

Variables

We will start by adding four variables:

Arduino IoT Bundle
Arduino IoT Bundle

Setup Hardware & Sketch

DIY soil moisture

Two wires placed in the soil pot form a variable resistor, whose resistance varies depending on soil moisture. This variable resistor is connected in a voltage divider configuration, and Arduino collects a voltage proportional to resistance between the 2 wires. Meaning that the more humid the soil is, the less voltage will be measured from the Arduino because the resistance in the soil decreases with its moisture. The dryer the soil is the higher resistance is. Using the 1 Mega Ohm resistor and two wires, we can create our DIY soil moisture sensor.

Arduino IoT Bundle
Arduino IoT Bundle

That value will be used to set a threshold so that the Arduino will know when your plants need water. Add the code shown below to your sketch and test the moisture levels of your plant. The values are shown in the serial monitor.

1#include "thingProperties.h"
2int moisturePin = A2;
3/* Set this threshold accordingly to the resistance you used */
4/* The easiest way to calibrate this value is to test the sensor in both dry and wet earth */
5int threshold = 800;
6void setup() {
7 /* Initialize serial and wait for port to open: */
8 Serial.begin(9600);
9 /* This delay gives the chance to wait for a Serial Monitor without blocking if none is found */
10 delay(1500);
11 /* Defined in thingProperties.h */
12 initProperties();
13 /* Connect to Arduino Cloud */
14 ArduinoCloud.begin(ArduinoIoTPreferredConnection);
15 /*
16 The following function allows you to obtain more information
17 related to the state of network and IoT Cloud connection and errors
18 the higher number the more granular information you’ll get.
19 The default is 0 (only errors).
20 Maximum is 4
21 */
22 setDebugMessageLevel(2);
23 ArduinoCloud.printDebugInfo();
24}
25void loop() {
26 ArduinoCloud.update();
27 moisture = get_average_moisture();
28 Serial.print("moisture ");
29 Serial.println(moisture);
30 /* assign the message variable based on water levels */
31 if (moisture > threshold) {
32 message = "Warning your plant needs water!"; /* Insert here your emergency message */
33 } else {
34 message = "Your plant has enough water!";
35 }
36 Serial.println(message);
37}
38int get_average_moisture() {
39 int tempValue = 0; /* variable to temporarily store moisture value */
40 /* make an average of 10 values to be more accurate */
41 for (int a = 0; a < 10; a++) {
42 tempValue += analogRead(moisturePin);
43 delay(100);
44 }
45 return tempValue / 10;
46}
47/*
48Since Message is READ_WRITE variable, onMessageChange() is
49executed every time a new value is received from IoT Cloud.
50*/
51void onMessageChange() {
52 /* Add your code here to act upon Message change */
53}

Light & temperature sensors

See the schematic below to wire up the two sensors. We will use these two functions to read values from the sensors:

Arduino IoT Bundle
Arduino IoT Bundle

1#include "thingProperties.h"
2int lightPin = A0; /*the analog pin the light sensor is connected to */
3int tempPin = A1; /*the analog pin the TMP36's Vout (sense) pin is connected to */
4int moisturePin = A2;
5/* Set this threshold accordingly to the resistance you used */
6/* The easiest way to calibrate this value is to test the sensor in both dry and wet earth */
7int threshold = 800;
8void setup() {
9 /* Initialize serial and wait for port to open: */
10 Serial.begin(9600);
11 /* This delay gives the chance to wait for a Serial Monitor without blocking if none is found */
12 delay(1500);
13 /* Defined in thingProperties.h */
14 initProperties();
15 /* Connect to Arduino Cloud */
16 ArduinoCloud.begin(ArduinoIoTPreferredConnection);
17 /*
18 The following function allows you to obtain more information
19 related to the state of network and IoT Cloud connection and errors
20 the higher number the more granular information you’ll get.
21 The default is 0 (only errors).
22 Maximum is 4
23 */
24 setDebugMessageLevel(2);
25 ArduinoCloud.printDebugInfo();
26}
27void loop() {
28 ArduinoCloud.update();
29 light = analogRead(lightPin); /* assign light variable to light sensor values */
30 Serial.print("light ");
31 Serial.println(light);
32 temperature = get_temperature(); /* assign temperature variable to temperature in Celsius */
33 Serial.print("temperature ");
34 Serial.println(temperature);
35
36 moisture = get_average_moisture();
37 /* assign the message variable based on water levels */
38 if (moisture > threshold) {
39 message = "Warning your plant needs water!"; /* Insert here your emergency message */
40 } else {
41 message = "Your plant has enough water!";
42 }
43}
44int get_average_moisture() {
45 int tempValue = 0; /* variable to temporarily store moisture value */
46 /* make an average of 10 values to be more accurate */
47 for (int a = 0; a < 10; a++) {
48 tempValue += analogRead(moisturePin);
49 delay(100);
50 }
51 return tempValue / 10;
52}
53float get_temperature() {
54 int reading = analogRead(tempPin);
55 float voltage = reading * 3.3;
56 voltage /= 1024.0;
57 /* temperature in Celsius */
58 float temperatureC = (voltage - 0.5) * 100 ; /*converting from 10 mv per degree with 500 mV offset */
59 /* Convert to Fahrenheit */
60 float temperatureF = (temperatureC * 9.0 / 5.0) + 32.0;
61 return temperatureC;
62}
63void onMessageChange() {
64 /* Add your code here to act upon Message change */
65}

Note that you can use the Fahrenheit units by returning temperatureF instead of temperatureC at the end of the “get_temperature()” function.

Dashboard

The final step to deploying our project is adding a control panel using the Arduino IoT Dashboards. We can navigate to Dashboards -> Build Dashboard -> ADD, then we can add four widget and link them to the variable as the following:

  • Graph widget -> temperature variable
  • Graph widget -> moisture variable
  • Gauge widget -> light variable
  • Messenger widget -> message variable

Arduino IoT Bundle

Now, we can see a visual representation of our sensor data.

Arduino IoT Bundle

Congratulations you have now build your own DIY plant communicator showing how your plants are doing using the IoT Bundle and IoT Cloud.

Want to Know More?

This tutorial is part of a series of experiments that familiarize you with the Arduino IoT Bundle. All experiments can be built using the components contained in the IoT Bundle.

Full Code

Suggest changes

The content on docs.arduino.cc is facilitated through a public GitHub repository. If you see anything wrong, you can edit this page here.

License

The Arduino documentation is licensed under the Creative Commons Attribution-Share Alike 4.0 license.