blog.kur.jp

バイオリンと山、自転車をこよなく愛するkurのチラシの裏。たまには技術的なことを書いたりするかも知れません。

Webブラウザからインターネット越しにArduinoのシリアル入出力を叩く

ネットワーク越しにArduinoを操作したいなと思ったので、ちゃちゃっと作って見ました。需要はあんまりない気がするので、最低限の記述だけれおd,ほぼリアルタイムの通信が出来ているので、備忘録代わりに。

仕組みとしては下記のような感じ。
f:id:mikio-k:20160310070354p:plain
Arduinoのシリアル出力をMacで動くNode.jsが受信してSocket.ioでAzureに投げつける。WebブラウザとAzureも同様にSocket.ioで通信をしている。コードを見てもらったほうが早いと思うので下記に示す。まず、下記がMac上のNode.jsのコード。

var serialPort = require("serialport")
var io = require('socket.io-client')

// send server
socket = io.connect('http://ほげほげ.azurewebsites.net/');
socket.on('connect', function () {
	  console.log("socket connected");
});
  
socket.on('s2c_message', function (data) {
	  console.log("data receive:" + data.value);
	  sp.write(data.value);
});
  var flag = 0;
  var sp = new serialPort.SerialPort("/dev/tty.usbmodem1421", {
  baudrate: 9600,
  dataBits:8,
  parity:'none',
  flowControl:false,
  parser:serialPort.parsers.readline('\n')
});

sp.on('data', function(data) {
	console.log('data received: ' + data);
    socket.emit("c2s_message", { value : data });
});

sp.on("open", function () {
  console.log('open');
});

そしてこれがAzure WebApps上のコード

var http = require('http');
var socketio = require( 'socket.io' ); // Socket.IOモジュール読み込み
var fs = require( 'fs' ); // ファイル入出力モジュール読み込み
//Lets define a port we want to listen to
var port = process.env.PORT || 1337;
var ip = "0.0.0.0";

// 3000番ポートでHTTPサーバーを立てる
var server = http.createServer( function( req, res ) {
    res.writeHead(200, { 'Content-Type' : 'text/html' }); // ヘッダ出力
    res.end( fs.readFileSync('./index.html', 'utf-8') );  // index.htmlの内容を出力
}).listen(port);

// サーバーをソケットに紐付ける
var io = socketio.listen( server );

// 接続確立後の通信処理部分を定義
io.sockets.on( 'connection', function( socket ) {

    // クライアントからサーバーへ メッセージ送信ハンドラ(自分を含む全員宛に送る)
    socket.on( 'c2s_message', function( data ) {
        // サーバーからクライアントへ メッセージを送り返し
        io.sockets.emit( 's2c_message', { value : data.value } );
    });
});

最後にブラウザのUI

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
    <style>
    #messageForm {
        margin-top: 15px;
    }
    </style>

    <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js"></script>
    <script type="text/javascript" src="socket.io.js"></script>
</head>
<body>
    <div class="container">
        <div class="row">
            <div class="col-md-6 col-md-offset-3">
                <form name="form">
                    <div class="form-group">
                        <input  name="field" type="text" class="form-control" id="messageForm" style="width:100px;">    
                    </div>
                    <div class="form-group">
                        <button type="button" class="btn btn-primary" id="sendMessageBtn">send message</button>
                    </div>
                </form>
                <div id="messageView"></div>
            </div>
        </div>
    </div>

    <script type="text/javascript">
	document.form.field.focus();
    var ioSocket = io.connect( "http://arduinosocket.azurewebsites.net/" ); // チャットサーバーに接続
    // サーバーからのデータ受け取り処理
    ioSocket.on( "connect", function() {} ); // 接続
    ioSocket.on( "disconnect", function() {} ); // 切断

	$("#messageForm").keydown(function(e) {
            if ((e.which && e.which === 13) || (e.keyCode && e.keyCode === 13)) {
				        var message = $("#messageForm").val();
    				    $("#messageForm").val("");

				        // クライアントからサーバーへ送信
        				ioSocket.emit( "c2s_message", { value : message } );

                return false;
            } else {
                return true;
            }
			});
    // サーバーからクライアントへの送り返し
    ioSocket.on( "s2c_message", function( data ) { appendMessage( data.value ) });

    // 画面にメッセージを追記
    function appendMessage( text ) {
        $("#messageView").prepend( "<div>" + text + "</div>" );
    }

    // 自分を含む全員宛にメッセージを送信
    $("#sendMessageBtn").click( function() {
        // メッセージの内容を取得し、その後フォームをクリア
        var message = $("#messageForm").val();
        $("#messageForm").val("");
        // クライアントからサーバーへ送信
        ioSocket.emit( "c2s_message", { value : message } );
    });

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