Storing Arduino sensor data on a (local) server using POST or GET and PHP and presenting it in a graph

In an earlier article, I described how to store your sensor data in GoogleSheet I also described how to make graphical presentations of data with the Highcharts library (much based on an article of Sarah&Rui Santos of Randomnerdstutorials, but extended by me).

That method was especially suited for an ESP8266 or ESP32 as they can hold and process a lot of data in memory.

So what if we use a processor with less memory, say an Arduino with an ethernet connector? Well, there are some possibilities for that too. It involves storing data on a (local) server. Yes that could be in say MySQL/MariaDB, but for much purposes a simple CSV file is enough. We will do everything in simple PHP with the help of the jpGraph library

So for now I will focus on the serverside: how to  store the data and how to show it nicely in a graph. In a subsequent article I will talk about the client side: the Arduino with an (old) ENC28J60 module.

For now let’s assume we have a local server, most likely a Raspberry with PHP and Apache installed.

The directory where we will store the PHP files as well as the data, is the ‘root’ website directory which is /var/www/html

POST-ing data
<?php 
define("LOG_FILE", "./data.csv"); 
$temp=$_POST['temp'];
$temp2=$_POST['temp2']; 
$file_handler = fopen(LOG_FILE, "a+") or die("Unable to open file");
 #fwrite($file_handler, time() . "," . $temp . "\n");
 fwrite($file_handler, time() . "," . $temp . "," . $temp2 . "\n");
 fflush($file_handler);
 echo "OK";
 ?>

Let’s call the script “POST-data.php”

GET-ing data
<?php

define("PASSWORD", "raspianTemp");
define("LOG_FILE", "./data.csv");

if(!isset($_GET["temp"])) die("NO - no value present");
if(!isset($_GET["pwd"])) die("NO - no password present");

$pwd = $_GET["pwd"];
if($pwd != PASSWORD) die("NO - wrong password");

$temp = $_GET["temp"];
if(!is_numeric($temp)) die("NO - not a number");
echo $temp;

$temp2= $_GET["temp2"];
#if(!is_numeric($temp)) die("NO - not a number");

$file_handler = fopen(LOG_FILE, "a+") or die("Unable to open file");
#fwrite($file_handler, time() . "," . $temp . "\n");
fwrite($file_handler, time() . "," . $temp . "," . $temp2 . "\n");
fflush($file_handler);
echo "OK";

?>

The GET script looks a bit more complicated than the POST script, but that’s simply because it has more checks: on a password and the entered values. That is because the GET method can also be used through an URLsuch as:

http://192.168.xx.yyy/saveTemp.php?pwd=raspianTemp&temp=12.5&temp2=9
But you can opt to leave them out or use them in the POST method as well.

Let’s call this script “GET-data.php”

Oh, darn. ‘privileges’
set the /var/www/html directory to ‘775’ (with chmod) and make sure the apache user is owner of the data.csv file. If  you let the php scripts create the file, then the apache user is the owner. If you happen to have created the file yrself, need to change ownership with:
sudo chown www-data data.csv

jpGraph

jpGraph is a graphic library meant for php. It can be downloaded here. for now we will install it in the /var/www/html folder.
Download the tar file and put it in the /var/www/html folder.
Currently jpgraph-4.2.10.tar.gz is the latest version.
‘Install’ it by unpacking it and then rename the created directory as follows:

tar xzf jpgraph-4.2.10.tar.gz
sudo mv jpgraph-4.2.10 jpgraph

 

Once that is all done we can show the data

Showing the data
<?php

define("LOG_FILE", "./data.csv");
require_once('./jpgraph/src/jpgraph.php');
require_once('./jpgraph/src/jpgraph_line.php');

$times = array();
$values1 = array();
$values2=array();
$file_lines = file(LOG_FILE, FILE_IGNORE_NEW_LINES|FILE_SKIP_EMPTY_LINES);

//Get the data
foreach($file_lines as $line_num => $line_value) {
$line_elements = explode(",", $line_value);
#$times[] = date("H:i:s", $line_elements[0]);
$times[] = date("d-m-y H:i", $line_elements[0]);
$values1[] = $line_elements[1];
$values2[] = $line_elements[2];
}
// setup the graph
$graph = new Graph(1100, 550);
$graph->SetFrame(false);
#$graph->SetScale('intint');
$graph->SetScale('textlin');
$graph->SetShadow($aShowShadow=true,$aShadowWidth=5,$aShadowColor=array(102,102,102));
$graph->ygrid->SetFill(true,'#EFEFEF@0.5','#BBCCFF@0.5');
$graph->ygrid->Show();
$graph->xgrid->Show();

#$graph->img->SetAntiAliasing(false);
//li,re,bo/on
$graph->SetMargin(50,30,36,90);
$graph->SetMarginColor('white');

//Setup Title and axis
$graph->title->Set("Temperatures");
$graph->xaxis->SetLabelAngle('50');
$graph->xaxis->SetTickLabels($times);
$graph->xaxis->SetLabelSide(SIDE_BOTTOM);

$graph->yaxis->scale->SetAutoMin(0);
$graph->yaxis->title->Set("&deg;C");

$graph->ygrid->SetFill($aFlg=true, $aColor1='white', $aColor2='gray9');
// Create the first line
$lineplot = new LinePlot($values1);
$lineplot->SetLegend('Living Room');
#https://jpgraph.net/features/src/show-example.php?target=new_line1.php
$graph->Add($lineplot);
$lineplot->SetColor("green");

// Create the second line
$p2 = new LinePlot($values2);
$graph->Add($p2);
$p2->SetColor("#FF1493");
$p2->SetLegend('Bedroom');

$graph->legend->SetFrameWeight(1);
// Finally send the graph to the browser
$graph->Stroke();
?>

The above methods can come in handy for every kind of data generated by a data monitoring system, but as said, I wanted to make some arduino/ENC28J60/EtherCard lib examples. The POST method was fairly simple (done) but the GET method caused some headaches.

Currently, if you have stored a lot of data, the graph becomes too condensed. That can be remedied by for example only showing the last 10 or 20 lines. I will see if i can add that.

(The idea to use jGraph came from Luca Dentella, who has done much work with the ENC26J60)

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.