Arduino + ESP8266, sending Post over Serial using AT Commands

Hi There,

I would like to be able to post (POST Method) a JSON object to a Web API which would finally parse and store it over the database on a server.

The Code that I am using is this:

#include "DHT.h"

#define DHTPIN 7 
#define DHTTYPE DHT11 
DHT dht(DHTPIN, DHTTYPE);

void setup() {
  Serial.begin(115200);
  Serial3.begin(115200); //ESP Connected over Serial3
  Serial3.println("AT+RST");
  delay(500);
  Serial.println("AT+CIPMUX=1");
  Serial3.println("AT+CIPMUX=1");
  delay(2000);
  Serial.println("AT+CIPSERVER=1,5000");
  Serial3.println("AT+CIPSERVER=1,5000");
  delay(2000);
  Serial.println("AT+CIPSTO=3600");
  Serial3.println("AT+CIPSTO=3600");
  delay(2000);

  Serial3.println("AT+CWMODE=3");
  delay(5000);
  Serial .println("Connect to WIFI");
  Serial3.println("AT+CWJAP=\"networkname\",\"password\"");
  delay(2000);

  dht.begin();
}

void loop()
{

  float h = dht.readHumidity();
  float t = dht.readTemperature();
  float f = dht.readTemperature(true);
  if (isnan(h) || isnan(t) || isnan(f)) {
    Serial.println("Failed to read from DHT sensor!");
    return;
  }
  float hif = dht.computeHeatIndex(f, h);
  float hic = dht.computeHeatIndex(t, h, false);

    String PostMessage = "";
    PostMessage += "{\"Humidity\":";
    PostMessage += h;
    PostMessage += ",\"Celcius\":";
    PostMessage += t;
    PostMessage += ",\"Fahrenheit\":";
    PostMessage += f;
    PostMessage += ",\"HeatIndexC\":";
    PostMessage += hic;
    PostMessage += ",\"HeatIndexF\":";
    PostMessage += hif;
    PostMessage += "}";

    unsigned int l=PostMessage.length();
    Serial3.print("AT+CIPSEND=0,");
    Serial3.println(l+2);

    Serial3.println("POST http://mysite.net/api/apicontrollername/ HTTP/1.1");
    Serial3.println("Accept:application/json, text/plain, */*");
    Serial3.println("Accept-Language:en-US,en;q=0.8,hi;q=0.6");
    Serial3.println("Connection:keep-alive");
    Serial3.println("Content-Length:" + l);
    Serial3.println("Content-Type:application/json;charset=UTF-8");
    Serial3.println("Host:mysite.net");
    Serial3.println(PostMessage);
    Serial3.println("AT+CIPCLOSE=0"); 
    delay(30000);
}

I'm not sure if I'm doing it correctly, but I cannot see the details getting stored to the database by the Web API, though I am sure that the WebAPI is not buggy, as I am able to send data using AJAX on a web browser. Also the ESP is getting connected to the Router as I can see it getting assigned a IP address on the router.

Can anyone tell me where am I doing it wrong, also, is there any way I can debug the HTTP request sent by ESP?

between headers and body of the POST request should by an empty line.

Hey Juraj,

I added a line in between the header and the body, and now the code looks like this:

Serial3.println("POST http://mysite.net/api/apicontroller/ HTTP/1.1");
    Serial3.println("Accept:application/json, text/plain, */*");
    Serial3.println("Accept-Language:en-US,en;q=0.8,hi;q=0.6");
    Serial3.println("Connection:keep-alive");
    Serial3.println("Content-Length:" + l);
    Serial3.println("Content-Type:application/json;charset=UTF-8");
    Serial3.println("Host:mysite.net");
    Serial3.println("\n"); // Line added here
    Serial3.println(PostMessage);
    Serial3.println("AT+CIPCLOSE=0");

But it still does not work.

you added 2 lines

and try

  Serial3.print("Content-Length: ");
  Serial3.println(l);

did you try a GET request example?

Hi,

Just figured that the issue is probably related to the incorrect JSON object or POST body.

I tried calling the PUT method and that worked, so now my code is something like this, which I need to change to POST or atleast be able to accept JSON object:

    unsigned int l=PostMessage.length();
    Serial3.println("AT+CIPSTART=\"TCP\",\"mysite.net\",80");
    delay(5000);
    Serial.println(Serial3.readString());
    Serial3.print("AT+CIPSEND=");
    Serial3.println(l);
    Serial.println(Serial3.readString());
    Serial3.println("PUT /api/apicontroller HTTP/1.1");//Need this to change to POST or atleast allow sending JSON object
    Serial3.println("Host:mysite.net");
    Serial3.print("Content-Length:");
    Serial3.println(l);
    Serial.println(Serial3.readString());
    Serial3.println();
    Serial3.println(PostMessage);//Probably an issue with this one
    delay(10000);

The structure of the JSON that is being sent is this:

String PostMessage =
 "{\"Humidity\":29.09,\"Celcius\":33.36,\"Fahrenheit\":92.05,\"HeatIndexC\":32.50,\"HeatIndexF\":89.61}"

The PUT method is currently saving random data from the server (infact hardcoded) and not taking data from ESP's HTTP request.

Hey cyberpks,

I'm also trying to send data through ESP8266 with HTTP POST method and in JSON format and tried your above code but failed.

Can you please update the final code which worked for you.

Thanks :slight_smile: