Arduino visualization

Hi,

I am having massive problems graphing my data, real time.
My data are stored on SQL server.
I have columns in the table 1. TIME_STAMP, 2. Temperature.
I would like to use FLOT to do the graphs or any other that can provide with the same functionality.
Afcourse I would be needing it in AJAX real time data, with the possibility to look at back at temperature in intervals, weeks, months.

Are there any examples of graphing such data and tutorials, because I have searched a lot of google entries and haven't found any that I could use.

Could you please provide me with an similar example (with code), because I am having massive trouble with setting up the basics, I am going to add wayt more sensors in the future for this project.

And no using some other web server than sending the data to my webserver from that is proposterous. I was thinking about Google, but it's the unnecesarry loop that I am trying to avoid. Also using some PC "softwarish" solution or serial is not an option also.

Thanks for your help in advance,
Raimonds

Hi,

Here a simple example for real time data acquisition: https://github.com/vmlenart/Guararduino

Have a look at my EzScrn project. It uses Flotr2

...R

The simplest solutions are to send the data direct to

  1. Bluetooth Graphics Terminal.
    This will show up to three lines of live graph on an Android device. It can receive receive several more data inputs, you just choose which ones to display. Timestamping is not included, or relevant. I also send data to SD with local timestamping for later use.

  2. Excel
    This can be done using older versions of Excel and the PLX-DAQ macro. This essentially turns Excel into a terminal and enables you to use Excel's graph facility live. Anything Excel can do can be done direct from Arduino. No need to send time, timestamping is done by Excel using the PC clock.

  3. Xively et al.
    Sending the data to the Internet of Things has the advantage of giving everybody else a look too. Timestamping is done at their end. With Xively, you can only send data at ten second intervals. Others may be different

In all cases, the code is quite straightforward, only requiring minor additions to what you send to the serial monitor

Those are really lovely Python examples, but I have never ever worked with Python. Ajax/Jquery are a little bit more familiar to me and easier to understand.
I would like the data to be in Jquery/AJAX form, it would be really great if you could provide examples of using those.
Also reading from an SQL database is much easier in my opinion, I just can't workout the graph part because I lack knowledge in this field.

Nick_Pyner I already typed that using another server is not an option for me. The data needs to be on my website in realtime. Not dimensioning the security of such a site and exposing your network to the world.
Also how am I suppoased to run Excel on Raspberry pi webserver :smiley: ? Further more I would than need to extract the data from Excel => webpage and than create a graph there :slight_smile: ?

The subject was visualisation, the second word of my previous was "simplest", I don't recall security being an issue, and whoever knew you're running this on a Raspberry Pi?

It just seemed like you were having a problem because things were more complicated than they need be.

I am sorry nick about the harsh words. I probably didn't explain this clear enough, thanks for you support :).

This is the code I currently have on the displaying side.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
 <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title>Graph of Energy Consumption</title>
    <link href="layout.css" rel="stylesheet" type="text/css"></link>
    <!--[if IE]><script language="javascript" type="text/javascript" src="flot/excanvas.min.js"></script><![endif]-->
    <script language="javascript" type="text/javascript" src="flot/jquery.js"></script>
    <script language="javascript" type="text/javascript" src="flot/jquery.flot.js"></script>
    <script language="javascript" type="text/javascript" src="flot/jquery.flot.selection.js"></script>
 </head>
    <body>
    <h1>Energy</h1>

    <p>Zoom to:
      <button id="nineties">half hour</button>
      <button id="ninetynine">1 hour</button>
      <button id="12hour">12 hours</button>
      <button id="24hour">24 hours</button>
      <button id="48hour">48 hours</button>
      <button id="Refresh">Refresh</button></p>
<?php

include 'connect.php';


$link=Connection();
$result=mysql_query("SELECT * FROM `tempLog` ORDER BY `timeStamp` DESC",$link);

$data = array();
$max = 0;
while($row = mysql_fetch_array($result))
{
  $data[] = array( $row['temperature'], $row['timeStamp'] );
}

?>
    <div id="placeholder" style="width:800px;height:400px;"></div>

    <p></p>
    <div id="overview" style="margin-left:20px;margin-top:20px;width:780px;height:100px"></div>

<script id="source" language="javascript" type="text/javascript">

var data = <?php echo json_encode($data); ?>;

$(function () {

    var options = {
        xaxis: { mode: "time" },
        selection: { mode: "xy" },
    };
    
    var plot = $.plot($("#placeholder"), [ data ], options);
    
    var overview = $.plot($("#overview"), [ data ], {
        series: {
            lines: { show: true, lineWidth: 1 },
            shadowSize: 0
        },
        xaxis: { ticks: [], mode: "time" },
        yaxis: { ticks: [], min: 0, max: 5000 },
        selection: { mode: "xy" }
    });

  $("#placeholder").bind("plotselected", function (event, ranges) {
        // clamp the zooming to prevent eternal zoom
        if (ranges.xaxis.to - ranges.xaxis.from < 0.00001)
            ranges.xaxis.to = ranges.xaxis.from + 0.00001;
        if (ranges.yaxis.to - ranges.yaxis.from < 0.00001)
            ranges.yaxis.to = ranges.yaxis.from + 0.00001;
        
        // do the zooming
        plot = $.plot($("#placeholder"), [ data ],
                      $.extend(true, {}, options, {
                          xaxis: { min: ranges.xaxis.from, max: ranges.xaxis.to },
                          yaxis: { min: ranges.yaxis.from, max: ranges.yaxis.to }
                      }));
        
        // don't fire event on the overview to prevent eternal loop
        overview.setSelection(ranges, true);
    });

    
    $("#overview").bind("plotselected", function (event, ranges) {
        plot.setSelection(ranges);
    });

  $("#nineties").click(function () {
        $.plot($("#placeholder"), [data], {
            xaxis: {
                mode: "time",
                min: (new Date()).getTime()-1800000,
                max: (new Date()).getTime()
            },
            selection: { mode: "xy" }
        });
    });

    $("#ninetynine").click(function () {
        $.plot($("#placeholder"), [data], {
            xaxis: {
                mode: "time",
                min: (new Date()).getTime()-3600000,
                max: (new Date()).getTime()
            },
            selection: { mode: "xy" }
        });
    });

    $("#12hour").click(function () {
        $.plot($("#placeholder"), [data], {
            xaxis: {
                mode: "time",
                min: (new Date()).getTime()-43200000,
                max: (new Date()).getTime()
            },
            selection: { mode: "xy" }
        });
    });

    $("#24hour").click(function () {
        $.plot($("#placeholder"), [data], {
            xaxis: {
                mode: "time",
                min: (new Date()).getTime()-86400000,
                max: (new Date()).getTime()
            },
            selection: { mode: "xy" }
        });
    });

    $("#48hour").click(function () {
        $.plot($("#placeholder"), [data], {
            xaxis: {
                mode: "time",
                min: (new Date()).getTime()-172800000,
                max: (new Date()).getTime()
            },
            selection: { mode: "xy" }
        });
    });

    $("#Refresh").click(function () {

    });




});
</script>

 </body>
</html>

My connect.php looks like this :

<?php

	function Connection(){
		$server="localhost";
		$user="root";
		$pass="";
		$db="temperatura";
	   	
		$connection = mysql_connect($server, $user, $pass);

		if (!$connection) {
	    	die('MySQL ERROR: ' . mysql_error());
		}
		
		mysql_select_db($db) or die( 'MySQL ERROR: '. mysql_error() );

		return $connection;
	}
?>

my database name is templog
my first column is timeStamp
second column is temperature

Somehow all this is not working togeather.

Is this short Flotr2 demo any help. I have tried to make it as short as possible for my own reasons.

<html>
  <head>
  </head>

  <body>

    <div id="container" style='position: absolute; left: 0px; top: 0px; width: 320px; height: 220px; padding:0px; background-color:red' >
    </div>
    <script type="text/javascript" src="flotr2.min.js"></script>
    <script type="text/javascript">


    function drawChart() {
        var graph = Flotr.draw( container, [
            {data: [[2, 3], [4, 18.5], [6, 5], [7, 13]] , bars: {show: true}} ,
            {data: [[1, 11], [4.5,  8.5], [6, 3], [7,  3]], lines: {show: true} }  
        ],{
            mouse: {
                track: true,
                relative: true
            }
        }); // end of .draw
    }; // end of function definition
    drawChart();

    </script>
  </body>
</html>

It obviously needs access to the file flotr2.min.js

My other Javascript code calls the function drawChart()

...R

You can also have a look at dygraphs http://dygraphs.com/ it visualizes time based data fast with a nice and interactive UI. You can use flat file databases, or put the data in the JS code, see Dygraphs — data format there is also a (German) tutorial how to use a MySQL data source Tutorial: Speicherung von Arduino Messdaten auf Webserver und deren Darstellung – Teil 1 | Glaskugelsehen Blog

With Flot they do not recommend using more than 1000 data points, "dygraphs plots millions of points without getting bogged down" the guys write on the website.

Hmm, that would mean I would have to set up a PHP script to write to a txt file.

It would be really nice if I could read directly from the SQL database itself, instead of interpreting it to another file, that would have the benefit of less processing power/space needed in long term.

But this fits my needs, I will definetly try this out and see how it works, I won't be picky.
Time to freshen up my German skills :slight_smile:

It would be really nice if I could read directly from the SQL database itself

From the Arduino? Just how would THAT be possible?

@PaulS's comment has caused me to look back at the original post

I am having massive problems graphing my data, real time.
My data are stored on SQL server.
I have columns in the table 1. TIME_STAMP, 2. Temperature.
I would like to use FLOT to do the graphs or any other that can provide with the same functionality.

It looks like this has nothing at all to do with an Arduino

...R

Would you say that I am making the temperature data myself in the SQL table :)? That is a serious acquisition right there.

As I explained before the data is being sent from Arduino => SQL server => web interface. And yes, the current installation isn't directly connected to Arduino. Yet I am working with data from Arduino so it is an Arduino related project.

The topic of this forum is interfacing w/ Software on the Computer, in my case SQL server and Jquery/AJAX. So I would say it fits in.

As I have deducted so far, my problem is with reading data from JSON, and probably the TIMESTAMP data is having some problems.

TIMESTAMP is the default offered by Mysql.
I have no idea how to make the Flot read this.
Here is my JSON output

Array ( [0] => Array ( [0] => 2015-04-16 22:47:27 [1] => 25 ) [1] => Array ( [0] => 2015-04-16 22:42:21 [1] => 25 ) [2] => Array ( [0] => 2015-04-16 22:37:15 [1] => 25 ) [3] => Array ( [0] => 2015-04-16 22:32:09 [1] => 24 ) [4] => Array ( [0] => 2015-04-16 22:27:03 [1] => 24 ) [5] => Array ( [0] => 2015-04-16 22:21:56 [1] => 23 ) [6] => Array ( [0] => 2015-04-16 22:16:50 [1] => 23 ) [7] => Array ( [0] => 2015-04-16 22:11:44 [1] => 24 ) [8] => Array ( [0] => 2015-04-16 22:06:38 [1] => 24 ) [9] => Array ( [0] => 2015-04-16 22:01:32 [1] => 24 ) [10] => Array ( [0] => 2015-04-16 21:56:25 [1] => 24 ) [11] => Array ( [0] => 2015-04-16 21:51:19 [1] => 24 ) [12] => Array ( [0] => 2015-04-16 21:46:13 [1] => 24 ) [13] => Array ( [0] => 2015-04-16 21:41:07 [1] => 24 ) [14] => Array ( [0] => 2015-04-16 21:36:01 [1] => 25 ) [15] => Array ( [0] => 2015-04-16 21:30:55 [1] => 25 ) [16] => Array ( [0] => 2015-04-16 21:30:07 [1] => 25 ) [17] => Array ( [0] => 2015-04-16 21:27:56 [1] => 25 ) [18] => Array ( [0] => 2015-04-16 21:27:40 [1] => 25 ) [19] => Array ( [0] => 2015-04-16 21:27:24 [1] => 25 ) [20] => Array ( [0] => 2015-04-16 21:27:18 [1] => 25 ) [21] => Array ( [0] => 2015-04-16 21:22:40 [1] => 25 ) [22] => Array ( [0] => 2015-04-16 21:22:04 [1] => 25 ) [23] => Array ( [0] => 2015-04-16 21:21:53 [1] => 25 ) [24] => Array ( [0] => 2015-04-16 21:21:42 [1] => 25 ) [25] => Array ( [0] => 2015-04-16 21:21:26 [1] => 26 ) [26] => Array ( [0] => 2015-04-16 21:21:10 [1] => 26 ) [27] => Array ( [0] => 2015-04-16 21:20:54 [1] => 25 ) [28] => Array ( [0] => 2015-04-16 21:20:38 [1] => 25 ) [29] => Array ( [0] => 2015-04-16 21:20:22 [1] => 25 ) [30] => Array ( [0] => 2015-04-16 21:20:07 [1] => 25 ) [31] => Array ( [0] => 2015-04-16 21:19:51 [1] => 25 ) [32] => Array ( [0] => 2015-04-16 21:19:35 [1] => 25 ) [33] => Array ( [0] => 2015-04-16 21:19:19 [1] => 26 ) [34] => Array ( [0] => 2015-04-16 21:19:03 [1] => 25 ) [35] => Array ( [0] => 2015-04-16 21:18:47 [1] => 25 ) [36] => Array ( [0] => 2015-04-16 21:18:31 [1] => 25 ) [37] => Array ( [0] => 2015-04-16 21:18:15 [1] => 25 ) [38] => Array ( [0] => 2015-04-16 21:17:59 [1] => 25 ) [39] => Array ( [0] => 2015-04-16 21:17:43 [1] => 25 ) [40] => Array ( [0] => 2015-04-16 21:17:27 [1] => 25 ) [41] => Array ( [0] => 2015-04-16 21:17:11 [1] => 25 ) [42] => Array ( [0] => 2015-04-16 21:16:55 [1] => 25 ) [43] => Array ( [0] => 2015-04-16 21:16:40 [1] => 25 ) [44] => Array ( [0] => 2015-04-16 21:16:24 [1] => 25 ) [45] => Array ( [0] => 2015-04-16 21:16:08 [1] => 25 ) [46] => Array ( [0] => 2015-04-16 21:15:52 [1] => 25 ) [47] => Array ( [0] => 2015-04-16 21:15:36 [1] => 25 ) [48] => Array ( [0] => 2015-04-16 21:15:20 [1] => 26 ) [49] => Array ( [0] => 2015-04-16 21:15:04 [1] => 26 ) [50] => Array ( [0] => 2015-04-16 21:14:48 [1] => 26 ) [51] => Array ( [0] => 2015-04-16 21:14:32 [1] => 26 ) [52] => Array ( [0] => 2015-04-16 21:14:16 [1] => 29 ) [53] => Array ( [0] => 2015-04-16 21:14:00 [1] => 29 ) [54] => Array ( [0] => 2015-04-16 21:13:44 [1] => 25 ) [55] => Array ( [0] => 2015-04-16 21:13:35 [1] => 25 ) [56] => Array ( [0] => 2015-04-16 21:13:17 [1] => 25 ) )

The code to interpret the Json data.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
 <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title>Graph of Energy Consumption</title>
    <link href="layout.css" rel="stylesheet" type="text/css"></link>
    <!--[if IE]><script language="javascript" type="text/javascript" src="flot/excanvas.min.js"></script><![endif]-->
    <script language="javascript" type="text/javascript" src="flot/jquery.js"></script>
    <script language="javascript" type="text/javascript" src="flot/jquery.flot.js"></script>
    <script language="javascript" type="text/javascript" src="flot/jquery.flot.selection.js"></script>
 </head>
    <body>
    <h1>Energy</h1>

    <p>Zoom to:
      <button id="nineties">half hour</button>
      <button id="ninetynine">1 hour</button>
      <button id="12hour">12 hours</button>
      <button id="24hour">24 hours</button>
      <button id="48hour">48 hours</button>
      <button id="Refresh">Refresh</button></p>
<?php

include 'connect.php';


$link=Connection();
$result=mysql_query("SELECT * FROM `tempLog` ORDER BY `timeStamp` DESC",$link);

$data = array();
$max = 0;
while($row = mysql_fetch_array($result))
{
  $data[] = array( $row['timeStamp'], $row['temperature'] );
}
print_r($data);

?>
    <div id="placeholder" style="width:800px;height:400px;"></div>

    <p></p>
    <div id="overview" style="margin-left:20px;margin-top:20px;width:780px;height:100px"></div>

<script id="source" language="javascript" type="text/javascript">

var data = <?php echo json_encode($data); ?>;
$(function () {

    var options = {
        xaxis: { mode: "time" },
        selection: { mode: "xy" },
    };
    
    var plot = $.plot($("#placeholder"), [ data ], options);
    
    var overview = $.plot($("#overview"), [ data ], {
        series: {
            lines: { show: true, lineWidth: 1 },
            shadowSize: 0
        },
        xaxis: { ticks: [], mode: "time" },
        yaxis: { ticks: [], min: 0, max: 5000 },
        selection: { mode: "xy" }
    });

  $("#placeholder").bind("plotselected", function (event, ranges) {
        // clamp the zooming to prevent eternal zoom
        if (ranges.xaxis.to - ranges.xaxis.from < 0.00001)
            ranges.xaxis.to = ranges.xaxis.from + 0.00001;
        if (ranges.yaxis.to - ranges.yaxis.from < 0.00001)
            ranges.yaxis.to = ranges.yaxis.from + 0.00001;
        
        // do the zooming
        plot = $.plot($("#placeholder"), [ data ],
                      $.extend(true, {}, options, {
                          xaxis: { min: ranges.xaxis.from, max: ranges.xaxis.to },
                          yaxis: { min: ranges.yaxis.from, max: ranges.yaxis.to }
                      }));
        
        // don't fire event on the overview to prevent eternal loop
        overview.setSelection(ranges, true);
    });

    
    $("#overview").bind("plotselected", function (event, ranges) {
        plot.setSelection(ranges);
    });

  $("#nineties").click(function () {
        $.plot($("#placeholder"), [data], {
            xaxis: {
                mode: "time",
                min: (new Date()).getTime()-1800000,
                max: (new Date()).getTime()
            },
            selection: { mode: "xy" }
        });
    });

    $("#ninetynine").click(function () {
        $.plot($("#placeholder"), [data], {
            xaxis: {
                mode: "time",
                min: (new Date()).getTime()-3600000,
                max: (new Date()).getTime()
            },
            selection: { mode: "xy" }
        });
    });

    $("#12hour").click(function () {
        $.plot($("#placeholder"), [data], {
            xaxis: {
                mode: "time",
                min: (new Date()).getTime()-43200000,
                max: (new Date()).getTime()
            },
            selection: { mode: "xy" }
        });
    });

    $("#24hour").click(function () {
        $.plot($("#placeholder"), [data], {
            xaxis: {
                mode: "time",
                min: (new Date()).getTime()-86400000,
                max: (new Date()).getTime()
            },
            selection: { mode: "xy" }
        });
    });

    $("#48hour").click(function () {
        $.plot($("#placeholder"), [data], {
            xaxis: {
                mode: "time",
                min: (new Date()).getTime()-172800000,
                max: (new Date()).getTime()
            },
            selection: { mode: "xy" }
        });
    });

    $("#Refresh").click(function () {

    });




});
</script>

 </body>
</html>

It would be really nice if you would help me with the project at hand, instead of picking on the details which aren't really helping in any way.

As I have deducted so far, my problem is with reading data from JSON, and probably the TIMESTAMP data is having some problems.

The Arduino is not doing that. So, Robin's comment is spot-on. The issues that you are having are completely on the PC side.

There may be other forums that are more appropriate.

linkers:
The topic of this forum is interfacing w/ Software on the Computer, in my case SQL server and Jquery/AJAX. So I would say it fits in.

I would not. Interfacing ends when the data arrives in the PC. Whether the PC wants to send it to SQL Server or convert it to JSON does not require Arduino programming.

It would be really nice if you would help me with the project at hand, instead of picking on the details which aren't really helping in any way.

You seem to be expecting people who know how to write Arduino programs to be able to give you advice about writing PC programs - and for free. That does not seem to me to be "picking on the details"

I gave you an example of a web page using Flotr2 because I happened to have it convenient - but it seems to have been ignored.

...R

Ok, so what happens, if I take out the SQL server part and send the data directly to Jquery engine with a php script :D? That would be Arduino directly interfaced.

You can just take out the SQL part.

A solution to this would be most fitting for my needs :D.

If you are so genious or smart, than provide me with fitting help for that, if you can't or don't have the time than just don't post at all.

Irritating random posts of PaulS in every section, was the first thing I noticed when I joined the forum.

Irritating random posts of PaulS in every section, was the first thing I noticed when I joined the forum.

@PaulS may not get an award for diplomacy but I don't think I have ever seen an error in one of his comments. If you put his style to one side you will get a lot of value from his comments.

Bigger Question ... do you want advice, or do you just want space to air your grievances ?

I gave you a link to my EzScrn demo in Reply #2 but you seem to have ignored that as well as my Flotr2 example.

That demo uses Python to read the data from the Arduino. I have no doubt that PHP can do the same thing, but I am not familiar with PHP.

If you want advice about code to read data from an Arduino why don't you post the code you have tried along with an explanation of what it should do and what it actually does.

Code for reading data from, or saving data to an SQL database is outside the scope of this Forum.

...R

Irritating random posts of PaulS in every section, was the first thing I noticed when I joined the forum.

Oh, good. I was beginning to think that no one noticed.

Thanks for you support, at no place I was trying to solve my grievance, all I was trying to do was to find some answers.
It is great that people like you are actually helping and doing something to help others.

I have also posted some information about my problem in other forums, but dispite that, this problem is in a way Arduino related, so it can be in the Arduino forum but let's not discuss that here and waste our time, as I already posted, if you can help me than do it, I will be most thankful for that, if you can't just don't post anything at all.

Robin, I wrote this a while ago.

linkers:
Those are really lovely Python examples, but I have never ever worked with Python. Ajax/Jquery are a little bit more familiar to me and easier to understand.
I would like the data to be in Jquery/AJAX form, it would be really great if you could provide examples of using those.
Also reading from an SQL database is much easier in my opinion, I just can't workout the graph part because I lack knowledge in this field.

linkers:
Robin, I wrote this a while ago.

I just can't workout the graph part because I lack knowledge in this field.

That is why I posted the code in Reply #7

I also envisaged that you could learn from the Python code and develop something similar in whatever language you are familiar with.

I can't see how I can help further.

...R