How to post data to my webpage via POST requests?


#1

I accidentally deleted my previous post while editing his :expressionless: (just the way things are going for me now)

SO a quick rundown. I’m a complete beginner to HTML and PHP, I’m trying to post data from my Arduino over WiFi to a table on my webpage. I’m making a POST request, as you can see in my Ardunio code, to my index.php. My understanding, which is not much, is that the php code I slipped into index.php should respond to the request and store the value of “Temperature” to a variable and then echo it to the webpage at the position where I slipped in the php code.

I wanted to post data to a mySQL table and then take the data from there to post onto my webpage, but I had no luck. At this stage I just want to be able to do this basic process.

Here is a snapshot of my webpage and the table I’m trying to poste data to:
Capture
.
.
.
EDIT
Full Arduino code:

/*
 WiFiEsp example: WebClient

 This sketch connects to google website using an ESP8266 module to
 perform a simple web search.

 For more details see: http://yaab-arduino.blogspot.com/p/wifiesp-example-client.html
*/

#include "WiFiEsp.h"



char ssid[] = "vodafone-43C5";  // wireless network name
char pass[] = "*****"; // wireless password
int status = WL_IDLE_STATUS;

char server[] = "markrigz.000webhostapp.com";

// This is the data that will be passed into your POST and matches your mysql column
int yourarduinodata = 999;
String yourdatacolumn = "Temperature=";
String yourdata;

// Initialize the Ethernet client object
WiFiEspClient client;

void setup()
{
  // initialize serial for debugging
  Serial.begin(115200);
  // initialize serial for ESP module
  Serial1.begin(9600);
  // initialize ESP module
  WiFi.init(&Serial1);

  // check for the presence of the shield
  if (WiFi.status() == WL_NO_SHIELD) {
    Serial.println("WiFi shield not present");
    // don't continue
    while (true);
  }

  // attempt to connect to WiFi network
  while ( status != WL_CONNECTED) {
    Serial.print("Attempting to connect to WPA SSID: ");
    Serial.println(ssid);
    // Connect to WPA/WPA2 network
    status = WiFi.begin(ssid, pass);
  }

  // you're connected now, so print out the data
  Serial.println("You're connected to the network");
  
  printWifiStatus();

  Serial.println();
  Serial.println("Starting connection to server...");

  
}

void loop()
{
postData();
delay(2000);
  
}


void printWifiStatus()
{
  // print the SSID of the network you're attached to
  Serial.print("SSID: ");
  Serial.println(WiFi.SSID());

  // print your WiFi shield's IP address
  IPAddress ip = WiFi.localIP();
  Serial.print("IP Address: ");
  Serial.println(ip);

  // print the received signal strength
  long rssi = WiFi.RSSI();
  Serial.print("Signal strength (RSSI):");
  Serial.print(rssi);
  Serial.println(" dBm");
}


void postData() {
  // Combine yourdatacolumn header (yourdata=) with the data recorded from your arduino
  // (yourarduinodata) and package them into the String yourdata which is what will be
  // sent in your POST request
  yourdata = yourdatacolumn + yourarduinodata;

  // If there's a successful connection, send the HTTP POST request
  if (client.connect(server, 80)) 
    {
      Serial.println("connecting...");
  
      // EDIT: The POST 'URL' to the location of your insert_mysql.php on your web-host
      client.println("POST /index.php HTTP/1.1");
  
      // EDIT: 'Host' to match your domain
      client.println("Host: markrigz.000webhostapp.com");
      client.println("User-Agent: Arduino/1.0");
      client.println("Connection: close");
      client.println("Content-Type: application/x-www-form-urlencoded; charset=UTF-8");
      client.print("Content-Length: ");
      client.println(yourdata.length());
      client.println();
      client.println(yourdata); 
      Serial.println("Done!");
      Serial.println("Disconnecting from server...");
      client.stop();
    } 
  else 
    {
      // If you couldn't make a connection:
      Serial.println("Connection failed");
      Serial.println("Disconnecting.");
      client.stop();
    }

    
}

And here is my index.php:

<html>
<head>
<title>AQWAH Dashboard</title>
</head>
<body>

<h1 style="text-align: center;"><span style="background-color: #33cccc;">AQ</span>WAH</h1>
<hr /><hr />
<h3 style="text-align: center;">LATEST READINGS:  <?php echo date("d-m-Y h:i:sa"); ?></h3>
<table style="width: 299.5px; border-color: blue; background-color: #33cccc; margin-left: auto; margin-right: auto;" border="10" cellspacing="10" cellpadding="10">
<tbody>
<tr style="height: 20.25px;">
<td style="width: 104px; text-align: center; height: 20.25px;"><strong>Temperature:</strong></td>
<td style="width: 197.5px; height: 20.25px;">
<?php 
	    $Temp=$POST['Temperature'];
        echo $Temp;  
 ?>  
</td>
</tr>
<tr style="height: 36px;">
<td style="width: 104px; text-align: center; height: 36px;"><strong>Heater Status:</strong></td>
<td style="width: 197.5px; height: 36px;">
<?php       
      $Temp=$_POST['Temperature'];
      echo "Here it is ". $Temp;
       
?>  

</td>
</tr>
<tr style="height: 18px;">
<td style="width: 104px; text-align: center; height: 18px;"><strong>Pump Status:</strong></td>
<td style="width: 197.5px; height: 18px;">&nbsp;</td>
</tr>
<tr style="height: 18px;">
<td style="width: 104px; text-align: center; height: 18px;"><strong>Messages:</strong></td>
<td style="text-align: left; width: 197.5px; height: 18px;">&nbsp;</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<hr /><hr />
<h3 style="text-align: center;">&nbsp;</h3>
</body>
</html>

#2

Can you expand on that? As far as I know, MySQL works perfectly well on the free tier. What do you mean by “uploading data to MySQL”?

Your current code looks OK, but you’ve not yet said what does happen. What do you get in the HTTP response?

Wouldn’t it be better to have a static page to start off with, just to check that your client code is actually sending a POST request correctly first?

No, you have it correct - the client side cannot read the document root - that is only visible to the web server side.

On that theme, please read this.


#3

Thanks for your response, halfer, I will try to give all the information you require, but please be patient with me as my understanding of these things are very very basic…at best.

Can you expand on that? As far as I know, MySQL works perfectly well on the free tier. What do you mean by “uploading data to MySQL”?

I’m trying to post data from my Arduino to a php file on here which is supposed to add that data to one of my mySQL tables. When I looked up information about it, I saw a few people mention that remotely connecting to 000webhost’s mySQL is only for Premium users. I took this to mean that I couldn’t post data from Arduino, instead only add data manually on their phpMyAdmin page.

Your current code looks OK, but you’ve not yet said what does happen. What do you get in the HTTP response?

I haven’t put code in place on my Arduino to read the responses. I’m not eaxactly sure on how to do it and to be honest, was just concerned about adding more trouble.

Wouldn’t it be better to have a static page to start off with, just to check that your client code is actually sending a POST request correctly first?

I’m not exactly sure what you mean by this. But I did find some useful php code that read in the request and appended it to a html file using a “file_put_contents” method. This worked, but it just printed the data to an empty html page, whereas I want to add it to a table on my index page.

I’m sorry about the image of code. If you require any more information, I’ll do my best to serve it up.

Thanks again!


#4

Your code samples seem to be quote blocks with occasionally embedded code blocks. As you can see, the first block is inconsistently formatted. I suggest editing your first post, and then deleting those code blocks and inserting them again (once something is quote formatted, removing the > devices results in the whole lot being re-paragraphed.

To format code, paste it here, select the whole block, and click the code icon (</>). Then make sure the block has a preceding blank line. That’s all there is to it, so would you fix? I will answer your questions once that is done satisfactorily. Thanks.


#5

Hi halfer, I’ve just made those corrections to the format.


#6

Righto. The original statement is correct, and you misinterpreted it.

MySQL is a database system, and is connected to over a network. In most cases, you connect to the database using a program (e.g. a web app written in PHP). The free tier of 000webhost requires you to connect to MySQL from a 000webhost server, which is what PHP is doing here. This is sometimes known as connecting “locally”.

However, more complex arrangements are possible. If you wanted to use a MySQL client on your laptop to run queries directly on the database, this is not possible because remotely connecting to 000webhost’s MySQL is only for Premium users. Equally, if you wanted to run your PHP application on Digital Ocean and still use your 000webhost database, then you cannot, because remotely connecting to 000webhost’s MySQL is only for Premium users.

Your use case is fine, because the Arduino is not trying to connect remotely to MySQL. It is connecting to your web app remotely (that’s the point of them!) and then the web app connects locally to MySQL.


#7

To move forward, you need to debug your POST operation. I wondered if you were trying to retrieve some information, but you have answered that question - you are trying to send some. In that case, try debugging it from the 000webhost side.

However, I am looking at your PHP, and I cannot see anything that would write to the database. In fact, I think you have misunderstood whatever tutorial you have read - this code looks like it was made to show values from a database.

I would delete your PHP code for now, and replace it with something to see if you are receiving the data you expect:

<?php
file_put_contents('debug.log', print_r($_POST, true), FILE_APPEND);

Then try your post operation - it should create the named file containing a dump of the data you’ve supplied.


#8

Right, that’s good to know about mySQL; your explanation was excellent!

I have php files that are supposed to add data to mySQL tables, but I couldn’t get it to work…

However, I am looking at your PHP, and I cannot see anything that would write to the database. In fact, I think you have misunderstood whatever tutorial you have read - this code looks like it was made to show values from a database.

…but, the php I posted here - the lines inserted into my index.php - were, to my understanding, written to get data from the POST requests I send from my Arduino and then print them to my webpage. That’s what I want to accomplish now; posting data to my webpage without using mySQL. Once I get that working, then I’ll move onto the mySQL aspect.

So as far as sending data from my Arduino to my index.php, which will then post that data to the table on my webpage, where am I going wrong?

I can’t seem to get onto the File Manager, it has been ‘connecting’ for the last hour. But here is the php code I mentioned at the top, the one I used when I was trying to upload data to mySQL:

<?php

foreach ($_REQUEST as $key => $value)
{
	if ($key == "yourdata") {
		$yourdata = $value;
	}
}

// EDIT: Your mysql database account information
$username = "id5081165_root";
$password = "****";
$database = "id5081165_aqwah";
$tablename = "test";
$localhost = "localhost";

// Check Connection to Database
if (mysql_connect($localhost, $username, $password))
  {
  	@mysql_select_db($database) or die ("Unable to select database");

    // Next two lines will write into your table 'test' with 'yourdata' value from the arduino and will timestamp that data using 'now()'
    $query = "INSERT INTO $tablename VALUES ($yourdata,now())";
  	$result = mysql_query($query);
  } else {
  	echo('Unable to connect to database.');
  }

?>

As soon as I can get back into the File Manager, I will try what you suggested regarding debugging.

Thanks again!


#9

Yes, I see what you intend to happen, and it does not work like that. Executing a post operation from the Arduino will make your post data available to PHP on the 000webhost server, it will render the page, and send it back to the caller - the Arduino. Since you are not inspecting the result in the Arduino code, the HTML result is thrown away.

When you view a web page, it is not saved on the server, which is what I think you are hoping. You need to save the database values to a database server, since your client is a machine, not a human. You may also wish to send a machine-readable response back so the Arduino can determine if the remote operation was successful.

So, you need to save the data first. You don’t have to use MySQL - you can use a flat file, a structured file, SQLite, but you need to save it somehow. Debugging next? :slightly_smiling_face:


#10

These methods are no longer available in PHP, starting from version 7.0. You need PDO or MySQLi.

I wonder, would it be worth doing some good MySQL tutorials first? You may find that your progress is faster in the long run if you get some basics under your belt.


#11

Hmmm, still trying to get to grips with how data is stored and passed around. That php file I mentioned earlier, the one that appended my POST data to a html file, I’m wondering how that can’t just post that data to my webpage instead? Furthermore, instead of writing it to a blank html, why can’t I keep writing it to that particular row on my webpage table? So, in essence, get the arduino to keep sending the data every minute, let’s say, and I can have some code in my html to make my webpage refresh every minute, too.

I know this must be exasperating for you; I can be very slow to grasp these things, I just need that one ‘Aha!’ moment and everything will make sense, so I appreciate your patience.

I did a very brief PHP and MySQL tutorial over the weekend and thought I had a useful handle on things, but going back and forth between all these videos and forums, then piecing together all the different code has me all fumbled. I would delve into it more, as I would definitely reap the benefits of it, but I need this done before the weekend. That’s why I assumed it would be quite simple to post data straight to the webpage on a regular basis, without any need of the MySQL side of things.

I still can’t make any changes or try the debugging php, as the page still refuses to load:
Capture

Again, I’m really appreciative of your help and knowledge with this, if you can shed any more light over my confusion while I wait for this page to load, I would be very grateful.


#12

Well, you’re using deprecated/removed functions, you might be open to SQL injection vulnerabilities, and there’s no check to ensure the caller is your Arduino. That should just about cover it :smiley_cat:

Do you mean your “AQWAH Dashboard”? It didn’t do any such thing. As I said before, the 000webhost web server runs this code, runs the PHP inside it, mixes it with the HTML, sends it back to the Arduino, and the Arduino throws it away. It is not saved anywhere.

That’s what worries me. If volunteers have to help more frequently based on your deadline, then they may stop helping. I post regularly to Stack Overflow, and we have something of a culture change there, which I bring to every help fora I am active in. It encourages me to encourage others to self-study as much as possible, and reminds me that my help can only get folks so far, if they want to be able to understand what they are building.

Your project is not trivial, unfortunately!

Yep, it doesn’t work that way.

I would say again that my file_put_contents() script is your next best bet to debugging this. Make sure your web page is actually getting the data. A storage script is not all that hard to build - but you need to ensure your Arduino is actually making a POST op in the right format first. There really is no way around that, so I advise you to do this first.

If you are struggling with the file uploader, use an FTP program instead - much more reliable!


#13

Do you mean your “AQWAH Dashboard”? It didn’t do any such thing. As I said before, the 000webhost web server runs this code, runs the PHP inside it, mixes it with the HTML, sends it back to the Arduino, and the Arduino throws it away. It is not saved anywhere.

No sorry, not the Dashboard, I meant it appended it onto a html file. So when you went to the URL of that html in you browser, you would see the text. But I know what you mean now anyway, in regards to why I can’t use this approach.

That’s what worries me. If volunteers have to help more frequently based on your deadline, then they may stop helping. I post regularly to Stack Overflow, and we have something of a culture change there, which I bring to every help fora I am active in. It encourages me to encourage others to self-study as much as possible, and reminds me that my help can only get folks so far, if they want to be able to understand what they are building.

I can understand that. Feed a man a fish…
I actually enjoyed learning about php and MySQL, and will definitely return to it once the pressure of my current situation is passed. I would like to get a solid understanding of these technologies and make use it some day. But sometimes you’re in a tricky spot and need any help you can get. Of which you have given plenty.

I will try an FTP application instead and see how I get on. You’ll see my confused words again soon, no doubt, after I try this debugging approach.

Thanks!


#14

Good idea. Use this one; it works on all platforms, and it’s free.


#15

Well, I’ve done the debugging POST and here are the results:

Array
(
    [Temperature] => 2
)
Array
(
    [Temperature] => 3
)
Array
(
    [Temperature] => 4
)
Array
(
    [Temperature] => 5
)

Which seems right, since I have set the temperature value (1) on the arduino to increment by 1 every 2 seconds, so when I go back to the debug.log after a few seconds, there will be a new bit of text showing this.

Now, in my desperation, I’ve somewhat turned to the dark side. I have got my webpage working, but have done so in a shady way:

<?php



//date_default_timezone_set("America/Los_Angeles");
//$TimeStamp = "The current time is " . date("h:i:sa");
//file_put_contents('dataDisplayer.html', $TimeStamp, FILE_APPEND);

$var1 = $_REQUEST['Temperature'];

   if( $_REQUEST["Temperature"] ) 
   {
    echo " <p> ".$var1. "Degrees Celsius</p>";
   }

$WriteMyRequest=
"<html>
<head>
<title>AQWAH Dashboard</title>
</head>
<body>

<h1 style=\"text-align: center;\"><span style=\"background-color: #33cccc;\">AQ</span>WAH</h1>
<hr /><hr />
<h3 style=\"text-align: center;\">LATEST READINGS:</h3>
<table style=\"width: 299.5px; border-color: blue; background-color: #33cccc; margin-left: auto; margin-right: auto;\" border=\"10\" cellspacing=\"10\" cellpadding=\"10\">
<tbody>
<tr style=\"height: 20.25px;\">
<td style=\"width: 104px; text-align: center; height: 20.25px;\"><strong>Temperature:</strong></td>
<td style=\"width: 197.5px; height: 20.25px;\">".$var1."
	
</td>
</tr>
<tr style=\"height: 36px;\">
<td style=\"width: 104px; text-align: center; height: 36px;\"><strong>Heater Status:</strong></td>
<td style=\"width: 197.5px; height: 36px;\">
  

</td>
</tr>
<tr style=\"height: 18px;\">
<td style=\"width: 104px; text-align: center; height: 18px;\"><strong>Pump Status:</strong></td>
<td style=\"width: 197.5px; height: 18px;\">&nbsp;</td>
</tr>
<tr style=\"height: 18px;\">
<td style=\"width: 104px; text-align: center; height: 18px;\"><strong>Messages:</strong></td>
<td style=\"text-align: left; width: 197.5px; height: 18px;\">&nbsp;</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<hr /><hr />
<h3 style=\"text-align: center;\">&nbsp;</h3>
</body>
</html>";

file_put_contents('index.html', $WriteMyRequest);

?>

I will tweak this further to get it to do what I want. I understand this is simply bad practice and presents a security risk, as you mentioned before. But in my desperation, I will settle for this as a back-up plan come this weekend, if all else fails, as I only have to do a once off demonstration. I would still like to plough on and learn how to do this the proper way; using MySQL.

I would assume that this debug.log demonstrates that the arduino is making a POST request in the right format?


#16

Yes, indeed. Progress!

OK, yep, that will work. Save an entire copy of your folder (or, better still, commit everything in your version control, if you are using that). Do not change anything until you have done so.

Do you only need to show the current readings, and not the historical ones? If so, a database is probably a bit overblown for your use case. You could just write values like so:

// This will overwrite every time
file_put_contents('data.json', json_encode($_POST));

and then read them when you want to render a web page, like so:

$data = json_decode(file_get_contents('data.json'), true);

(JSON is a way of converting structured data e.g. an array into a string).

Your approach of writing the whole HTML file in the POST operation is unnecessary - just do the data recording in your Arduino call, and then read the data from file when you are rendering the HTML document.


#17

This is very helpful!

Do you only need to show the current readings, and not the historical ones? If so, a database is probably a bit overblown for your use case.

It’s really down to me. If I get this working smoothly, then I will consider adding a table of old data on my webpage, using the database.

I have tried your suggestion using the json file and it works! Now I’m just wondering how do I post multiple variables from the Arduino?
I’ve tried sending the request to the debug.php but it hasn’t worked.
Here’s how I built the data up on my Arduino:

// This is the data that will be passed into your POST 
int temp = 1;
String heater = "On";
String heaterName = "Heater=";
String tempName = "Temperature=";
String yourdata; 

Then I add it together like this:

yourdata = tempName + temp + "&" + heaterName + heater;

And finally I insert it into my POST command as “yourdata” like usual:

// EDIT: The POST 'URL' to the location of your php on your web-host
      client.println("POST /dataCollector.php HTTP/1.1");
      // EDIT: 'Host' to match your domain
      client.println("Host: markrigz.000webhostapp.com");
      client.println("User-Agent: Arduino/1.0");
      client.println("Connection: close");
      client.println("Content-Type: application/x-www-form-urlencoded; charset=UTF-8");
      client.print("Content-Length: ");
      client.println(yourdata.length());
      client.println();
      client.println(yourdata); 
      Serial.println("Done!");
      Serial.println(yourdata);
      Serial.println("Disconnecting from server...");
      client.stop();

But this hasn’t worked.

Again, this is probably something simple that I am missing.


#18

Hmm, if this had any effect, it might close the connection before the data is sent. I don’t think you need it.

If that doesn’t sort it, see various tips here.

Also, handy tip, try to avoid “doesn’t work” as a problem description. Here’s why.


#19

Hi halfer, I can’t believe I forgot to come back here and thank you for your invaluable help.

I solved my problem and I reached that “Aha!” moment where everything suddenly made sense and I could do what I had planned to, and more.

But anyway, thanks again for your patience and help. I’m very grateful and I apologize for not thanking you sooner. :+1:


#20

@markrigz Let us know if you’ve any other issue :slight_smile: