What to do with boat data....

My first graph :cool:

OK, maybe less than the most exciting thing anyone has ever seen, but the tricky bit is done which wasn't even tricky. From here on in it's just filling in blanks for any nmea, engine temperature etc.

Just add a raspberry pi :cool:



qXizZVT.png


(and the engine isn't even turned on!)
 
Another update just in case someone is actually interested..... ;)

Rrdtools seem solid, a weeks worth of 1 parameter at 1 minute intervals is 80Kb so not going to bust the hard drive.

Now set up just as a test just to save engine temperature and gps Cog at 1 minute intervals, also every minute it creates a graph and saves it which then the raspberry pi broadcasts on a Web page so you could have a few pages with different graphs/timescales etc. Rrdtools graphing is powerful and not too hard to set up.
I'm not up on html/php but it's probably possible to write a page where you input what you want and it will go get the graph for you.

So the cost of all this for anyone using a pi as an onboard nav computer?

Don't need a graph for that, nasa, zilch, zero. Just a few hours enjoyable googling and cut/paste programming :cool:
 
Done something similar with barometric pressure - RRD, php etc. Charts for last hour, 3 hours, day, week etc are very useful.

The biggest problem I have is SD card corruptions. I want the pi to come on when the instruments are switched on, and turn off cleanly when the power is removed. How are you handling that?
 
Done something similar with barometric pressure - RRD, php etc. Charts for last hour, 3 hours, day, week etc are very useful.

The biggest problem I have is SD card corruptions. I want the pi to come on when the instruments are switched on, and turn off cleanly when the power is removed. How are you handling that?

I can feel a lot of coffee and a late night on Google looking into php coming up... :)

As for corrupt cards, I'm pretty sure I've never once had one. The Pi is left on most of the time but will be rebooted quite a lot when I'm playing around loading new stuff. What power supply are you using? And what Pi model?
I have quite a heavy duty buck/boost dc converter set to about 5. 1v from memory plus another one powering a usb hub for the peripherals so power is pretty solid all round.

Istr something about the experimental hardware graphics driver possibly being linked with corrupted cards - do you have that turned on? What OS?

Not much help, sorry, good luck, there's (nearly!) always a reason........ :)
 
I can feel a lot of coffee and a late night on Google looking into php coming up... :)

I'd recommend taking a look at Highcharts - has a really easy to use set if PHP functions, plenty of nice chart examples, and using the 'HighchartJsExpr' constructor you can dynamically fetch the data from RRD using another PHP script. Happy to send you some examples if you wish.
 
Does the Pi stay powered for a fraction of a second when 12V is removed? If so, detect power loss and close the file.

Unfortunately not. Best I could manage was to have a script running that triggers a clean shutdown when one of the GPIO pins goes high. Add a button and you now have an off switch. I really wanted this thing to run without a screen, keyboard and mouse.
 
Unfortunately not. Best I could manage was to have a script running that triggers a clean shutdown when one of the GPIO pins goes high. Add a button and you now have an off switch. I really wanted this thing to run without a screen, keyboard and mouse.

If you google "raspberry pi ups" there's a variety of reasonably priced mini UPS boards which can signal when power has been removed and keep the device powered by battery for long enough to effect a safe shutdown.
 
Thanks - didn't realise that these existed. Just ordered a S.USV basic from Germany - Looks like it will do the job.
 
I'd recommend taking a look at Highcharts - has a really easy to use set if PHP functions, plenty of nice chart examples, and using the 'HighchartJsExpr' constructor you can dynamically fetch the data from RRD using another PHP script. Happy to send you some examples if you wish.

Thanks, had a quick look, zoom able cool looking graphs - very nice! But maybe one thing at a time, I'm just made up that I've got as far as I have so quickly :)

Still thinking about your sd card woes, something just doesn't seem right. I usually exit raspian properly but really won't think twice about pulling the power, either intentionally or not :) it happens quite a lot and I've never had a corrupted sd card. Maybe just lucky.
That's using sans disk 16Mb x10 cards on a rasp Pi 3 running openplotter (why run anything else :) ) with good power.
I've a spare pi 3 so if I get round to it will maybe set it up with an arduino on a loop switching off the Pi power then rebooting overnight and see if it will misbehave.

Having some sort of ups would be the way to go as well.
 
I've had 2 cards corrupt - both Sandisk class 10. I have a Pi 2, but may swap to a Pi 3 in the short term. Power comes from the USB port on my Mac when at home. I have a DC 12V to 5V 3A converter for the boat which plugs straight into the micro USB port. With the UPS board it should be much better, as I will get a controlled shutdown when the instruments/mac are turned off. I suspect that it was made worse as when data logging, the pi is regularly writing to the SD card.
 
Done something similar with barometric pressure - RRD, php etc. Charts for last hour, 3 hours, day, week etc are very useful.
So how do you get your data onto the web?
Or is it just local?

I was thinking of just a little script checking if the Pi is connected to Web and if so running a ftp upload, maybe backing up the RRD databases to Dropbox or something once in a while.

Or is there a better way?
 
The first thing I would do with that data is to make an accurate polar.

If you extract the BSP, TWS, TWA into a spreadsheet, you can make a nice polar using least-squares method (LINEST function). I used

BSP=aTWS^-1+bTWS+cTWS^2+dTWS^3+eTWS^4+fSIN(TWA)+gCOS(TWA)+h(SIN(TWA))^2+i(COS(TWA))^2

I then used the data to make csv polar tables formatted for Predictwind and for my Raymarine plotter.
 
The first thing I would do with that data is to make an accurate polar.

If you extract the BSP, TWS, TWA into a spreadsheet, you can make a nice polar using least-squares method (LINEST function). I used

BSP=aTWS^-1+bTWS+cTWS^2+dTWS^3+eTWS^4+fSIN(TWA)+gCOS(TWA)+h(SIN(TWA))^2+i(COS(TWA))^2

I then used the data to make csv polar tables formatted for Predictwind and for my Raymarine plotter.

No need. Cruising boat, upwind isn't a point of sail but a major passage planning error. :)

But thanks, one day might have a play. And thinking about TWS & TWA would be pretty easy to calculate and make into nmea, ta.
 
I'd recommend taking a look at Highcharts - has a really easy to use set if PHP functions, plenty of nice chart examples, and using the 'HighchartJsExpr' constructor you can dynamically fetch the data from RRD using another PHP script. Happy to send you some examples if you wish.
Before getting to highcharts I'm pulling my hair out here trying to get php to create a rrdtools graph this module..
http://php.net/manual/en/book.rrd.php

The info seems to work but rrd_graph won't, just a blank error.

Did you use php direct on rrdtool?

Some examples would be great.
 
Really suggest that you use Highcharts :) It will help you break the problem down into 2 parts:
1) extract data from the time series database (I used the RRD PHP module to make this a little easier)
2) create a snazzy graph with Highcharts

Here is some example code for the first part:

Code:
<?php

	if (!extension_loaded('rrd'))
	{
    		if (!dl('rrd.so'))
		{
        		exit;
    		}
	}

	$query = parse_url($_SERVER['REQUEST_URI'], PHP_URL_QUERY);
	parse_str($query, $params);
	switch ($params['zoom']) {
		case '0':
			$start = 'now-1w';
			break;
		case '1':
			$start = 'now-1d';
			break;
		case '2':
			$start = 'now-3h';
			break;
		default:
			$start = 'now-1h';
			break;
	}

	$fname = "/home/pi/nmea/pressure/pressure.rrd";

	$export = rrd_xport(array("--json", "--start", $start, "--end", "now", "--step", 'automatic', "--maxrows", "200",
		"DEF:pressure=/home/pi/nmea/pressure/pressure.rrd:pressure:AVERAGE",
		'XPORT:pressure:"Pressure"'));

	$data = Array();
	foreach ($export['data'][0]['data'] as $key => $value)
	{
		if ( ! gettype($value) == "double" || ! is_nan($value))
		{
			if ($value > 925 && $value < 1055) // UK extremes of barometric pressure to remove anomolies
			{
				array_push($data, array($key*1000, round($value,2)));
			}
		}
	}

	header("Content-type: text/json");
	echo json_encode($data, JSON_PRETTY_PRINT);

?>

And the second part

Code:
<?php

use Ghunti\HighchartsPHP\Highchart;
use Ghunti\HighchartsPHP\HighchartJsExpr;
use Ghunti\HighchartsPHP\HighchartOption;

function renderBarometerChart($option)
{
	switch ($option) {
		case 'bar1w':
			$zoom = 0;
			break;
		case 'bar1d':
			$zoom = 1;
			break;
		case 'bar3h':
			$zoom = 2;
			break;
		default:
			$zoom = 3;
			break;
	}

	$chart = new Highchart();
	$chart->chart->renderTo = "highchartsContainer";
	$chart->chart->zoomType = 'x';
	$chart->chart->events->load = new HighchartJsExpr(
		"function() {
			var series = this.series[0];
			function getData() {
				$.ajax({
					url: '/php/barometer-data.php?zoom=" . $zoom . "',
					success: function(data) { series.setData(data); },
					cache: false
				});
			}
			getData();
			setInterval(getData, 5000);
		}"
	);
	
	$chart->title->text = "Barometric Pressure (Sea Level)";
	$chart->subtitle->text = new HighchartJsExpr(
	    "document.ontouchstart === undefined ?
	                'Click and drag in the plot area to zoom in' :
	                'Drag your finger over the plot to zoom in'");
	
	$chart->xAxis->type = "datetime";
	$chart->yAxis->title->text = "Barometric pressure (millibars)";
	$chart->yAxis->minRange = 2;
	$chart->yAxis->minTickInterval = 1;
	$chart->yAxis->minorTickInterval = 'auto';
	
	$chart->legend->enabled = false;
	$chart->tooltip->formatter = new HighchartJsExpr(
		"function() {
	    		return '<b>'+ this.series.name +'</b><br/>'+
	    			Highcharts.dateFormat('%d-%m-%Y %H:%M:%S', this.x) +'<br/>'+
	    			Highcharts.numberFormat(this.y, 1);
		}"
	);
	
	$chart->plotOptions->area->fillColor->linearGradient->x1 = 0;
	$chart->plotOptions->area->fillColor->linearGradient->x2 = 0;
	$chart->plotOptions->area->fillColor->linearGradient->y1 = 0;
	$chart->plotOptions->area->fillColor->linearGradient->y2 = 1;
	$chart->plotOptions->area->fillColor->stops = array(
		array(0,new HighchartJsExpr("Highcharts.getOptions().colors[0]")),
		array(1,new HighchartJsExpr("Highcharts.Color(Highcharts.getOptions().colors[0]).setOpacity(0).get('rgba')"))
	);
	$chart->plotOptions->area->lineWidth = 1;
	$chart->plotOptions->area->marker->radius = 2;
	$chart->plotOptions->area->states->hover->lineWidth = 1;
	$chart->plotOptions->area->threshold = null;
	
	$chart->series[0]->name = "Barometric pressure";
	$chart->series[0]->type = "area";
	$chart->series[0]->data = array();
	
	$globalOptions = new HighchartOption();
	$globalOptions->global->useUTC = false;
	$globalOptions->lang->decimalPoint = '.';
	$globalOptions->lang->thousandsSep = '';
	
	$html  = $chart->printScripts();
	$html .= "<div id='highchartsContainer'></div>";
	$html .= "<script type='text/javascript'>";
	$html .= $chart->render("chart1");
	$html .= "</script>";
	
	return $html;

}
 
Last edited:
Really suggest that you use Highcharts :) It will help you break the problem down into 2 parts:
1) extract data from the time series database (I used the RRD PHP module to make this a little easier)
2) create a snazzy graph with Highcharts

Here is some example code for the first part:
____________
Thanks, that's really useful! :cool:
I'll definitely get round to checking out HighCharts, looks great.

Only just got php to create a graph, all because of a really stupid tiny syntax error hidden away in a string array. :(

So at least moving forward again. Long term it would be lovely to have a php page with lots of options allowing you to select what data you want and start , end time etc, etc. Shouldn't be that hard.... :)

Thanks again :encouragement:
 
Top