Arduino UNO R3でとったセンサーデータをC3.jsでグラフ表示する


# 環境
* Mac OS X Yosemite
* Arduino UNO R3

# ソース一式

https://github.com/itagakishintaro/ArduinoLesson

# 1.Arduinoでセンサーデータをとる

センサーは何でもいいけど、[Arduinoをはじめようキット](http://www.amazon.co.jp/dp/B0025Y6C5G)には光センサー(Cdsセル)しかなかったので、それを使った。

## 使ったもの

Arduino UNO R3
ブレッドボード:1
CdSセル		:1
抵抗(10k)	:1
ジャンパー線	:3

## 回路

図がなくてわかりにくいけど、ググれば色々でてくるので。。。

5V - CdS ------- 10k抵抗 - GND
　　　　　　|
　　　　　　A0

# 2.Node.js+SocketIOでサーバーからセンサーデータを送信する

(1) `package.json`をつくる

```
{
	"name": "Arduino",
	"version": "0.0.1",
	"private": true,
	"dependencies":{
		"johnny-five": "*",
		"serialport": "*",
		"express": "*",
		"socket.io": "*"
	}
}
```

(2) インストール

```
npm install
```

(3) Node.jsでサーバーをたてるコードをかく

次の3つに注意。

* expressを使っている
* ルーティングを別ファイルにしている
* 静的ファイルのディレクトリを指定している

（参考：http://qiita.com/itagakishintaro/items/a1519998a91061cbfb1e）


```server.js
'use strict';
var http = require('http');
var express = require('express');
// ルーティングファイルを指定
var routes = require('./routes');
var app = express();
var server = http.createServer(app);
// socket.ioの読み込み
var socketIO = require('socket.io');

// 静的ファイルのルートディレクトリを指定
app.use(express.static(__dirname + '/public'));
// ルーティングを設定
routes.configRoutes(app, server);

module.exports = {
	io: socketIO.listen(server),
	init: function() {
		server.listen(3000);
		console.log('Listening on port %d in %s mode', server.address().port, app.settings.env);
	}
}
```

```routes.js
'use strict';
var configRoutes;
var fs = require('fs');

configRoutes = function(app, server, passport) {
    app.get('/', function(request, response) {
        response.redirect('/index.html');
    });
}

module.exports = {configRoutes: configRoutes};
```

(4) SocketIOでセンサーデータを送信するコードをかく

はじめにserver.jsを呼んでサーバーを起動し、johnny-fiveというモジュールでArduinoからセンサーデータを取得している。
（参考：http://ics-web.jp/lab/archives/6338）

```sensor-charts-server.js
var server = require('./server.js');
server.init();

/*
    Socket.IO
*/
var socket;
// サーバーへのアクセスを監視。アクセスがあったらコールバックが実行
server.io.sockets.on('connection', function (s) {
    socket = s;
});

/*
    johnny-five [ Arduino Setting ]
*/
var five = require('johnny-five');
var board = new five.Board();
var sensor;

board.on('ready', function() {
    // アナログ0番ピンを100msごとに取得
    sensor = new five.Sensor({
        pin: 'A0',
        freq: 100
    });

    // センサーを追加(アクセス許可)
    board.repl.inject({
        pot: sensor
    });

    // センサーの入力値を0～100にスケーリングして取得
    sensor.scale(0, 100).on('data', function() {
        var value = this.value;

        // Socket.IOで値を'sensor'というイベント名で送信
        if(socket) socket.emit('sensor', { value: value });
    });
});
```

# 3.センサーデータをグラフ表示する

## 使うもの

[C3.js](http://c3js.org/samples/timeseries.html)というD3.jsをラップした簡単にグラフが書けるJavaScriptのライブラリ

## コードをかく

静的ファイルは上記`routes.js`でpublic配下にしたことに注意。

```public/sensor-charts.html
<!DOCTYPE html>
<html lang="ja">
<head>
	<meta charset="UTF-8">
	<title>センサーチャート</title>
	<link href="css/vendor/c3.min.css" rel="stylesheet" type="text/css">
</head>
<body>
	<div id="chart"></div>
	
	<script src="js/vendor/jquery-2.1.3.min.js"></script>
	<script src="js/vendor/xdate.js"></script>
	<script src="js/vendor/d3.min.js" charset="utf-8"></script>
	<script src="js/vendor/c3.min.js"></script>
    <script src="../socket.io/socket.io.js"></script>
    <script src="js/sensor-charts.js"></script>
</body>
</html>
```

SocketIOからセンサーデータを受信して、1秒間隔でデータを取得してグラフを再描画している。

```public/js/sensor-charts.js
(function() {
	var data = [ ['x'], ['sensor'] ];

	$(function() {
		// サーバーに接続
		var socket = io.connect(location.origin);
		var value;

		// サーバーからセンサーの値を受信
		socket.on('sensor', function(dataFromServer) {
			value = dataFromServer.value;
		});

		// 一定間隔でサーバーのセンサーデータを確認してchartを変更

		setInterval(function() {
			data[0].push( new XDate().toString('yyyy-MM-dd hh:mm:ss') );
			data[1].push( value );
			draw();
		}, 1000);
	});

	// http://c3js.org/samples/timeseries.html
	function draw() {
		var chart = c3.generate({
		    data: {
		        x: 'x',
				xFormat: '%Y-%m-%d %H:%M:%S',
		        columns: data
		    },
		    axis: {
		        x: {
		            type: 'timeseries',
		            tick: {
		                format: '%Y-%m-%d %H:%M:%S'
		            }
		        }
		    }
		});
	}
})();
```



# 4.動かす

(1) サーバー起動

```
npm install
node sensor-charts-server.js
```

(2) ブラウザからアクセス

```
http://localhost:3000/sensor-charts.html
```