Forming HTTP POST request on Arduino w/ ESP8266 Wifi

I am prototyping a piece of my project that will send temperature data to a database on a remote website. For this I have setup a MySQL database and website on the free hosting service 000webhost. I have written a very simple server side PHP script that should add a row of temp data to the database via a HTTP POST.

I have tested all the web server side functionality and confirmed that it is working just fine by using requestmaker.com to "manually" send the POST request.

But every attempt I have made to update the table via my Arduino code has failed with a 400 Bad Request response from the server. The response doesn't really give me a lot of details to go on so my troubleshooting so far has been just pretty much random trial and error in forming the POST request and I am getting nowhere.

If anyone can spot an obvious problem in my code, or suggest some better ways to go about troubleshooting I would greatly appreciate it.

Here is the Arduino sketch:

#include "SoftwareSerial.h"
#include "Arduino.h"

//connection info for WiFi router
String ssid = "my_SSID";
String password = "my_password";

//create SoftSerial object for communication with ESP8266
SoftwareSerial esp(2, 3); // RX, TX

String data; //data for the POST request
String server = "rksiii.000webhostapp.com"; // www.example.com
String uri = "add.php"; //server side script to call

//reset the esp8266 module
void reset() {
	esp.println("AT+RST");
	delay(3000);

	if (esp.find("OK"))
		Serial.println("Module Reset");
}

//connect to your wifi network
void connectWifi() {
	String cmd = "AT+CWJAP=\"" + ssid + "\",\"" + password + "\"";
	esp.println(cmd);
	delay(4000);

	if (esp.find("OK")) {
		Serial.println("Connected!");
	}
	else {
		connectWifi();
		Serial.println("Cannot connect to wifi");
	}
}

void setup() {
	esp.begin(9600); //start SoftSerial for ESP comms
	Serial.begin(9600); //start regular serial for PC -> Arduino comms

	reset(); //call the ESP reset function
	connectWifi(); //call the ESP connection function
}

void loop() {
	int temp1 = 73;
	int temp2 = 231;
	int temp3 = 12;

	data = String("temp1=");
	data = data + temp1 + "&temp2=" + temp2 + "&temp3=" + temp3;

	httppost();
	delay(7000);
}

void httppost() {
	esp.println("AT+CIPSTART=\"TCP\",\"" + server + "\",80"); //start a TCP connection.

	if (esp.find("OK")) {
		Serial.println("TCP connection ready");
	}
	delay(1000);

	String postRequest = String("POST ");
	postRequest = postRequest + uri + " HTTP/1.1\r\n" +
	"Host: " + server + "\r\n" +
	"Accept: *" + "/" + "*\r\n" +
	"Content-Length: " + data.length() + "\r\n" +
	"Content-Type: application/x-www-form-urlencoded\r\n" +
	"\r\n" + data;

	Serial.println("Post Request text: "); //see what the fully built POST request looks like
	Serial.println(postRequest);

	String sendCmd = "AT+CIPSEND="; //determine the number of caracters to be sent.
	esp.print(sendCmd);
	esp.println(postRequest.length());
	delay(500);

	if(esp.find(">")) {
		Serial.println("Sending..");
		esp.print(postRequest);

		Serial.println("Data to send: ");
		Serial.println(data);
		Serial.print("Data length: ");
		Serial.println(data.length());
		Serial.print("Request length: ");
		Serial.println(postRequest.length());
		Serial.println("Request Sent:");
		Serial.println(postRequest);

		if( esp.find("SEND OK")) {
			Serial.println("Packet sent");
			while (esp.available()) {
				String tmpResp = esp.readString();
				Serial.println(tmpResp);
			}

			// close the connection
			esp.println("AT+CIPCLOSE");
		}
	}
}

And here is the actual text response I get back from the server as it shows up in the serial monitor:

+IPD,424:HTTP/1.1 400 Bad Requeerver: awex
X-Xss-Protection: 1; mode=block
X-Content-Type-Options: nosniff
X-Request-ID: 698d62d8b91ac68f1257d93fe0677488

<html>
<head><title>400 Bad Request</title></head>
<body bgcolor="white">
<center><h1>400 Bad Request</h1></center>
<hr><center>nginx</center>
</body>
</html>

Looking forward to any help I can get or new directions to try. Thank you.

I have written a very simple server side PHP script that should add a row of temp data to the database via a HTTP POST.

It would be simpler to use GET. Why don't you?

Why does connectWiFi() call connectWiFi()?

It would be necessary to see ALL of your serial output.

PaulS:
It would be simpler to use GET. Why don't you?

You have just uncovered how ignorant I am about HTTP. :slight_smile:
My sketch is inspired by and in some cases flat out stolen from several other Arduino web projects I found on the Internet. Every other example I found used POST to update a remote database and it sort of just seemed logical to me that POST would be used for sending information while GET would be used for retrieving it. But I will now start looking into GET and see what it can do for me.

Why does connectWiFi() call connectWiFi()?

Again, some of this is other people's code and until you just drew my attention to it I had not noticed how odd that bit of code is. The intent seems to be to keep looping until a successful connection has been made but the recursive call and some other aspects of that function now jump out at me as odd. Nevertheless, I do not think that function is the source of my specific problem.

It would be necessary to see ALL of your serial output.

If exploring GET does not provide some answers for me I will post the full output when I am next at my workbench.

Thank you for the reply and the new avenues to explore.

I can't see anything obviously wrong.

I'd be inclined to remove the data and send a zero-length form: one with no values in it. If that goes through, then there's a prblem with the values. If that doesn't, something else.

"POST add.php HTTP/1.1" + "\r\n" +
"Host: rksiii.000webhostapp.com" + "\r\n" +
"Accept: */**" + "\r\n" +
"Content-Length: 0" + "\r\n" + 
"Content-Type: application/x-www-form-urlencoded" + "\r\n" +
"\r\n";

If that works - there a problem with the content. If not,

1 - try specifying /add.php instead of just add.php
2 - try sending a simple get request to a page you know is not there, and see if you get a 404 like you should do

"GET /foo HTTP/1.1" + "\r\n" +
"Host: rksiii.000webhostapp.com" + "\r\n" +
"\r\n";

If that works, see if sending a post request to a page you know is not there gets a 404

If it doesn't, then maybe the stuff you are doing to make the ESP8266 isn't working as it should. Or maybe the server doesn't like your Host string.

You have to try stuff out. To learn about HTTP, google "rfc2616".

Hi, have you solved this problem? It would be helpful to me. I have a similar problem

Cheers

hello friend,
did you solved the issue? are you able to successfully send the data from esp to URL? I am working on the same and couldnt achieve it.

Kindly help and share the code pls.
I am using arduino + esp826601 module. I want to post the data to the iis hoted server in my office network locally. We made the page to receive the data. Manually its happening and through the hardware it is not.

Pls help me.

Pls help me.

The problem is on line 45456542155125 of the code you didn't post. So says my crystal ball, and it is ALWAYS right. Well, it was until I dropped it...

Hi

I am trying the code which is posted here.

I am not getting any response after the data which is posted.

can you post your recent updated code in which you succeeded sending?

If so I owe you a huge favor.

thanks in advance.

whoever has the finished code please
can you post your recent updated code in which you succeeded sending?
If so I owe you a huge favor.

thanks in advance.