概要


USBシリアル機能は、USBポートを通してUSBシリアルデバイスを接続して利用する機能です。専用のライブラリを使用して、Webアプリからシリアル通信を行うことができます。



USBシリアルの仕組み


Firefox OSは、現在 USB Serial APIを備えていません(※2015/1/16現在)。そのため、外部機器との接続が必要なOpen Web Boardでは、シリアルポートとWebアプリの中継を行う簡易的なデーモンプロセスを動作させることで、USBシリアル機能を実現しています。



WebアプリからUSBシリアルデバイスへアクセスするアーキテクチャ概要図

Open Web Boardではこのserialdデーモンが動作しており、Arduinoなどのデバイスに対応しています。特殊な設定が必要なデバイスにも、このserialdを書き換えることで自由にアクセスすることができます。



使用方法


■マニフェストファイル

mozTCPSocketを使用するため、"tcp-socket" パーミッションを必要とします。Webアプリのマニフェストファイルに下記のような permissionを指定してください。permissionに関する詳細はこちらをご参照ください。
{
  (省略)
    "type": "privileged",
    "permissions": {
      "tcp-socket":{}
    }
}
			

■プログラム

USBシリアルの利用フローを下記の図に示します。



動作フロー図

1) まずWebアプリから serialdへTCPコネクションを確立します。デフォルトでは、ポート9943を開いています。Firefox OSではmozTCPSocketが利用できますので、これを使用してローカルホストに接続します。
var  socket = navigator.mozTCPSocket.open(“127.0.0.1”, 9943 );
socket.onopen =  fucntions() {
	// 必要があれば、ここで初期コマンドなどを送ります。
};
			

2) 次にUSBシリアルの初期化コマンドを送ります。JSON形式で、開くデバイス名とビットレートを指定できます。
var command = { "devicename": “ttyUSB0”,
		"bitrate": 9600 };	// /dev/ttyUSB0に B9600で接続するときの例です。
socket.send(JSON.stringify(command));
			

3) 初期化が終わるとメッセージを送受信できるようになります。USBシリアルにコマンドを送ってみましょう。TCPのSENDメソッドでコマンドを送るだけです。
socket.send(“CMD OP 2211 EXAMPLE”);
			

4) USBシリアルからメッセージを受け取るときにはコールバック関数を指定します。
socket.ondata = function(msg) {
	alert( msg.data );
}
			

以上でUSBシリアルとの送受信が可能となります。serialdが対応していないパリティビット設定や通信速度、またバイナリ送受信などは serialdを修正する必要があります。



ライブラリ(serial.js)の使用方法


USBシリアルを少しだけ簡単に使用するためのラッパーライブラリ(serial.js)を使用することができます。

利用フローは、mozTCPSocketを使用する場合とほぼ同じです。

var mySerial = new TCPSerial();	//	オブジェクトの生成
mySerial.setParams( “ttyUSB0”, 115200 );	//	接続デバイスと、bitrateの指定
mySerial.onread = function(msg) {		//	キャラクタ受信時の処理
	alert( msg );			
};
mySerial.connect( “127.0.0.1”, 9943 );	//	serialdへの接続
mySerial.send( “CMD TEST”);		//	キャラクタをおくります。
mySerial. disconnect();			//	切断します
			

serial.jsソースコード
/*	Serial for Open Web Board JavaScript framework, version 0.1
 *	(c) 2014 KDDI CORPORATION
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. 
 *--------------------------------------------------------------------------*/

var TCPSerial = function() {
	this.host = "";
	this.port = "";
	
	this.bitrate = 9600;
	this.devicename = "ttyUSB0";

	this.onread = null;
	this.onopen = null;

	this.socket = null;
};

function seriallog(mes) {
	console.log(mes)
};

TCPSerial.prototype = {
	//	 set serial port params
	setParams: function( devicename, bitrate ) {
		seriallog( "SERIAL: " + devicename + ", " + bitrate );
		
		this.devicename = devicename;
		this.bitrate = bitrate;
	},
	
	//	 connect to seriald
	connect: function( host, port ) {
		this.host = host;
		this.port = port;
		
		seriallog("SERIAL Connecting: " + this.host +":"+this.port);
		
		this.socket = navigator.mozTCPSocket.open( this.host, this.port );
		
		//	send command to seriald after connected
		this.socket.onopen = function() {
			seriallog("TCP Connected to seriald");
			
			var command = { "devicename": this.devicename, 
			"bitrate": this.bitrate };
			var ret = this.socket.send(JSON.stringify(command));
			
			if (this.onopen) {
				this.onopen();
			}
		}.bind(this);
		
		
		//	get message from seriald
		this.socket.ondata = function(msg) {
			if(this.onread) {
				this.onread(msg.data);
			}
		}.bind(this);

		// OnError
		this.socket.onerror = function(e) {
			seriallog( "SERIAL: onerror:" );
			seriallog( e );
		}.bind(this);
		
		//	OnClose
		this.socket.onclose = function(e) {
			seriallog( "SERIAL: onclose is called" );
			this.socket = null;
		}.bind(this);

	},
	
	send: function(msg) {
			var ret = this.socket.send(msg);
			return ret;
	},
	
	disconnect: function() {
		if (this.socket) {
			this.socket.close();
		}
	}

};