Sunday, August 31, 2014

jQuery Memo

jQUeryについてのメモ。正直、まともに勉強したことないからググる率高いのん…(;ω;

selector - scriptタグ

セレクタの使い方。<script id="vs" type="x-shader/x-vertex">...</script>…こういうタグを取得した場合こうなる。続いてtype属性の値を取得したい場合はattr(name)を使う。

var el = $('script#vs');
el.attr('type');

Written with StackEdit.

Friday, August 22, 2014

NodeBB on Windows8

公式のインストールガイドでまさかのOSXがない…!ので、やむをえずWindows8(on Surface 3 Pro)にインストールする。

事前インストール

インストール

redisサーバーを起動させておく。

アプリにまんまStart Redis Serverってあるから、それを実行したけど激しくかっこ悪いorz

ターミナル(ckw x Nyaos)開いて、粛々とコマンドを打つ。

$ git clone https://github.com/NodeBB/NodeBB.git
$ cd NodeBB
$ npm install

最初の起動では初期セットアップを行う。

$ node app.js

全部デフォルトのままでいいよって書いてあったが流石に管理者アカウントくらいは設定。インストール時に幾つかwarn レベルの警告が出たけど、中でもこれ大丈夫か?ってのが1つ。

arn: No administrators have been detected, running initial user setup
(node) warning: possible EventEmitter memory leak detected. 11 listeners added.
Use emitter.setMaxListeners() to increase limit.
Trace
    at ReadStream.EventEmitter.addListener (events.js:179:15)
    at ReadStream.Readable.on (_stream_readable.js:667:33)
    at new Interface (readline.js:124:11)
    at Object.exports.createInterface (readline.js:38:10)
    at read (c:\Users\Yukaary\home\project\nodebb\NodeBB\node_modules\prompt\node_modules\read\lib\read.js:45:23)
    at EventEmitter.prompt.getInput (c:\Users\Yukaary\home\project\nodebb\NodeBB\node_modules\prompt\lib\prompt.js:502:3)
    at get (c:\Users\Yukaary\home\project\nodebb\NodeBB\node_modules\prompt\lib\prompt.js:321:12)
    at c:\Users\Yukaary\home\project\nodebb\NodeBB\node_modules\prompt\lib\prompt.js:280:7
    at iterate (c:\Users\Yukaary\home\project\nodebb\NodeBB\node_modules\prompt\node_modules\utile\node_modules\async\lib\async.js:134:13)
    at Object.async.eachSeries (c:\Users\Yukaary\home\project\nodebb\NodeBB\node_modules\prompt\node_modules\utile\node_modules\async\lib\async.js:150:9)

イベントエミッタ―のリスナー制限数が10になってる?警告が言う通り、最大リスナ数を上げればいいのかな。試用してて動きが怪しかったらやり直してみよう。githubのmasterブランチってそもそも安定してるか疑わしいのがちょっとね…。

初期セットアップが終わったら、もう一度

$ node app.js
info: NodeBB v0.5.0-2 Copyright (C) 2013-2014 NodeBB Inc.
info: This program comes with ABSOLUTELY NO WARRANTY.
info: This is free software, and you are welcome to redistribute it under certain conditions.
info:
info: Time: Fri Aug 22 2014 23:12:05 GMT+0900 (東京 (標準時))
info: Initializing NodeBB v0.5.0-2
info: * using configuration stored in: c:\Users\Yukaary\home\project\nodebb\NodeBB\config.json
info: * using redis store at 127.0.0.1:6379
info: * using themes stored in: c:\Users\Yukaary\home\project\nodebb\NodeBB\node_modules
warn: You have no redis password setup!
morgan deprecated morgan(options): use morgan("default", options) instead src\logger.js:128:22
morgan deprecated default format: use combined format src\logger.js:128:22
info: [user.startJobs] Registering User Jobs
info: [meta/css] Minifying LESS/CSS
info: [themes] Compiling templates
info: [themes] Successfully compiled templates.
info: NodeBB attempting to listen on: 0.0.0.0:4567
info: NodeBB is now listening on: 0.0.0.0:4567
info: [meta/css] Done.
info: [meta/js] Successfully minified.
info: [meta/js] Retrieved Mapping.
info: [meta/js] Compilation complete
info: NodeBB Ready

なんやかんや出てきたけど、見た感じ動いてそう。nodeは今のところ手順通りやったけど動かない!のが少ないからいいな。削除も楽だしね。

試用

http://127.0.0.1:4567/ にアクセス。表示された!

以下、使ってみた時のメモ.


profile画像をアップロードできない。デフォルト画像を保存して再アップロードしても無理だからバグかな?
これっていわゆる掲示板ツールみたいだな。トピックという単位で話題を管理でき、それぞれのトピックにスレッドを立ててやり取りするスタイル。デフォルトでは12のトピックが定義されている。

ログインしている他のユーザに対して1:1のチャットを始めることができる。チャット開始時にリアルタイムで通知が来ている(小さいびっくりマークだけども)

尚、投稿の際の記法はMD形式っぽい。これは地味にありがたい。


手軽にコミュニケーションサイトを立ち上げたいときには、結構いい選択肢かもしれない。

Written with StackEdit.

Webアプリ開発者向けの基本Javascriptツール

InfoWorldのSlideshow で紹介されていたのでなんとなく。

自分が知らないツールがたくさんある現実。

Meteor

Javascriptで書かれた多Web Application Frameworkか。Backbone.jsやAngular.jsのお仲間なのかな。

気になった特徴が幾つか。

2.Live page updates.

templateさえ書いてしまえば、データベースで変更があったときに自動更新。なんてこった。push型通信がデフォルトで実装されてるのかな。

3.Clean, powerful data synchronization.

RESTのendpointからデータをロードする必要がなくなっている。サーバー側のコードのようにデータベースへのアクセスを実現できる。

7.Fully self-contained application bundles.

1コマンドでアプリケーションをtarball形式にコンパイルできる。これをnode.jsが動いているサーバー上で解凍すれば、1コマンドで実行できる。こにより特定のホスティングプロバイダによる制約を受けずに済む。

8.Interoperability.

単純なDDPプロトコルを実装するだけで何でも(ネイティブなモバイルアプリから従来データベースまで?)Meteorに接続できる。

文字通り受け取ればRaspbery Pi使ってセンサ情報を取得、node経由でサーバーに送ろうとしている自分には朗報なのですが。

Epoch

d3.js をベースにしたチャート描画モジュールなのかな。d3.jsを直で触るのは色々つらいので最近この手のやつが幾つかある印象。

Raspberry Piで収集したセンサ情報を可視化するときに使ってみようかな。そのためにはnode.js > wiringPi でセンサ情報を継続的に取れないとな。後でwiringPi直で使った場合のSPI経由データ取得方法を調べよう…。

Web Starter Kit

google様謹製のWebApi開発ツールキット?。 開発するWebアプリがマルチデバイス(古いタイプのiPadとかAndoroid端末とか…)に対応するよう色々と便宜を図ってくるらしい。なんか面白そう。

reveal.js

htmlベースのパワポだっ。かっこいいなこれ。

RxJs

複数のデータストリーム(マウス操作、キーボード操作、tweet、etc…)を同時に監視して、ユーザの直接的な操作とは無関係にイベントを発生させる用のライブラリなのかな?

簡単に概要読んだくらいじゃ全容が分からないorz。後でもう少し詳しく読む…後で。

NodeBB

github

nodeで書かれたコミュニケ―ションWebアプリ。機能がとても豊富そう。何より、Chatがっあるぞっ Chartだーーーッ!

★簡単そうだったら自宅のOSXにインストールしてみようかな。

Odyssey.js

github

ブラウザ上で地図(map)を表示、簡単なコーディングでインタラクティブな操作を可能にするライブラリってことでいいのかな。旅行記なんかを作るときに使えるぜって書いてある気がする。既存のWebアプリにインタラクティブなMapを簡単に追加したりできるなら歓喜する人たちがいそうだ…。

PlayCanvas

WebGL Game Engineを使ったゲーム開発環境?
サイト見てきたけど、なんか凄い。ここまでやるか&できるのな…。

Deb.js

javascriptで書いたアプリのデバッグヘルパー。

SPIについてお勉強

Raspberry PI SPIによるアナログ―デジタル変換について

SPI

そもそもSPIって何ぞ? wiringPiを作った人のサイトで解説されてた。助かる(;ω;

SPI Serial Peripheral Interface

モトローラによって開発された同期型のシリアルクロック、双方向バス(マスター/スレーブ)のインターフェース。

データはクロック信号(Wire1)に同期して送信(Wire2)される。また、データを受信するワイヤ(Wire3)があり、最後にチップセレクトとして動作する4本目のワイヤ(Wire4)がある。送信/受信それぞれにワイヤとピンが用意されるからfull-duplexである。4本のワイヤを使うので4-wireバスとも言われる。

master/slave方式により、バス上に存在するデバイスではどれでも他のデバイスにデータ転送を行うことができる。チップセレクトワイヤは複数存在することができ、同じSPIバス上で複数のデバイスと接続できる。

Raspberry PIはマスターモードのみ実装されており、2つのチップセレクトピンを持っているため、2のSPIデバイスを同時に制御できる。(ただ、いくつかのデバイスは独自のサブアドレススキームを持っていることがあり、この場合はもっと多くのデバイスを設置できる。)

SPIについて覚えておかなければならないのは、バイトデータを受信するために、バイトデータを送信しなければならない点にある。

MCP3002 2channel, 10-bit analog to digital converterの例。

このチップはSPIクロックを内部ロジックを動かすために利用している。MCP3002には4bit長のコマンドのみで十分だが、帰ってくるデータ長は最後のコマンドビットの後ろから数え始めて10bitだ。従って実際に通信するときは2byteのデータを送り、2byteの結果を得ることになる。データは5bit目から始まって10bit後ろまで続いている。従ってクロックが動作している間、MCP3002との間では2byteを送り、2byteの結果を取得、この結果から10bitぶんのデータビットを取得する必要がある。


ここまで読んでrubyのpi_piperで書かれたサンプルコードの意味が分かった。

PiPiper::Spi.begin do |spi|
    raw = spi.write [0b01101000,0]
    value = ((raw[0]<<8) + raw[1]) & 0x03FF
end

spi経由でMCP3002に送っているのはコマンドビットである4bitのみ。上の例だと1001(先頭ビットは0固定)。6bit目からは返信されてくるデータビットのためにダミーバイトを11bit送っている。

データの送受信が同時に実行されているから、結果はrawに入ってくる。最初のバイトの先頭4byteは意味がないので8bit左シフトした上で不要な部分を論理積(0x3FF)で排除し。raw[0]ってやると16bit長のデータが得られるっぽいな。ruby内部でint型は16bitだからってことか。

Thursday, August 21, 2014

raspberry pi スイッチでLED点灯

練習がてらブレッドボード上で回路を組んで、前回同様にrubynodeで実装してみた。

ruby

require "open3"

def readswitch
    out, err, status = Open3.capture3("gpio read 6")
    return out
end

def blink(value)
    puts "LED would be set on " + value
    Open3.capture3("gpio write 1 " + value)
end

Open3.capture3("gpio mode 1 OUT")
Open3.capture3("gpio mode 6 IN")

loop {
    led = readswitch()
    blink(led)
    sleep 0.1
}

node

var Q    = require('q');
var exec = require('child_process').exec;

exec('gpio mode 1 OUT');
exec('gpio mode 6 IN');

function blink(value) {
    console.log('LED would be set on ' + value);
    exec('gpio write 1 ' + value);
}

function readswitch() {
    var deffered = Q.defer();
    exec('gpio read 6',
        function(error, stdout, stderr) {
            deffered.resolve(stdout);
        });
    return deffered.promise;
}

setInterval(function() {
    readswitch().then(blink);
}, 100);

nodeでは相変わらずQ(deffered)を使いループに代わりにsetIntervalを使っている。慣れるとこちらのほうが違和感が無くなってくる不思議。

回路図あげたいなどうしようかな…。

Written with StackEdit.

raspberry pi B+ LED x PWM

raspberry pi B+ でPWMを使って明るさの制御をやったときのメモ.

rubyとnodeでそれぞれサンプルコードを記述。配線はごく単純にLED, 抵抗, ケーブル2本。

ruby

require "open3"

out, err, status = Open3.capture3("gpio mode 1 pwm")
out, err, status = Open3.capture3("gpio pwm-bal")
out, err, status = Open3.capture3("gpio pwmr 1024")

0.step(1023, 8) do |x|
    Open3.capture3("gpio pwm 1 " + x.to_s)
    sleep 0.1
end

0.step(1023, 8) do |x|
    Open3.capture3("gpio pwm 1 " + (1023-x).to_s)
    sleep 0.1
end

rubyにはwiringpiのモジュールがあってgemでインストールできるのだけど(参考)、まだModel B+に対応していないぽい。仕方がないので直接外部コマンドを叩くことにした。

  • gpio mode 1 pwm …GPIOピン1をpwmモードに変更
  • gpio pwm-bal …pwmの制御モードを「バランス」に設定
  • gpio pwmr 1024 …pwmの制御幅を「1023」に設定
  • gpio pwm 1 x …pwmによる電圧調整(厳密には電圧一定でパルス調整なんだろうけど)

node

var Q = require('q');
var exec = require('child_process').exec;

// この3コマンドもdefferedで実行制御したほうがいいかも.
exec('gpio -g mode 18 pwm');
exec('gpio pwm-bal');
exec('gpio pwmr 1024');

var step = 8;

function inc_intensity() {
    var deffered = Q.defer();
    var intensity = 0;
    var id = setInterval(function() {
        intensity += step;
        if(intensity > 1023) {
            clearInterval(id);
            deffered.resolve();
            return;
        }
        exec('gpio pwm 1 ' + intensity);
    }, 100);
    return deffered.promise;
}

function dec_intensity() {
    var deffered = Q.defer();
    var intensity = 1023;
    var id = setInterval(function() {
        intensity -= step;
        if(intensity < 0) {
            clearInterval(id);
            deffered.resolve();
            return;
        }
        exec('gpio pwm 1 ' + intensity);
    }, 100);
    return deffered.promise;
}

inc_intensity().then(dec_intensity);

やってることはrubyのコードで一緒。ただし、nodeは非同期で動いちゃうので、Q(deffered)を使って明るさの制御順を指定している。最初はだんだん明るくして…次にだんだん暗くする。

まとめ

単純なプログラムだけどruby, nodeそれぞれで特色が出るなぁ。rubystepを使いつつnodedeffered使えたら最高なんだけど…coffee script、type script使えって話ですかね。

Written with StackEdit.

Sunday, August 17, 2014

node.js q promise

node.jsでpromise(deffered)を使いたかったので現状どうなってるのか簡単に調べた。
まず、本家のPromiseだけど安定板のv0.10.30ではまだサポートされていない。仕方ないのでlatestv0.11.13を使って試してみる。

node.js Promise

サンプルコード。
function promiseA() {
    return new Promise(function(onFulfilled, onRejected) {
        setTimeout(function() {
            console.log('I execute first.');
            onFulfilled();
        }, 1000);
    });
}

function promiseB() {
    return new Promise(function(onFulfilled, onRejected) {
        setTimeout(function() {
            console.log('I execute second.');
            onFulfilled();
        }, 5000);
    });
}

function promiseC() {
    return new Promise(function(onFulfilled, onRejected) {
        setTimeout(function() {
            console.log('I execute third.');
            onFulfilled();
        }, 5000);
    });
}


promiseA().then(promiseB).then(promiseC);
// ダメ. 関数を実行してしまい、promiseBとpromiseCが同時に動く.
//promiseA().then(promiseB()).then(promiseC());
こんな感じか。
最初はnew Promise(..)で取得したオブジェクトを直接thenに指定してしまい、promiseB, promiseCが同時に実行されてはまる。
お馬鹿な例。
var promiseA = new Promise(function(fulfill, reject) {
    setTimeout(function(){ console.log('first.') },1000);
});
var promiseB = new Promise(function(fulfill, reject) {
    setTimeout(function(){ console.log('second.') },1000);
});
var promiseC = new Promise(function(fulfill, reject) {
    setTimeout(function(){ console.log('third.') },1000);
});

promiseA.then(promiseB).then(promiseC);
newした瞬間に処理実行されちゃってるからな。このnew、地味にこういう誤解を招くと思うんだけど…。

Q

node.jsの現バージョンであるv0.10.30はPromiseをまだ実装していない。ぐぐったらQがデファクトっぽい扱いだったのでこちらで同様の事を試みる。

サンプルコード
var Q = require('q');

function one() {
    var deffered = Q.defer();

    setTimeout(function() {
        console.log('execute one.');
        deffered.resolve();
    }, 1000);

    return deffered.promise;
}

function two() {
    var deffered = Q.defer();

    setTimeout(function() {
        console.log('execute two.');
        deffered.resolve();
    }, 1000);

    return deffered.promise;
}

function three() {
    var deffered = Q.defer();

    setTimeout(function() {
        console.log('execute three.');
        deffered.resolve();
    }, 1000);

    return deffered.promise;
}

one().then(two).then(three).done();
関数内でdefferedを作り、返り値をdeffered.promise、処理完了をdeffered.resolve()で伝えてあげればいいみたい。こっちのほうが凄いしっくりくる。node.js/Promisethenable使えば似たような感じになりそうだけど、いちいち自前でnewを書くのがちょっと面倒に感じた。