Introduction: ESP8266 Building Blocks: Send Data to a Web Server With POST

About: IoT - Internet of Things. Iota - small thing. Thingamajig - An object whose name can't be recalled. Iotamajig - A little unnamed internet connected gizmo!

This instructable is part of my series on introducing people to the ESP8266-01 WiFi transceiver. The goal of this series is to act as a basic code repository for easy reuse, as well as to provide some foundational building blocks for people new to the ESP. The "building blocks" series will contain just the basic code needed to complete the object of the instructable, with a (hopefully) thorough explanation of what's going on and why.

Here we are going to take a look at one way of sending data to a web server: the HTTP POST. We covered the GET method in this instructable. Please Note: This code will NOT run on it's own, as there is no code included actually connecting it to the internet. See this instructable for the code to add to make that connection (building blocks!).

Step 1: The Code

#include 

//IP or name of address root: ie: google.com
//NOT google.com/nothing/after/the/dotcom.html
const char* hostPost = "mydatasite.com"; 

void postData(String sline) {

   WiFiClient clientPost;
   const int httpPostPort = 80;

   //the path and file to post the data to:
   String urlPost = "/data/collector.php";

      Serial.print(">>> Connecting to host: ");
      Serial.println(hostPost);
      
       if (!clientPost.connect(hostPost, httpPostPort)) {
        Serial.print("Connection failed: ");
        Serial.print(hostPost);
      } else {
          clientPost.println("POST " + urlPost + " HTTP/1.1");
          clientPost.print("Host: ");
          clientPost.println(hostPost);
          clientPost.println("User-Agent: ESP8266/1.0");
          clientPost.println("Connection: close");
          clientPost.println("Content-Type: application/x-www-form-urlencoded;");
          clientPost.print("Content-Length: ");
          clientPost.println(sline.length());
          clientPost.println();
          clientPost.println(sline);

          Serial.print("Content Length: ");
          Serial.println(sline.length());
          
          unsigned long timeoutP = millis();
          while (clientPost.available() == 0) {
            
            if (millis() - timeoutP > 10000) {
              Serial.print(">>> Client Timeout: ");
              Serial.println(hostPost);
              clientPost.stop();
              return;
            }
          }

          //just checks the 1st line of the server response. Could be expanded if needed.
          while(clientPost.available()){
            String retLine = clientPost.readStringUntil('\r');
            Serial.println(retLine);
            break; 
          }

      } //end client connection if else
                        
      Serial.print(">>> Closing host: ");
      Serial.println(hostPost);
          
      clientPost.stop();

}

void setup() {
  // put your setup code here, to run once:

}

void loop() {
  String dataSend = "name=Jimmy&ID=52";
  postData(dataSend);

  delay(60000);

}

Step 2: Upload Your Code

You'll need to update a number of the parameters, as well as add the WiFiCon() function from here (or something similar). Parameters that need to change are the host, the URL, and the data parameters - we'll look at these in the explanation step.

Open the serial monitor in the Arduino IDE. This is so once your code uploads, we can see the messages coming over serial from the ESP.

Use a setup like the one laid out here to upload your code. Once the code is done uploading, you should immediately start to see some messages in the serial monitor. If you don't, power down the ESP, turn the switch off of flash mode, and repower the ESP.

After the code is uploaded, a simple wiring like the one at the top of this instructable is all you need to actually run the ESP.

Step 3: Explanation

What's that you say? "You just copied this whole instructable from the GET method post!"

Hold on, hold on.. there's differences! I promise!

Let's first talk about what's the same: the data string get's built exactly the same. You have the variable name that the server needs, followed by "=", followed by the data. If there's more than one piece of data, throw an "&" in, and repeat:

name=Jimmy&id=52

So, what's different? With GET, we concatenated this variable string into the URL, and just sent it on it's way.

With POST, we add it in as another line towards the bottom of the headers we are sending. On top of this, the server needs to know how long the expected character string is for the variables - so you'll see a "length" header sent as well.

Step 4: Which Method Is Best?

Why use POST over GET? Well, GET is more limited in size than POST. When using an ESP, you aren't normally sending crazy amounts of data, so this limitation isn't usually a deal breaker. Most of the time, the decision to use POST or GET is going to depend on the server that you are sending the data to. If you own the server and the write the data collection page yourself, it's down to your personal preference. However, if you are just starting out, you are probably using some type of data service to collect your data - so in that case, you will use what they dictate.

For an example of when I use POST: I have a data logging project that works in an "off-grid" setting that is powered by batteries and solar power. My ESP unit consumes little power compared to my modem/router, so it runs all the time. But the modem/router get turned off when power levels start dropping.

When this happens, I get a built up batch of data that needs to ship to my web server. I never know how long this will be, so I concatenate all the data into a POST variable with carriage and line returns ("/r/n"), and ship it.

When the server gets the data, it takes it all in as one variable, and then parses it line by line and breaks it into any sub-variables it needs - I let the server do the hard work, and let the little ESP just ship it bulk.

Most of the time, you will probably use GET. But hopefully now you have a better understanding of both methods!