0

BlendMicro npmが自動再接続・複数接続できるようになった

BLE接続のArduinoマイコンボードBlendMicroと簡単に通信できるnodeライブラリをアップデートした。

https://www.npmjs.com/package/blendmicro
v0.2.3になった。

普通BLEで通信しようとすると、PeripheralをScanしてServiceを探してTXとRXを探して……とかなり面倒な実装をしなければならないのだが、このライブラリを使うとマイコン側のble_set_name関数で指定した名前で探して接続まで全部やってくれるのでとても簡単に通信ができる。


自動再接続

BlendMicroと距離が離れて電波が通らなくなったり、太陽電池で動かしていて電源が落ちたりした時に、自動的に再scanしてちゃんと再接続できるようになった。
この機能はデフォルトで有効になっている。

というかもともと再接続は実装していたんだけどバグがあったのでちゃんと直した。3日ぐらい動かしっぱなしにしていて調子が良かったのでリリースした。

blendmicro.reconnect = false;
を指定すると無効にできる。

複数のBlendMicroへの同時接続


今までは1つのNodeプロセスから1つのBlendMicroにしか接続できなかったんだけど、うまくイベント管理したら複数同時接続できるようになった。

これはblendmicro npmを内部で使っているble-firmataでも使えるので、例えばこういう風に複数のBlendMicroに接続してそれぞれアナログ入出力させたりが簡単に書ける。

var BLEFirmata = require('ble-firmata');

var devices = [ "BlendMicro", "device2", "device3" ];

devices.map(function(device_name){
return new BLEFirmata().connect(device_name);
}).forEach(function(arduino){

arduino.on('connect', function(){
console.log("connect!!" + arduino.peripheralName);
console.log("board version: "+arduino.boardVersion);
});

arduino.once('connect', function(){
setInterval(function(){
var an = Math.random()*255;
arduino.analogWrite(13, an);
console.log(arduino.peripheralName + " -> " + arduino.analogRead(0));
}, 100);
});

});

もちろん複数台でも切断時再接続される。

BLENanoと通信できるようになった

BlendMicroと同じRedBearLabが作っているBLENanoという、もうひと回り小さいボードと通信できた。

俺はBLENanoを持っていないんだけど、hiraku君がBLENanoのサンプルコードの一つであるSimpleChatを書き込んだBLENanoを持っていてそれと通信させてもらったら通った。
SimpleChatの上の方に書いてあるService/TX/RXのUUIDがBlendMicroと同じなので、特に何も変更せずに動くことが確認できた。

なおBLENanoが手元にないのでble-firmataのBLENano版ファームウェアが書けないのだが、たぶんBLEFirmataSketch.inoを少し修正すれば動くと思うので誰か作って欲しい

add BLENano Firmata firmware · Issue #6 · shokai/node-ble-firmata
add BLENano sample code · Issue #7 · shokai/blendmicro-node

0

chokidar-cliのファイル更新監視が速い

1年ぐらいgulpを使おうとがんばったけど理解できなかったので、先月からこちらを参考にpackage.jsonのnpm run scriptにshell script書いてタスク実行する方式をやっている

参考:Grunt/Gulpで憔悴したおっさんの話 – MOL

あらためて最近使ってるコマンドの周辺ツールを調べると、ファイル更新検知して差分だけタスク実行してくれる機能があるのが多い。


あとは上の記事にも書いてあるんだけどparallelshellで複数のwatchしてくれる系コマンドを同時に実行できるので

例えばこんな感じでpackage.jsonのscriptsを書いて、npm run watchで全部watchしてビルドしたりlintしたりしている。
{
"name": "es6-study",
"private": true,
"version": "1.0.0",
"scripts": {
"watch": "parallelshell 'npm run build -- --watch' 'esw src/*.es6 server/*.es6 --watch'",
"build": "babel src/ --out-dir dist/ --source-maps inline",
"test": "eslint src/*.es6 server/*.es6",
"server": "babel-node server/app.es6",
"start": "npm run build && npm run server"
},


で、よく見たらbabel/eslint-watch/watchifyでみんなchokidarというnpmを使っていた。
chokidarはNode組み込みのfs.watchとMac用のfseventsを適切に使い分けてくれるクロスプラットフォームなファイル監視ライブラリで、これを使えばファイルの更新を監視してタスク実行する系のツールは簡単に作れそう。

さらにchokidar-cli npmというのがあってこれをグローバルインストールすると使えるchokidarコマンドがファイル監視してからの指定コマンド実行をやってくれる。

例えばこんな感じで実行するとwatchしてテストを実行できる
% chokidar "**/*.es6" -c 'npm run test'

watchというnpmもファイル更新監視してコマンド実行してくれるコマンドが付いているんだけど、こっちはpollingなので1秒ぐらいラグがあってつらい。chokidarだと一瞬で更新検知して実行されててすごい。

0

HerokuのHubotをProcess Schedulerで寝かす前に報告させる



HerokuのHubotを寝させる

無料で使うには1日6時間寝かせないとならないので
Heroku | Heroku’s Free (as in beer) Dynos

dashboard.heroku.comからaddonにProcess Schedulerを追加して6時間寝させる。


参考:HerokuでHubotを指定の時間に寝かせる – はらへり日記


寝る前に報告させる

寝る前に「寝ます」とか「寝ましょう」とか言ってくれた方が安心感がある。

herokuはプロセスの終了時にSIGTERMを投げてくるので、それを受ければいい。

nodeだとprocess.on(‘SIGTERM’, function(){ });でキャッチできるはずだけどHubotではできなかった。ソースをよく見たらbin/hubotが先にSIGTERMにイベントを登録して、その中でexitしていた。なのでSIGTERMイベントを上書きした。

module.exports = (robot) ->

## 起きた時、slack-adapterがつながるのを待って通知
cid = setInterval ->
return if typeof robot?.send isnt 'function'
robot.send {room: "#general"}, "ガバリ"
clearInterval cid
, 1000

## 寝た時、通知してからexitする
on_sigterm = ->
robot.send {room: "#general"}, 'スヤリ'
setTimeout process.exit, 1000

if process._events.SIGTERM?
process._events.SIGTERM = on_sigterm
else
process.on 'SIGTERM', on_sigterm

processがイベント管理に使っているEventEmitterは先に登録したイベントが先に実行される。先にbin/hubotが登録したイベントを削除するにはイベント登録時にreturnされるidを使うしか無いので、仕方なく_eventsプロパティを直接書き換えた。
hubotの仕様が変わった時に挙動がおかしくなるかもしれないけど、例えばsocket.ioがhttp.serverに/sockets/socket.io.jsを登録する処理とかでも_eventsの順序入れ替えをやっているし、まあしょうがない。EventEmitterとはそういう物だと思うしかない。

先に登録されていなければ普通にonで登録する。

本当は上書きじゃなくて先に実行されるようにしようかと思ったけど、eventemitterは登録されているコールバックが複数なら配列で持ち、1つなら配列ではなく関数を直接持つので、なんだか面倒になって上書きにした。

0

Edisonのnpmをupdateした

Edisonのnpmのバージョンが1.0系なのでnpm run test — –watchとかできなかったのでupdateした。

% npm update -g npm

したらnpmが壊れたので

module.js:340
throw err;
^
Error: Cannot find module 'npmlog'
at Function.Module._resolveFilename (module.js:338:15)
at Function.Module._load (module.js:280:25)
at Module.require (module.js:364:17)
at require (module.js:380:17)
at /usr/lib/node_modules/npm/bin/npm-cli.js:18:11
at Object. (/usr/lib/node_modules/npm/bin/npm-cli.js:75:3)
at Module._compile (module.js:456:26)
at Object.Module._extensions..js (module.js:474:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)


ソースからインストールしなおした。

% opkg install tar
% curl -0 -L https://www.npmjs.com/install.sh | sh
% npm --version
2.11.2

0

littleBits Arduino moduleをNode.jsやRubyから操作する

littleBitsArduinoモジュールをNodeから使うFirmataのラッパーを書いた。PCで動かしているNodeからlittlebitsを操作できる。

https://www.npmjs.com/package/littlebits-arduino
https://github.com/shokai/node-littlebits-arduino


littleBitsは専用のマグネットコネクタで接続する電子工作ツールキットで、このコネクタのおかげで部品が壊れるような向きには絶対接続できないようになっている。サーボモーターとLEDとスピーカーみたいな回路的に全然違う物も全部「output module」として組み換え可能になるようにモジュール化されていたりと、回路としては無駄は多いけどとてもソフトウェア的な考え方で作られていて面白い。回路わからない人でも適当につなげれば動くのはすごい。


インストール

% npm i littlebits-arduino


使い方


左側の3つが入力、右側が出力ポートになる。

d1やa0のようなポート名そのままのアクセサがあるので、読み取ったり代入したりすると操作できる。
なおarduino-firmata npmを単純にextendしただけなので、arduino-firmataのdigitalWriteやanalogRead等の関数もそのまま使える。

var LittleBitsArduino = require('littlebits-arduino');

var arduino = new LittleBitsArduino();
arduino.connect(); // use default Arduino
// arduino.connect('/dev/tty.usb-device-name');

arduino.on('connect', function(){
setInterval(function(){
var d0 = arduino.d0; // true or false
var a0 = arduino.a0; // 0~1023 analog input
var a1 = arduino.a1; // 0~1023 analog input

console.log([d0, a0, a1]);

arduino.d1 = d0; // digital output
arduino.d5 = a0/4; // 0~255 analog output
arduino.d9 = a1/4; // 0~255 analog output
}, 100);
});


Ruby用

Rubyでlittlebits操作するのはどうやるのかな、と思って検索したらlittle_bitsというgemがあって、node版ではこれのインタフェースを参考にさせてもらった。ほぼ同じ雰囲気で使える。

あと、中を見たらで自分が作ったarduino_firmata gemが使われていて、入力ポートを読むとか足りない機能があったのでプルリクしておいた。