beaglebone black GPIO ピンの謎

GPIOというのはGeneral Programmable IOという意味でつまりは、用途に合わせて設定できる入出力ピンということだ。 ソフトウエアで設定すれば入力ピンにも出力ピンにもなるという便利もので、40年前に電気工学を勉強した自分にとっては夢みたいなハードウエアなのだ。
BeagleboneBlackにはこのGPIOピンが69pinも用意されている。(とはいうもののHDMIとeMMC support用にリザーブされているピンもあるので全部が即使える、というわけではない. それでも30本以上はありそうだ) デジタル入出力のほかにもアナログ入力や出力に使えるピンも何本か用意されている。

ただ、出力ピンにした場合、その出力電流はソースで4ミリアンペア、シンクで6ミリアンペアとなっており、それほど大きな電流が流せるわけではない。 ちなみにArduino は 各ピン20mA、ピントータルで400mA。 Derek Molloy さんのyoutube ビデオでは、これを鑑み、LEDを点灯させるのに小さなトランジスタをかましている。(http://www.youtube.com/watch?v=wui_wU1AeQc)

これが正解だと思うのだが、 Adafruitのサイトのチュートリアルでは初心者を考えたのか、トランジスタを省略し、470オームの抵抗をLEDに直列にいれて、これを直接駆動している。 あのSimon Monk氏が書いているTutorialで、470オーム以下の抵抗値は使わないように、という指示がある。 この場合、 普通に売っているLEDのフォワード電圧が20mA通電時で1.85V~2.5Vと考えると(3.3-2.0)/470~(3.3-1.85)/470=1.7mA~3.08mA. 一応4mA以下となるので、OKということらしい。写真を見ると、これでも結構明るく点灯している。

最近みたこのサイトの場合はもっと過激で、50~100オームの抵抗を指定している。 (ちなみに作者はMaker: からRaspberry PiやBBBの入門書も出版していて、ちらっと見た限りではこの書籍の中でも100オームを指定していた。)
100オームを使った場合だと、電流量は 最悪 12mA程度になる。 50オームだとその倍で、20mAになる。さらに、100オームの場合だとフォワード電圧が飽和しないので、実際には12mA以上になるはずで、当然ICメーカーの指定仕様は超えている。 平気なのか、と思うが、実際に数分だけやってみたところ平気だった(おい) ただし、これはTIのチップの設計および現物が仕様に対してマージンを持っている、ということで、、LED1個点灯くらいならまだしも複数個点灯させるのはやはりまずいだろ。

20年前の電気屋の頭でLEDには20mAとはいかなくてもその半分くらいは流したいとおもっっているので、出力ピンにはNPNトランジスタをかませる、というのが、今の自分の結論。

3者三様、LEDの点灯回路

3者三様、LEDの点灯回路

driving-led2

Circuitlab のDCシュミレーションでの計算値。

boneScriptで遊ぶ

Beagleboneblackを電子工作用にリザーブしたので、Angrstrom Linux についてくるbonescriptで遊んでみた。(Debian wheezyのイメージになっていたeMMCにAngstromの最新イメージを改めて焼き直した。) 普通javascriptといえばWEBクライエント用のプログラム言語だし、 C++やJavaなどいじっているプロの方から見るとToy Lanuguageなどとバカにされがちだけれど、自分のような日曜プログラマにとっては非常に重宝するtool なんである。 boneScriptは、このjavascriptをサーバー側で使えるようにしたnode.jsというプログラム上で走る。 BBBのハードウエアをJavaScriptの文法で操作してしまおうという優れものだ。 node.js は一般的にはwebサイトのサーバー側を能動的に管理するような形で使われるのだと思うけれど、boneScriptと組み合わせるとPC上のプログラミング言語として機能する。

JavaScriptの特徴としてプログラムの非同期実行ということがあげられる。jQueryの使い方で一度はまったことがあって、 関数によっては前に呼び出して得たreturn情報を次のステートメントで使うためにはちょっと待てという感じでプログラムの流れをブロッキングするかコールバック処理を使う必要がある。 逆に言えばコールバックを使ってのイベント処理には力を発揮する。

その特徴を使って以下のようなbonescriptをいたずら書きしてみた。BBBに実装されている4つのLEDをてんでバラバラに明滅させる、というだけのプログラム。

//#!/usr/bin/node
//uncomment the above line and chmod +x  to make it shell executable.
//This program will randomly turn on/off four on board LEDs.
// 11/28/2013
//setup()
  var b = require('bonescript');
  var LEDs=['USR0','USR1','USR2','USR3'];
  for (var i=0; i < LEDs.length;i++) b.pinMode(LEDs[i], b.OUTPUT);

//loop();
    for (var i=0;i < LEDs.length;i++) animateLED(LEDs[i]);

//helpers
function animateLED(led){
    function toggleLED(led){ //randomly toggle LED
        b.digitalWrite(led,Math.floor(Math.random()*2)?b.HIGH:b.LOW);
    }
    function randomTimer(){ //randomly set timer between 0~199msec)
        return Math.floor(Math.random()*200);
    }

    setInterval(function(){toggleLED(led);},randomTimer());
}

Arduino の流儀に従って、setup 部分と loop部分を書いてみたが、ごらんのとおり、while/until 的なloopなどしていない。 animateLED()という関数を4回呼び出したあとは、それぞれの関数インスタンスが勝手にタイミングを作って繰り返しの明滅を行っているわけで、それぞれ非同期実行されている。

ところで、
上のスクリプトはCloucd9というIDEから直接実行させる他にも、command line でも

node randomLED.js

というように、実行可能。 いちいちnode を指定するのが面倒ならば、 プログラムの一番上の行にシュバング(#!)を追加してNodeプログラムだということを明示し、

#! /usr/bin/node

randomLED.js を実行可能としておけばプログラム名を指定するだけで実行できる。

$ chmod +x rondomLED.js
$ ./randomLED.js

もともとNode.jsがPHPと同じようにサーバー側のスクリプトを実行することを目的に書かれていることを考えると、bonseScript+Node.jsだけでハードウエアをリモートコントロールできるアプリが書けそうである。