はじめに
今回は若干組み込みよりですが、使用する言語はCoffeeScriptです。 htmlやcss、JavaScriptなどブラウザで動作する技術を使用し、組み込み機器と通信しよう!という試みです。
あーるえすにーさんにーしー?
RS-232C(あーるえすにーさんにーしー)です。
http://ja.wikipedia.org/wiki/RS-232
モデム等と通信するために設計された通信方式です。古いPCには必ずといっていいほどついていましたが(D-SUB 9pin(でぃーさぶきゅーぴん)ってやつですね)、今や、ついている機種のほうが少ないと思います。ただ、組み込み業界ではまだまだ現役です。
PCについていない場合、以下のような変換をケーブルを使うのが一般的じゃないでしょうか。この変換を使用することでUSB通信がRS-232Cレベルの通信に変換されます。PCから見るともともと実装されているポートは「COMポート」、USB等で拡張したポートは「仮想COMポート」という扱いになります。

iBUFFALO USBシリアルケーブル(USBtypeA to D-sub9ピン)1.0m ブラックスケルトン BSUSRC0610BS
- 出版社/メーカー: バッファロー
- 発売日: 2012/04/25
- メディア: Personal Computers
- 購入: 2人 クリック: 14回
- この商品を含むブログを見る
RS-232Cは約-3V~-15Vを『1』、約+3V~+15Vを『0』とする負論理の規格です。大抵の場合、RS-232Cドライバ・レシーバというICによって+5Vや+3.3Vのレベルに変換されマイコンに接続されます。
今回どんなの作るの?
味気ないですが、COMポートを選択し、『send』を押すことで固定データ[0x01, 0x02, 0x03, 0x04, 0x05]がCOMポートの送信ラインから送信されるというサンプルです。送信ラインをそのまま受信ラインに直結(ループバック)させることで送信データ[0x01, 0x02, 0x03, 0x04, 0x05]がそのまま受信できることを確認できると思います。
chrome拡張を作る
chrome拡張にはCOMポートにアクセスする機能が用意されています。 この機能を使うことでchrome上から通信ができます。
用意するファイル
- manifest.json
- window.html
- icon.png
- background.js
- jquery-1.11.2.js
- chromeserial.js(chromeserial.coffee)
- app.js(app.coffee)
manifest.json
この拡張がどういうものかを定義します。 ここで"serial"を許可しておかないと通信はできません。
{ "name": "chrome_serial_sample", // app名 "description": "chrome_serial_sample", // 説明 "version": "1.0", // バージョン "manifest_version": 2, // マニフェストバージョン "app": { "background": { "scripts": ["js/background.js"] // backgroundで動作するJSの指定 } }, "icons": { "128": "icon.png" }, // iconのサイズと指定 "permissions": [ "serial" // serial使用許可 ]
window.html
COMポートの選択や送信ボタンなどをhtmlでwindow.htmlに書いていきます。今回は味気ないですがcssで装飾できるので見た目は好きなようにできます。
<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"></meta> <title>serialsample</title> </head> <body> <span>COMポートの選択</span> <select value="" id="ports" ></select> <a href="#" id="com-open">open</a> <a href="#" id="com-close">close</a> <a href="#" id="send">send</a> <!-- Load JS here for greater good =============================--> <script src="js/jquery-1.11.2.min.js"></script> <script src="js/chromeserial.js"></script> <script src="js/app.js"></script> </body> </html>
icon.png
好きなものを用意してください。
background.js
windowサイズ等を指定します。 いじる必要はあまりないかと思います。 ほぼサンプルのまま。
chrome.app.runtime.onLaunched.addListener(function(){ chrome.app.window.create('window.html', { 'bounds': { 'width': 500, 'height': 400 } }); });
- chromeserial.js(chromeserial.coffee)
chrome.serialのラッパーです。chrome.serialを使うにはひと手間いるのでclass化してその中で処理しています。
class @Serial connectionId = null constructor: (parms) -> for name, value of parms @[name] = value @getPorts() getPorts: -> chrome.serial.getDevices (ports) => for i,value of ports port = value.path @select.appendChild new Option port, port return startConnection: -> portName = @select.childNodes[@select.selectedIndex].value config = bitrate : @bitrate dataBits : @dataBits parityBit : @parityBit stopBits : @stopBits chrome.serial.connect portName, config, (openInfo) -> connectionId = openInfo.connectionId console.log "connectionId = " + connectionId return return endConnection: -> chrome.serial.disconnect connectionId, (result) -> startRecieve: -> console.log "recieve start!!" chrome.serial.onReceive.addListener @getData getData: (readInfo) => data = new Uint8Array readInfo.data @recieveCallback(data) sendData: (message) -> buffer = new ArrayBuffer(message.length) array = new Uint8Array(buffer) for value, i in message array[i] = value chrome.serial.send connectionId, buffer, (sendInfo) => @sendCallback sendInfo
- app.js(app.coffee)
アプリケーション部分です。 $comOpenButtonがクリックされるとCOMポートをオープンし、受信を開始します。 $sendButtonがクリックされたときに["0x01, 0x02, 0x03, 0x04, 0x05"]を送信しています。 受信が来たらrecieveCallback内でconsoleに受信データを表示しています。 受信したひとは送信ラインと受信ラインを直結(ループバック)してください。
D-SUB9pinのピンアサインはこうなってます。
2pinが受信データ、3pinが送信データです。他にもごちゃごちゃありますが基本的には送信データ、受信データ、GNDの3本あれば通信できます。
$comOpenButton = $('#com-open') $comCloseButton = $('#com-close') $sendButton = $('#send') $comOpenButton.click (event) -> serial.startConnection() serial.startRecieve() $comCloseButton.click (event) -> serial.endConnection() $sendButton.click (event) -> message = ["0x01, 0x02, 0x03, 0x04, 0x05"] serial.sendData(message) recieveCallback = (data) -> console.log "recieve data!!" console.log data sentCallback = (info) -> console.log "send!!" serialConfig = select : document.getElementById 'ports' # ポート名を表示するselect要素ID名 bitrate : 9600 # ボーレート dataBits : "eight" # データ数 parityBit : "no" # パリティビット stopBits : "one" # ストップビット recieveCallback : recieveCallback # データ受信完了時コールバック関数 sendCallback : sentCallback # データ送信完了時コールバック関数 serial = new Serial serialConfig
デモ
chrome -> 『設定』 -> 『拡張機能』で『デベロッパーモード』をチェック
『パッケージ化されていない拡張機能を読み込む』でサンプルの入ったディレクトリを選択
『起動』でwindowが立ち上がる
『open』を押してCOMポートをオープン consoleに接続idと受信開始メッセージが表示される
『send』を押すとデータ送信される。 ループバックしている場合じゃ以下のように送信データが受信されます。
これなにがいいの?
- htmlとjavascriptをちょっと知ってるよ!って組み込み技術者がPC側のシミュレータなどを簡単に作れる
- jQueryなど既存のJSライブラリを使える。(リッチな表現が簡単にできる)
- 以前紹介したc3.jsなどを使えば組み込み基板からのデータをリッチなチャートにできる
簡単にリッチなチャートが作れるC3.jsを使ってみた - ぼくのかんがえたさいきょうのうぇぶさーびす
ってとこかと思います。c3.jsとかhighchart.jsとか使うと綺麗なチャートがさくっとできちゃうんでteratermとかでセンサーデータ眺めてる人にこういうの作ってあげると「うおっ!」てなるかもしれません。