This is machine translation

Translated by Microsoft
Mouseover text to see original. Click the button below to return to the English version of the page.

Note: This page has been translated by MathWorks. Please click here
To view all translated materials including this page, select Japan from the country navigator on the bottom of this page.

Moisture Monitor with HTTP POST to Channel and Deep Sleep

This example shows how to post multiple fields of data to a ThingSpeak™ channel with a device that wakes from deep sleep. You read a soil moisture sensor and post the value to a ThingSpeak channel. The HTTP POST request is executed by writing to a communication client without a separate library. Directly writing the HTTP request to the wireless network client can offer increased flexibility and speed over the ThingSpeak Communication Library.

Supported Hardware

  • ESP 8266–12

  • NodeMCU ESP8266–12.

  • Arduino with Ethernet or Wireless Connection (with some code adjustments)

In this example, the on-board ADC reads a moisture sensor and posts the value and the elapsed time to two fields of a ThingSpeak channel. You can modify the post to fill up to eight fields with data.

This image shows an office plant with a moisture sensor wired to a Node MCU ESP 8266-12. The NODE MCU provides a wireless network connection. The moisture sensor is powered from a data pin on the board, limiting the time power is on. This design reduces power and extends the life of the sensor. In between measurements, the device is put into a deep sleep mode to save power. Once your data is posted to the channel, you can set up reactions to the data. For example, you can set the React app to notify you that the moisture level is low.


  1. Create a ThingSpeak Channel.

  2. On the Channel Settings tab, enable field 1. You can provide an informative field title such as Moisture Value.

  3. Note the Write API Key from the API Keys tab. You need this value in the code used to program your device.

Required Hardware

  • NodeMCU ESP8266-12E (Used for this demonstration, other hardware can be substituted)

  • Soil Moisture sensor: Sparkfun Moisture Sensor

  • Jumper wires (at least 4)

  • USB cable

Schematic and Connections

  1. Connect VCC of the moisture sensor to pin D7 on the NodeMCU.

  2. Connect the sensor Gnd to the NodeMCU ground.

  3. Connect the sensor Sig pin to NodeMCU pin A0.

  4. Connect the NodeMCU Rst pin to NodeMCU pin D0, to enable wake up from deep sleep.

Programming Your Device

  1. Download the latest Arduino® IDE.

  2. Add the ESP8266 Board Package.

    1. Enter into Additional Board Manager URLs under File > Preferences.

    2. Choose Tools > Boards > Board Manager. Search for ESP8266 in the search bar and install the package.

  3. Select the appropriate port and board in the Arduino IDE. The hardware used to generate this example used the Node MCU 1.0 (ESP 8266–12E) option.

  4. Create the application:

    Open a new window in the Arduino IDE and save the file. Add the code provided here. Be sure to adjust the wireless network information and API key in the code.

  5. After you successfully upload your program, you can monitor the output using the serial monitor, or your channel view page.

     Full Code for Copy and Paste

    1. Include the ESP8266WiFi library and initializing variables. Edit the network information and Write API Key in your code.

      #include <ESP8266WiFi.h>
      #define soilPin A0
      #define sensorPower 13
      // Network Information
      const char* ssid     = "ssid";
      const char* password = "PPPPP";
      // Global Variables
      int ADCValue = 0;
      long sleepTimeSeconds = 1800;
      char thingSpeakAddress[] = "";
      String writeAPIKey="XXXXXXXXXXXXXXXX";            // Be sure to change this to your channel Write API key
      WiFiClient client;
      int numFields = 2;
    2. In the setup function, start the serial monitor, connect to the wireless network, and initialize the device pins that you use.

      void setup()
          Serial.begin( 115200 );   // You may need to adjust the speed depending on your hardware.
          pinMode( sensorPower , OUTPUT );
          digitalWrite( sensorPower , LOW );   // Set to LOW so no power is flowing through the sensor.
    3. In the main loop, read the soil monitor and store it in the data[] array. Post the data to ThingSpeak, and then put the device in low-power mode.

      void loop()
          String data[ 8 ];  // You can fill data with up to 8 values to write to successive fields in your channel.
          data[ 1 ] = String( readSoil() ); //you can write to multiple fields by storing data in the data[] array.  Be sure to increase numFields
          Serial.print( "Soil Moisture = " );
          Serial.println( data[ 1 ] );
          data[ 2 ] = String( millis() );
          HTTPPost( data );
          delay( 1000 );
          Serial.print( "Goodnight" );
          ESP.deepSleep( sleepTimeSeconds * 1000000 );
          // If you remove the sleep, be sure to add more delay so you don't post to ThingSpeak too often.
    4. Use the readSoil function to provide power to the sensor, and then read the voltage at the output using the ADC. Remove the power after the measurement.

      // This is a function used to get the soil moisture sensor.
      int readSoil()
          digitalWrite(sensorPower, HIGH);  // Turn power to device on
          delay(10);    // Wait 10 milliseconds for sensor to settle
          ADCValue = analogRead(soilPin);     // Read the value from sensor
          digitalWrite(sensorPower, LOW);   // Turn power to device off
          return ADCValue;                    // Return the moisture value
    5. Connect your device to the wireless network using the connectWiFi function.

      int connectWifi()
          WiFi.begin( ssid , password );
          while (WiFi.status() != WL_CONNECTED) {
              Serial.println( "Connecting to WiFi" );
              delay( 2500 );
          Serial.println( "Connected" );  // Inform the serial monitor
    6. Build the data string to post to your channel. Connect to ThingSpeak, and use the client to complete an HTTP POST.

      int HTTPPost(String fieldData[]){
          // This function builds the data string for posting to ThingSpeak and provides the correct format for the wifi client to communicate with ThingSpeak.
          // It will post "numFields" worth of data entries, and take the data from the fieldData parameter passed to it.
          // Be sure to increase numFields to the number of fields you need, and activate the fields in your channel view.
          if (client.connect( thingSpeakAddress , 80 )){
            // Build the Posting data string.  If you have multiple fields, make sure the sting does not exceed 1440 characters.
              String PostData= "api_key=" + writeAPIKey ;
              for ( int field = 1; field < numFields+1; field++ ){
                  PostData += "&field" + String( field ) + "=" + fieldData[ field ];
              // POST data via HTTP
              Serial.println( "Connecting to ThingSpeak for update..." );
              client.println( "POST /update HTTP/1.1" );
              client.println( "Host:" );
              client.println( "Connection: close" );
              client.println( "Content-Type: application/x-www-form-urlencoded" );
              client.println( "Content-Length: " + String( PostData.length() ) );
              client.println( PostData );
              Serial.println( PostData );

You can determine the useful range of values by monitoring your channel over wet and dry cycles. The number read by the ADC and posted to your channel is proportional to the voltage, and thus proportional to the soil moisture. The values vary depending on the temperature, humidity, and soil type. Once you know the values for dry soil, you can use the React app to generate a notification that it is time to water the plant. For more information on setting up React, see Monitor and Act on Channel Inactivity Using ThingSpeak Apps.

Related Topics

External Websites

Was this topic helpful?