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


環境

  • Mac OS X Yosemite
  • Arduino UNO R3

ソース一式

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

センサーは何でもいいけど、Arduinoをはじめようキットには光センサー(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という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