Measuring soil moisture with the NodeMCU Amica (ESP8266)
Tags: iot, esp8266, beginners, arduino
Published: 2018-05-24 13:32:12

---
title: Measuring soil moisture with the NodeMCU Amica (ESP8266)
published: true
description: Use a NodeMCU Amica (ESP8266 based development board) and a Funduino moisture sensor to measure soil moisture, and build a Wia Flow that notifies you when your plants need watering.
tags: #iot #esp8266 #beginners #arduino
---

![alt text](https://s3-eu-west-1.amazonaws.com/wia-flarum-bucket/2018-05-24/1527154845-205657-tech3182-2-sdr2kznlof.jpeg)

In this tutorial, we'll use a NodeMCU Amica (ESP8266 based development board) and a Funduino moisture sensor to measure soil moisture, and build a Wia Flow that notifies you when your plants need watering.


###**Before you begin**
To get set up with the NodeMCU Amica, you'll need to follow [our tutorial on getting started with the ESP8266](https://developers.wia.io/v1.0/docs/espressif-esp8266). It details setting up the correct environment to complete the rest of this tutorial.


###**Connecting the hardware**
Use jumper wires to connect the moisture sensor to the board as follows:
![alt text](https://files.readme.io/82b3be5-Screenshot_from_2018-05-15_15-01-06.png)

###**Install the required libraries**
In the Arduino IDE, go to `Sketch > Include Libraries > Manage Libraries`. 
Install each of the following libraries by searching for their name in the search bar within the modal. A button will appear in the bottom right of the box that will allow you to install the library.

* ArduinoJson
* ESP8266WiFi
* ArduinoHttpClient
If a library doesn't show up in the results when you search it, you may need to update your Arduino IDE version. You can download the latest version [here](https://www.arduino.cc/en/main/software).


###**The Code**
In the Arduino IDE, copy and paste the following code:
```
#include <ArduinoJson.h>
#include <ESP8266WiFi.h>
#include <ArduinoHttpClient.h>
#include <Arduino.h>

const char* ssid     = "your-ssid"; // Your WiFi ssid
const char* password = "your-password"; //Your Wifi password

// Get this secret key from the wia dashboard. It should start with `d_sk`
const char* device_secret_key = "your-device-secret-key";

// Wia API parameters
char server[] = "api.wia.io";
char path[] = "/v1/events";
int port = 80;

WiFiClient client;
int status = WL_IDLE_STATUS;

StaticJsonBuffer<200> jsonBuffer;
HttpClient httpClient = HttpClient(client, server, port);
JsonObject& root = jsonBuffer.createObject();

const int ANALOG_PIN = 0;

void setup() {
  
  // initialize serial communications and wait for port to open:
  Serial.begin(115200);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }
  WiFi.begin(ssid, password);
  Serial.print("Attempting to connect to SSID: ");
  Serial.print(ssid);
  // attempt to connect to WiFi network:
  while (WiFi.status() != WL_CONNECTED) {
    Serial.print(".");
    // Connect to WPA/WPA2 network. Change this line if using open or WEP  network:
    // wait 5 seconds for connection:
    delay(5000);
  }

  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());
  Serial.println("connecting...");
}

// Thing function runs continiously
void loop() {
  
  root["name"] = "moisture";
  root["data"] =  analogRead (ANALOG_PIN);

  // if you get a connection, report back via serial:
  if (client.connect(server, port)) {

    sendToWia(root);

  } else {
    // if you didn't get a connection to the server:
    Serial.println("connection failed");
  }
  delay(1000*15*60); // Wait for 15 minutes to post again
}

// Adds the correct headers for HTTP and sends Data to Wia
void sendToWia(JsonObject& data) {
  size_t len = data.measureLength();
  size_t size = len + 1;
  char json[size];
  httpClient.beginRequest();
  httpClient.post(path);
  httpClient.sendHeader("Content-Type", "application/json");
  httpClient.sendHeader("Content-Length", data.measureLength());
  httpClient.sendHeader("Authorization", "Bearer " + String(device_secret_key));
  httpClient.beginBody();
  data.printTo(httpClient);
  Serial.print("Posting ");
  data.printTo(Serial);
  Serial.println(" to Wia");
  httpClient.endRequest();
}
```
Replace the values of the following variables (Place the correct value between the quotation marks right of the variable names in the code):

* `your-ssid` - with your WiFi network name
* `your-password` - with your WiFi network password
* `your-device-secret-key` with your device secret key from the Wia Dashboard (the one that begins with d_sk)

The code above publishes an Event to Wia every 15 minutes, with a `name` value of `moisture` (you'll need this later on, when building your Flow), and a `data` value equal to the reading from the moisture sensor.

Make sure the correct board is selected - go to `tools > board` and select `NodeMCU 1.0 (ESP-12E Module)`.
Make sure the correct port is selected - `tools > port`.

If either of those steps are not working for you, refer back to [our tutorial on getting started with the ESP8266](https://developers.wia.io/v1.0/docs/espressif-esp8266).

Click `Sketch > Upload` in the menu.

Go to your Wia dashboard and view the Events as they come in via the Device debugger.

###**Notifying you when your plant needs watering**
Next, we'll set up a Flow that will send a notification to your phone when the moisture level drops below a certain threshold. The Wia app is required to send a push notification to your phone, it can be installed [here](https://play.google.com/store/apps/details?id=io.wia.wia) for Android.

Go to your Wia Dashboard and click `Flows` in the left hand side menu. Create a new Flow with any name you like.

In Flow Studio, drag an `Event` node from the triggers section and:

* Enter `moisture` as the the `Event Name`
* Add the Device that matches the one you added to the code earlier
![alt text](https://s3-eu-west-1.amazonaws.com/wia-flarum-bucket/2018-04-16/1523872401-934367-selection-060.png)

Drag a `function` node from the logic section and copy and paste the following code:
```
// Check moisture levels
if (input.body.data && input.body.data < 500) {
  // Plant is thirsty
  output.process = true;
} else {
  // Plant is ok
  output.process = false;
}
```
The output from the soil moisture sensor is a number between 0 and 1023 with 0 being completely dry and 1023 being completely wet. 

The code above tells Wia to only process the input if it is less than 500 (i.e. the doesn't plant need watering).

Finally, add a `notification` node and enter `The plant needs watering` in the text field so that Wia can send a notification to you when your plant needs watering. 

![alt text](https://s3-eu-west-1.amazonaws.com/wia-flarum-bucket/2018-04-16/1523879728-577477-notification-node.png)

###**Taking it One Step Further**
Here's just one way you could take this project to the next level: we're going to feed our moisture data into two Widgets on the Wia Dashboard, in addition to sending the notification.

First, add another `function` node from the logic section, and connect it to the same `event`. In this node, paste the following code:
```
// Check moisture levels
if (input.body.data && input.body.data < 500) {
  // Plant is thirsty
	output.body.data = "Thirsty";
} else {
  // Plant is ok
	output.body.data = "Ok";
}
```
This code outputs 'Thirsty' if the plant needs watering, and 'Ok' otherwise. We're now going to connect the output of this `function` node to a new `event` action node. Drag one over from the 'actions' section (not 'triggers'). This will create a new event. Give the event a name (such as `status`), and connect the `function` node to it.

![alt text](https://files.readme.io/63ceff4-Screenshot_from_2018-05-15_15-17-15.png)

Next, head over to your Device's 'Overview' tab. Click 'Add a Widget'. Give the Widget a name ('Status'), choose Widget type 'text', and enter the name of the Event that you created in your Flow (`status`).

![alt text](https://files.readme.io/1dada30-Screenshot_from_2018-05-15_15-22-17.png)

Create another Widget of type 'text', give it a name ('Moisture') and enter the name of your original Event trigger (`moisture`).

![alt text](https://files.readme.io/623e1d4-Screenshot_from_2018-05-15_15-24-46.png)

Now, when your events are published, the Widgets on your Device overview page will update in real time!

![alt text](https://files.readme.io/00a4538-Screenshot_from_2018-05-15_15-28-40.png)