カテゴリー「Node」の3件の記事

2015年7月17日 (金)

EdisonのPWMをmraaライブラリーで動かす

mraaライブラリーでEdisonのGPIOは動いたが時間が不定(6/20/2015)
 Edisonプロジェクトの進展は相変わらず遅々としている。理由は簡単で、Edisonで具体的に何を作るかが決まっていないからである。しかし迷っていても先には進まない。無理やり目標を決めて進むことにする。結局、EdisonもRaspberryPiと同じ、パンチルトの出来るウェブカメラに仕立てることにした。まあ監視カメラはいくつあってもかまわない。何かの役に立つだろう。05p7167205

 前回にご紹介したサーボモーター2つでカメラをパンチルト出来る操作キットをEdisonのPWMで動かすことにする。ウェブカメラそのものは、既にEdisonで無線LAN経由で動いているが、サーボモーターの方はAVRで動かしただけで、Edisonではまだである。

 このあいだのEdisonマザー基板には、秋月で調達した1.8~5Vのレベルシフター(FXMA108)が仮止めしてあるが、配線はしていない。Edisonのピン出力は1.8Vなので、PWMで市販サーボを動かすためには、このシフターが必要である。

05p6247158  久しぶりのハンダ付けである。とりあえずEdisonのPWM(4本ある)と、ジャイロセンサーなどに使うI2C(これは2本)をアートワークした。5V出力は、20ピン2段のピンソケット(メス)をマザー基板に実装し、こちらからジャンパー経由で実験できるようにする。

 EdisonのGPIOピンの制御は、定番のmraaライブラリを使う予定だ。待ちきれないのでPWM部分だけ配線してすぐにテストを始めた。いきなりPWMのテストはきついので、スイッチサイエンスのページのnodeソースを参考にGPIO(12)を使ってLチカを最初にやる。ここはたまたまPWM0とピンが同じなので新たに配線を追加する必要がない。

 nodeは、感心にもmraaのライブラリーが用意されている(require('mraa')で動く)。Edisonのviでソースコードを入力する。これくらいの入力なら大した時間はかからない。早速動かしてみる。

 オシロでまず出力を確かめる。おおー、出た出た。おやあ、パルスが時々動かないときがある。それより不審なのが、レベルシフター(FXMA108)を通しているのに、LEDの点き方が安定しない。オシロで見るとパルス状になっている。

03p7157201 このシフターの電源供給力はスペックによれば、ピン単位50mA(全体では100mAまで)もあるので、10mAのLEDぐらい楽々なはずなのだが、いかにも頼りない波形だ。それに、点滅の間隔がかなりでたらめなのである。0.3秒で動いていると突然、点滅が止まったりして一定しない。

nodeでは正確なLチカは出来ないのか(6/26/2015)
 あわてて、ウェブにお伺いをたてる。やっぱり時間は正確にはならないと書いてある。しかし、msレベルならともかく、こんなに不正確なのだろうか。現在の300msの間隔でも正確なパルスになっていない。Edison用のこのYocto Linuxは、一般のLinuxと同様リアルタイムOSではない。同時に沢山のプログラムが動いているので、正確な待ち時間は作れない。

 考えてみたら、nodeのsetTimout( タイムアウトで呼ぶ関数, 待ち時間ms)は、再帰関数的な使い方で、確かに、そのあいだにコンソールに出力はしているし、無線LANの応答もしているだろう、LinuxはリアルタイムOSではないからそれまでと言ってしまえばおしまいだが、こんなに時間がまちまちなのはどうも納得できない。

 Yocto LinuxにはリアルタイムOSにするためのオプション(PREEMPT_RTパッチ)があるらしいが、カーネルの再構成が必要である。そんな大げさなことはできないし、これで解決するとも思えない。

 nodeではだめなのだろうか。いろいろ資料を探す。console.log()などのコンソール出力を省略すると、少しはまともになるが、時々、ずっこけて点滅をさぼるときがあることは変わらない。時間に厳密なPWMではこんなことは起きないだろうが、気になると先に進めない性分である。PWMそっちのけで色々ウエブを探し回る。

Edisonのクロスコンパイル環境の整備が難航(6/27/2015)
 しかし、この状況を説明してくれるサイトは見つからなかった。そのうちこれにばかりこだわるのも時間の無駄のような気がして、正式なCでプログラムを組んでみようということになった。CにはCPUループを使ったsleepなどの時間待ちの標準関数があり、nodeのようなプロセスをまたがるような待ちではないので少しは正確なはずだ。

 Edisonでのプログラム開発は面倒(エディターがviしかない)なので、このあいだやったPCのUbuntuで、Edisonのクロス開発をすることにする。ところが、Ubuntuに構築したはずのC言語開発環境をどう使ったらよいのか分からないのである。

 Ubuntuに入れたのはEdisonカーネルの再構成のための環境で、Makefileで動く。情けないことに、ここにmraaのライブラリをどうやって組み込むのかがわからない。下手なライブラリのインストールで、折角作ったカーネル再構築の環境がおかしくなるのは避けたい。

 ということで、これとは別に簡単なgccのクロス開発環境をこのサイトの案内で作ることにした。ここでEdisonの実行形式のプログラムまで作り(ここなら全画面エディターのgeditが使える)、Edisonへの実行ファイルの転送は、scpというコマンドを使う。

 順調にインストールが済んだので、サンプルプログラム("Hello World")を入力し、gccを動かしてみる。コンパイルが出来て実行ファイルが作られた。scpでEdisonに送ってみる。これも簡単に送れて、Edisonで実行すると無事"Hello World"が出た。よーし、好調だ。

 ところが、何故か肝腎のlibmraaのコード一式が別のところにインストールされてしまってリンクできない。/sysrootが決め手だったというサイトの言葉がカギなのだろうが、このあたりの技術レベルは見よう見まねレベルなので先に進めない。mraaが入らないのでは、何のために別の環境を作ったのか意味がないことになってしまった。

/sys/class/gpioでGPIOピンが動かない(6/30/2015)
 まあ、クロス開発ができなくても、Edisonの中でもやろうと思えばプログラム開発はできる。Edison内でのmraaライブラリは、opkgで大分前にインストールに成功している。エディターさえ我慢すれば、規模の大きなプログラムでない限り大丈夫だ。

 開発環境を調べているうち、さらに/sys/class/gpioという仮想ファイルを使えば、簡単にGPIOピンの操作が確認できることがわかった。脱線だがハードの状況を調べられる複数の方法があるのはありがたい。早速これを試してみる。

 ところが、これがさらに暗礁に乗り上げて、一歩も先に進まなくなったのである。肝腎のGPIOが想定通り動かない。ピンの定義であるexportと、direction(入出力)の定義は問題なく済んでも、実際の値(value)が入らない。mraaとは違う枠組みで動いていると思うのだが、オシロで見る限り、ピンが動いていない。

 しかも、汎用的なピンであるはずのGPIO40番(mraaでは37番、ややこしい)は4Hzで発振している。EdisonのI/OピンはUART以外にはどこも接続されていないはずだが、どうもすでに定義済みのピンがいくつかあるようで、export自体がエラーになるピンもある。わけがわからない。

 ウェブで心当たりを探すが、このあたりを詳しく解説したサイトを見つけることができない。ちょうどソフトとハードの中間の世界なので詳しい資料が不足している。

 そのうち、node.jsで不正確ながら動いていたGPIO(20)ピンもオシロで反応しなくなった。うーむ、これはどうしたことなのだろう、ハードだろうか。どうもGPIO(40)の発振といい、Edisonのハードそのものがおかしくなっている疑いが強くなってきた。

Edisonブレークアウト基板をもうひとつ買ってセットアップする(7/4/2015)
 久しぶりに秋葉原に寄る。迷っていたが、もう一台のEdisonを買うためである。少し見ないうちに、秋月電子の界隈は大きく変わっていた。向いの空き地に立派なビルが建って人の流れが変わっている。しかしメイド喫茶の客引きと外国人の団体は相変わらずで歩くのが煩わしい。

 今日は、本体以外にI2Cのコンバーター(FXMA2102)を買うことも目的の一つだ。このあいだの8チャンネルのレベルシフター(FXMA108)はプルアップが出来ないのでI2Cは接続できないということを知り、これを調達する。秋月の商売上手はさすがである。I2Cの配線をしていなかったのは幸運というか先見の明があったというか。

06p7167210 Edisonは本体だけでなく、ブレークアウト基板も一緒に揃える。前のブレークアウト基板は、充電中を示すLEDが点かなくなっているからだ。I2Cで何をやるかは決まっていない。I2Cで制御できる多チャンネルサーボ基板があるというので、これは将来のロボット構築に向けた準備でもある。

 帰宅して早速、2号機のEdisonブレークアウト基板をセットアップする。一応、nodeのウェブカメラサーバーが動くところまで作る。2回目なので作業は順調に進む。今度のYocto Linuxのイメージには、既にmraaライブラリがインストールされていた。

 ついでに、前記事で紹介したIPアドレスの固定化のためWiFiのwlan0をいじる。起動スクリプトでIPアドレスの設定をDHCP側にお願いするのでなく、単純に固定IPの設定をするだけである。簡単に変更できた。node側はこのアドレスで決め打ちにする。テストする。問題なく動いた。

 マザー基板に差すには、2号機にもピンソケット(オス)を実装する必要があるが、その前に、 サンハヤトのスルーホールに差しこんで使うジャンパーを活用して、2号機での/sys/classのGPIOピンの状況を調べ始めた。すると驚くべきことがわかってきた。

何と使えないGPIOピンが沢山ある(7/6/2015)
 これは驚いた。2号機でもおかしいのだ。使えないピンが続出した。ところがウェブサイトに出ているピンを試すとこれだけは動いている。サイトで使っているピンは大丈夫なのだ。一体これは何だ。

 ちょっと脱線になるが、しらみつぶしに、GPIOピンを調べて行った。驚くべきことに、作動するピンと動かないピンがあることがわかった。 Newedisonlist

 動かない状態は、2つあって、一見、sys/class/gpioXXが動いているように見えて(in/outのdirectionと1/0のvalueをノーエラーで受け付ける)、ピン上では何の変化もないもの。

 もうひとつはgpioXXの仮想ピンの定義が、最初からdevice busyでexportを受け付けないものの2種である。このことは、ウェブサイトを探したが、どこにも書いていない。

 サイト(Qiita)でまとめていただいたEdisonブレークアウト基板の早見表に、今回のテストの結果を加えてみた。GPIOとしてまとめたピンのところである。備考のところの赤が動かないピンで、青が動くピン、備考のところにこのGPIOピンに重複定義されている機能名を付加した。

 これを見ていると、どうも、Yocto Linuxの立ち上げで動かしたデーモンあたりがこのピンを定義し、そのあと正しくピンを解放していないのではないかと思われる状況である。動かないピンは特定の機能に集中している。UARTピンが2つともbusyなのは当然だが(それでもUART1は使っていない)。

カメラを動かしたEdison1号機にヒートシンクをつけるが熱暴走(7/7/2015)
 動作がおかしくなっている一号機でもGPIOピンの状況を調べた。全部のピンは調べなかったが、調べた限りでは(5~6本)すべて同じ状況だった。

 ついでに、2号機に加えた変更(IPアドレスの固定化)をこちらにも与えてテストする。カメラを動かしてみる。問題なく動く。ただ、こちらの方が少し熱を持つようだ。 01p7127196

 温度計で測ってみると、50℃を軽く超える。不安になったのでヒートシンクをつけてみた。 温度上昇は少し鈍化したが、60度近くになる。1時間程動かしたところでハングアップした。うーむ、ヒートシンクだけでは長時間には耐えられない。冷却ファンが必要かも。

 しかし、こんなに熱かったかなあ。前はもっと低いところで安定していた。1号機には何か別の問題がある可能性が高い。GPIO(37)で4hzの発振信号が続いているなど、I/Oピンに不審な動きが多すぎる。

1号機でシリアルを失ったのは、やはりショートか(7/10/2015)
 ヘッダーピンの実装のため、Edisonの2号機をブレークアウト基板から外した時のことである。2号機の裏面が絶縁ラベルで覆われている。おやあ、 1号機は違っていたような気がする。確かめてみる。

02p7137199  やはり、そうだ。1号機の裏面は表と同じようにアルミ生地のままプリントされている。ふーむ、何故変わったのだろう。閃きが走った。以前、この裏面とブレークアウト基板のピンヘッダーの配線部が接触していて、あわててはみ出たピンをニッパーで切り取ったことを思い出した。

 そうか、当研究所で起きた事故が他でもあったのだ。それで、ここの表面が絶縁されるようになったのだ。シリアルが動かなくなったのは、このショートに違いない。

やっとEdisonでPWMが動いた。nodeのLチカも正確になった(7/14/2015)
 道草を食っていたが、やっと2号機でPWMを実験する気運が盛り上がってきた。実はmraaのPWMの操作は実に簡単で、ピンを初期化した後、周期(usか秒)とduty比を整数と浮動小数で設定するだけである。

Edison_pwm サンプルコードはここを参考にさせてもらう。サーボモーターはPWMで、一般的な仕様では周期は10から20ms。仮に15msとすると、大抵のサーボは0.5msから2.5msのパルスが動作範囲である。このduty比は0.033から0.166である。この間で動かせば、サーボが最大幅動く。中点は、1.5/15 = 0.100である。

 Cソースの入力は10分もかからない。コンパイルも一瞬で終わる。問題なさそうである。本体のサーボに接続する前に、オシロにレベルシフターの出力を入れてテストする。

 恐る恐る、コンソールからプログラム実行のキーを入力する。おーし、プログラム通り0.5msパルスが1秒ごとに少しづつ増えて2.5msまで進んだ。コンソールにもduty比の数値がならぶ。浮動小数点が気楽に扱えるというのは、フラッシュの少ないAVRと違って贅沢なものだ。

 いやあ、ここまでが長かった。とりあえずはオシロ上だけだがEdisonでPWMが動かせることを確認した。今はPWMの1チャンネルだけだが、コンソールからパンチルトの2チャンネルのPWM値を入力し、自由に2方向にカメラを動かすことを次のステップにすることにしよう。

 勢いに乗って、このあいだの 1号機では不正確だったnodeのLチカプログラムを2号機でも動かしてみた。これが何と、全く正確にパルスが生成されたのだ。暫く動かしていても、パルス幅が乱れることは全くない。

 何ということだ。時間が不正確なのは、nodeのsetTimoutなどの関数ではなく、1号機の別の原因によるものだった。今のところ、ハードかソフトかはわからない。動画ストリーミングで高熱になるのも何かこれと関係あるような気もする。

| | コメント (2) | トラックバック (0)

2015年5月18日 (月)

EdisonでIPアドレスを変数化した動画サーバーが動いた

 Edisonの無線動画サーバーソフトは、ウェブでいくつか紹介されている。そのうちnodeを使ったこのサーバーは軽くて具合が良いのだがWindowsでは動かない。ローカルネットの中のホスト名を拾い上げる機能(Avahi)をこのサーバーが使っているからである。Windowsのためには生IPアドレスをクライアント用のソースコード(index.html)にハードコーディングしてやる必要がある。

 EdisonはWiFiでネットとつながっており、IPアドレスは勝手に設定されるので、このままでは運用性が極めて悪い。iTuneのソフトをインストールすればWindowsでも動くようだが、このためだけにクライアント側をいじるというのは、どうも本末転倒で、元プロのソフト開発者としては受け入れがたい解決手段である。

Node

 そこでnodeの勉強も兼ねて、自分のIPアドレスが変わってもストリーミングサーバーが動くように、このサーバーのソフト改修にこのところ熱中していた。久しぶりのPCプログラミングである。ここは電子工作のブログで、PCのソフト開発はなるべくやらないはずだったのだが、行きがかりで止まらなくなってしまった。

 悪戦苦闘していたが、このほど、まがりながら、当面の目的を果たしたので、そのご報告とともに修正方法を紹介することにする。オリジナルはMITライセンスなので、改訂したソースの公開は問題ないと認識している。ただし、オリジナル同様、完全な無保証、無責任であることはご承知置き願いたい。

Linuxでのnodeとexpressのインストール(4/24/2015)
 久しぶりの大物、node.js(正式名)である。これまでのウェブプログラミングの概念を破る革新的な手法ということで、少し勉強してみる気になった。ただ、node.jsは近年、分派活動(io.jsというらしい)が始まったりして、ちょっと先行きが不透明だったが、つい先日統合されるというニュースが飛び込んできた。ウェブサイトにはおびただしい量のnodeの紹介ページが存在する。

 Edisonのサーバーがnodeの中のHTTPサーバー用のモジュールexpressを使っているので、まずはWindowsでnodeとexpressの学習を続けていた。その結果、概要がつかめてきたので、いよいよ、本題のEdisonサーバーの改修に移ることにする。

 Edisonの石はIntel AtomでOSはLinux(Yocto Linux)である。ここのエディター環境は貧弱(viしかない)なので、この上で開発やテストを続けて行くのはつらい。このためPCのLinux(Ubuntu14.04)にもnodeをインストールし、こちらで動作を確認していくことにした。

 nodeのLinuxでの導入ツールはapt-getである。この環境は強力で、Windowsに比べれば嘘のように簡単だった。あっと言う間にすべてのモジュールがインストールされた(node,express,npm)。動作を確認する。expressも問題なく動く。

Screen20150427

 うまくいったのは、Linuxの環境(nodeの生まれ故郷)ということもあるがnodeに慣れてきたということもあるだろう。薄紙をはがすように、expressの構造も見えてきた。レンダリングのツールはejs(enbedded java script、組み込みjs)を選ぶ。

 ejsを選んだ理由は、HTMLに近く可読性が高いことによる。jadeなど省力を狙ったものは別言語のようで扱いにくい。それにしても、nodeでの付加すべきパッケージはやたらと種類が多い。しかも、バージョンの変化が激しく、各所でバージョン違いでのトラブルが発生する。しかし経験を積んできたので事前に必ず確認するようにし失敗は少なくなった。

 Windowsで懲りたので、Linuxでは少し計画的に作業を進めることにする。結構道のりが遠い。下手をするとまた脱線する。少し細かいが、以下のステップで行くことにした。

1. Linux(Ubuntu)でNodeのインストールとテスト。

2.  同        expressのインストールとテスト。

3.  同        ejsのインストール。ここまでは済んでいる。

4. 外部コマンド(ifconfig )によるIPアドレスの取得。これはWindows(ipconfig)ではnodeで実現できている。ウェブにたくさん記事がある(ここやここ)ので簡単だった。Linuxでのテストはここで済ませる。

5. ejsを使ってクライアントファイルをレンダリングし、所定のIPアドレスに変更する部分の開発。ここまではUbuntuでやる。

6. Edisonにnodeの上記スクリプトファイルの持ち込み。

7. Edisonでのサーバーテスト。いきなり動画サーバーを動かさないで別サーバーでテストする。

8. Edisonでの動画ストリーミングのテスト

Linuxでのnodeの勉強は順調(4/25/2015)
 PC Linuxでnodeを復習する。久しぶりのLinux環境である。Linuxも昔に比べると格段に進歩している。ブラウザー(Firefox)も明らかにWindowsより早い。USBメモリなど周辺のI/O機器も何もせずに認識する。特にサウンド関係が全く手づかずで動いたのには感動した。YouTubeでクラシックを聴きながら作業する。快適だ。

 少しづつnodeとjs(JavaScript)が見えてくる。ただ、無料で読ませて貰ってケチをつけるのは少々気が引けるが、どの入門サイトも、サンプルコードの中の変数名やプロパティ、さらにオブジェクトにどうして同じような名前を付けるのだろう。

 オブジェクト指向言語の変数や関数は、ピリオドなどでいくらでも派生できるので、同じ名前をつけると致命的に混乱する。しかも、この変数名が予約語なのか、一般の変数なのかの区別は、すべてモジュールの原典にまで戻らないと分からない。解読するのに一苦労である。

 海外のものでも、fooとかbarという名前がやたらと使われ混乱することおびただしい。経験者には自明のことなのかもしれないが、初心者にとっては、どの部分がオブジェクトで、どれが変数で、どれがプロパティなのかはわからない。

//foo.js
exports.foo = 'foo';
//main.js
var foo = require('./foo')
console.log(foo.foo); // 'foo'

こういうサンプルを見せられて、いらいらしないで読み下せる人がいたらお目にかかりたい。

 こんな悪態をつきながら、少しづつサーバーの機能を増やしていく。お手本にしたのはこれ。このサイトは少しづつ、実例付きで、相当高度なところまで案内してくれるので嬉しい。このサイトのコードを参考に、テーブル表記や、POSTによるデータ入力、ejsによるフィルタリングなどの初歩的なことができるようになった。

LinuxでもIPアドレスの抽出は成功。grepの正規表現にはまる(4/28/2015)
 IPアドレスの抽出は、Windowsのnodeですでに成功している。nodeでの外部コマンド出力については、以下のサイトが親切だった(前に紹介したところと同じ)。
http://yosuke-furukawa.hatenablog.com/entry/2014/07/26/145814

 今のところ、コマンドの出力文字列から、IPアドレスを抜き出す方法は、grepを2回使っている。まず、該当アドレスの行を抜出し、それをさらにIPアドレスだけに絞り込む方法である。

IPアドレスを抽出する正規表現: [0-9]+(\\.+[0-9]+){3}   (\は不要な環境もある)

 これを何とか一段で出来ないか、色々サイトを漁って調べているが、プログラムでも書かない限り無理なようだ。しかし、久しぶりのこういうパズルのような開発は面白い。正規表現は奥が深い。

 Windowsでは、grepのバージョンを上げる必要があったが、さすが本家のLinuxである。Linuxでは何の問題もなく成功した。ただ、Edisonではコマンド出力のフォーマットがUbuntuとまた違うので気を付けないといけない。

 grepも方言が多い。Windowsでは成功してもLinuxで動くとはかぎらない。しかも、UbuntuとEdisonではOSが違うのでifconfigの出力も違い、別のやり方が必要である。エスケープ\のタイミングが微妙である。[^ ](ブランクでない文字)という表現に気が付くまで迷走した。今のところEdisonでは以下のコマンドで抽出に成功している。

ifconfig wlan0 | egrep -o 'addr[^ ]+' | egrep -o '[0-9]+(.[0-9]+){3}'

正規表現に慣れない方のために、少し説明しておくと、ifconfigの出力メッセージが以下の通りなので、
wlan0   Link encap:Ethernet  HWaddr fc:c2:de:3c:c4:23
   inet addr:192.168.1.13 Bcast:0.0.0.0 Mask:255.255.255.0
   UP BROADCAST ........(以下略)

 まず、addrから始まり、ブランクで終わる文字列を残す。つまり、addr:192.168.1.13が残る。次に、数字の0から9だけで構成される1つ以上(カギかっこのあとの+)の文字と.のあと同様に一つ以上の数値の組み合わせが3個ある文字列を抽出すると、addr:がとれて、めでたく、192.168.0.13となるわけである。

Edison_ipaddr

Edisonのサーバーはejsを使っていなかった(4/29/2015)
 いよいよ、Edisonのnodeストリーミングサーバーの解析に入る。久しぶりにEdisonを立ち上げて様子を見る。ここのexpressはV4であった。ウェブ上の資料はV3が多い。ソースは最新のテクニックを駆使しているようなので、理解するのに時間がかかる。

 そのうちEdisonのサーバーソースは、ejsを使っていないことがわかる。勘違いしていた。しかし、IPアドレスの埋め込みは必要なので、ejsは使わなければならない。Edisonのソースコードをさらに真面目に調べ始める。いや、この前のmjpg-streamerほどではないが複雑な構造だ。

require関数(と呼ぶのか)の新しい形に戸惑う。

require(パス名).serveIndex(app,function(){ });

というステートメントが理解できない。いったいこれは何だ。

 調べた結果、serveIndexという関数が、別のところで定義したプライベートな関数で、その定義場所が前のrequireのパスであるらしい。このステートメントでexportされた当該関数を実行している。やれやれ。

 node(というよりjs)が難しいのは、こんな感じで、ある名前が、オブジェクトなのか、プロパティなのか、メソッドなのか、また、既に出来ているモジュールの予約された変数なのか、それともプライベートな変数定義なのかは、一つ一つ調べていく以外に、分からないことにある。

 ディレクトリ構造が変わってもソースが動くように、かなり抽象化したコーディングになっているようで、とても複雑だ。結局、サーバーの構造を変えることはあきらめた。姑息な手段だが、このサーバーの中はそのままにしておき、クライアント側のディレクトリに用意されているindex.htmlだけを換えることにする。

 ファイルアクセスが発生するが、立ち上がりの時の一回限りだ。幸いnodeは、ファイルをアクセスするモジュールは完備している。サーバーの開始直後に、直接ejsのレンダリングで書き換えて入れ替える。

Node expressのインストール不調の原因解明(5/3/2015)

 Edisonのnodeサーバーの解析で壁にぶつかっているころ、思わぬところで別の進展があった。Windowsでnodeのexpressが入らない原因が判明したのだ。何かゴミが入っているのだろうと推測していたが、そのゴミが見つかった。

 たまたま別の調べものをしていて、Winでのnodeのワークディレクトリ直下に.npmrcというファイルを見つけた。その内容は、prefix=C\;\Users\NODE\Nodist\binというテキストである。この文字列は、これまでさんざん頭を悩ましてきた幻のC;ディレクトリチェーンと一致する。

 いつもはこの下のプロジェクト単位のディレクトリで作業していたので気付かなかった。これを誰が作ったのかはわからないが、このいかにもプリファレンスファイル臭い名前は間違いなくインストール時に悪さをしている元凶に違いない。

 これを消してもういちど、npmでexpressをインストールする。大当たりであった。変なディレクトリも作られず、順調にインストールが完了した。expressのコマンドはどうだ。よーし、ちゃんと動く。

 これでWin7のexpressは所定のところにインストールされコマンドとして働くようになった。めでたし、めでたしである。ささいなことだけれど、こういうトラブルが解決したときの爽快感は何ものにも代えがたい

あともう少しだが、うまく整形されない(5/9/2015)
  IPアドレスの抽出に成功したので、残るは、index.htmlの書き換えである。これも思わぬところで新しい手法が見つかった。ejsを使った置換を考えていたのだが、もっと簡単な方法があった。jsのreplaceメソッドを使う方法である。お世話になったこのサイトの最初の講義のところで紹介されていた。

 nodeのfsモジュールを使ってプロトタイプのindex.htmlファイルの内容を文字列に読み込み、 str = str.replace('/置換される文字列/g', IPアドレス); とやると、IPアドレスが、置換される文字列(@などを使った他にない文字列)のところに置き換わる。gはglobalの略でマッチするすべてを変換する。

 こういうところはjsは便利である。変換したあとこのstrをfsで書き出す。造作のない作業だ。早速Windows版でテストしてみた。見事に、該当の場所がIPアドレスに換わった。良いぞ。おや、最後のところで改行され(0x0A)、行が折り返されている。Windowsだから改行が残るのだろうか。もしかすると、HTMLの中の改行は無視されるので問題ないかも。

 まあ、あれこれ考えるより、この外部コマンドの末尾の改行をとってしまえば良いはずだ。というので、ウェブでまた「末尾の改行文字をとる」「java script」などで検索するとすぐ解決法が見つかった。同じreplaceメソッドで、replace('/\n/g','')という正規表現である。

 ところが、こいつがエラーになるのである。fsで読んだファイルの文字列はうまくいくのに、外部コマンドの出力は文字列ではないとはねられる。わけがわからない。文字列オブジェクトを新規に定義して、そこにコマンド出力を移し替えてもだめである。

 これはWindowsだけの現象ではないかと淡い期待を抱いて、Edisonにコードを持ち込み、実際に動かしてみた。危惧した通りEdisonでもindex.htmlファイルの中のIPアドレスは折り返された。さらに一縷の望みを抱いて動画サーバーを動かしてみる。残念、画像は表示されない。悔しい。あともう少しなのに。

ちょっとしたきっかけで遂に成功。いやあ難しいもんだ(5/12/2015)
 この問題もちょっとしたことで解決した。ええー、こんなところにしかけがあったとは、というやつである。外部コマンドをjsで出す、execsync関数の解説ページを見ていた時のことである。外部コマンドの出力を文字列オブジェクトへ収容するステートメントで、冒頭に""という空白文字をつけ加えていることに気付いた。

 str = “” + execsync(“ifconfig wlan0 | grep ...

ふーむ、これはいったい何のためだ。こちらでは無駄なステートメントとしてこの部分は消してしまっていた。電撃が走る。むむむ、これは匂うぞ。

 外部コマンドの出力は文字列でなないと怒られている。文字列オブジェクトを新たに定義し、そこへ放り込んでもだめだったので論理性はないが、もしかすると、これが文字列にするおまじないなのかもしれない。

 だめもとである。この部分を加えてテストしてみる。ヤッホー、大当たりだ。改行文字を除くreplaceメソッドがエラーなしに正常終了した。焦る手で、index.htmlでもテストする。よーし、IPアドレスは折り返さずに表示される。

 喜び勇んでEdisonを立ち上げ、ソースコードを修正する。やった、やりました。外部コマンドから収集したIPアドレスが認識され、Edisonの動画サーバーが見事にWindowsでもストリーミングを開始した。JavaSciriptは型には全くうるさくないと聞いていたが、結構、気難しいことがわかった。

 現在の変更は、オリジナルの複雑なディレクトリ構造とは無関係に、本来、サーバーなどを置く場所にプロトタイプのindex.htmlを収容し、現在のクライアントディレクトリにあるindex.htmlを書き換えるという武骨な方法だが、とにかくこれでEdisonのIP環境がどう変化しても自分でアドレスを拾って正しく稼働する。

 公開は迷ったが、とりあえず、変更した分だけのソースリストをご紹介することにする。このソースの変更と、index.htmlの少しの変更、外部コマンド実行の関数、execsyncsのインストールが必要である。これについては公開したフォルダーのreadme.txtを参照されたい。オリジナルはMITライセンスなので、ライセンスファイルも同梱されている。

ここに、上記のソースファイルなどを入れたディレクトリーを圧縮したzipファイルを置きます。適当な場所に解凍して、中のreadme.txtを読んでください。

「Edison_server_js.zip」をダウンロード

| | コメント (0) | トラックバック (0)

2015年4月23日 (木)

Edisonの電池駆動無線カメラの実現へ

Windowsでnode.jsのストリーミング成功(4/5/2015)
 遂にWindowsでもEdisonのnodeサーバーの画像配信に成功した。うまくいかなかったのは、前の記事のコメントにあるように、単にクライアント側のindex.htmlファイルにWindowsでは動かないローカルサーバー名を使っていたことが原因だった。 

前々記事にも説明があるが、今度のnodeサーバーは、ローカルネットの中のホスト名を自動的に調べてネームサーバーなどの助けなしに、それが使えるような機能がついている。Unixの世界ではAvahi、Macの世界ではBonjourと言うのだそうだ。前回の記事のコメントで、tmz7273さんから教えて頂いた。

 WiFiではDHCPで自動的にIPアドレスを設定していくのでネットワークプリンターなどに固定のIPアドレスを振ることが出来ない。勝手に振られて迷子になってしまう。プリンターの個別のホスト名が使えれば、その心配はなくなる。Windowsでも使えるそうだが標準では入ってこない(iTuneをインストールすると入るらしい)。

 ffmpegとnodeサーバーの映像配信がWindowsで動かなかったのは、nodeのクライアント側のコードが、これを前提としていたためで、tmz7273さんからあらためてコメントを頂き、とりあえずコードの中のローカルホスト名(ホスト名.local)を直か打ちのIPアドレスに修正したら、難なくWindowsでも画像が配信された。懸案は見事に解決である。tmz7273さんには感謝、感謝である。

 これにより、Edisonの電池駆動の無線カメラの実用化は大きく前進した。早速1Fの居間に持ち込んで、ノートPC(WinXP)での画像配信を確認する。よーし、大丈夫だ。画面に地下のPCルームの光景が映った。

 この電池駆動の無線移動カメラはまだ何に使うか決まっていない。これが一番の問題なのだが、当面の目標は達成である。心なしか体が軽い。次の課題はこれの実装だ。ここまでは、本体と電池、それにDC-DCコンバーターそれぞれが、完全にバラックの状態である。 P4127056

電池駆動の移動カメラのケースの実装(4/7/2015)
 電池によって移動できる無線ウェブカメラというのは行き掛かり上の目標で、具体的な用途が決まっていない段階で実装するのは、少し危ない。とはいえ、このままにしておくわけにもいかない。せめて本体と電源関係はひとつにまとめて動かせるようにしておくべきだ。こうしておくと、次のアイデアも湧いてくるだろう。

 というので、手持ちのケースをいくつか取り出してレイアウトを考える。このあたり(タカチPB-2 110x80x33)が入りそうだ。2段にした単三電池4つのホルダーのため、秋月のCサイズの基板を少し切り詰めてマザー基板とする。

 ここにEdisonブレークアウト基板とDC-DCコンバーター、スイッチなどを置く。Edison基板は50本近くのピンヘッダーとソケットでマザー基板と固定する。Edisonの入出力ピンは、Vccが1.8Vである。3Vや5Vの一般のペリフエラル機器を動かすにはひと手間かかる。

 しかし心配ない。ちゃんと秋月では、1.8Vから5Vに双方向に動く8ビットレベルシフターIC(FXMA108)基板を用意してくれている。Edisonを買うときに、一緒に2つほど調達した。基板上の場所も確保してある。ただし、何に使うか決まっていないので実装は後回しである。用途の決まっていない基板のレイアウトはいつもながら難しい。

Edisonのシリアル端末が消える。nodeサーバーのソース解析に挑戦(4/10/2015)
 ところが、ここで大きな問題が起きた。突然、Edisonのシリアル回線が動かなくなってしまったのである。心当たりと言えば、ブレークアウト基板の下に密集しているGPIOピンにすべてピンヘッダーをつけて、マザー基板で固定するようにしたことだが、これが原因とは到底思えない。P4227062 Edisonブレークアウト基板はシリアルが動かなくても、OTG用のUSBソケット(J3)に、PCからタイプBのコネクターをつなげば、USBの仮想IPポートが生まれるので、WiFiがつながらなくても、そう心配ではない。とはいえ最後の頼み、シリアルが動かないというのは不安である。

 しかし、これにこだわっていたらいつまでたっても先に進めない。もし何かあれば、もう一台買い直す覚悟で先に進むことにする。まずは、今、直か打ちしているhtmlファイルの中のホストIPアドレス(Edison本体の)をnodeの中で変数として取得することだ。

 サンプルコードは何か事情があって、ホスト名にしか出来なかったと思われるので、もしかするとこの改善は難しいのかもしれない。しかし、今のままでは、Edisonの立ち上げのタイミングでその都度IPアドレスが変わってしまい、運用性が極めて悪い。

 この解決には、node.jsのソースが読めることが必須である。しかし、手続き言語のCなどと違ってオブジェクト指向のプログラムは、処理が外から見えないので、ちょっと読んだだけでは歯が立たない。何をやるオブジェクトなのかがわかっていなければ手も足も出ない。

 nodeの本を買って勉強はしているが、このEdisonのソースは、expressという定番のウェブサーバー用のモジュールを使っており、独自の変数や関数を自在に使っているので全くチンプンカンプンである。

 ただ幸いにも、nodeはWindowsでも動くそうなので、まずはEdisonではなくメインのWin7のPC上で実際にコーディングしながら勉強して行くことにした。しかし、これが苦難の道の始まりだった。

JavaScriptのお勉強にもどる(4/12/2015)
 nodeの言語であるJavaScript(以降js)の文法や構文はCに近い。かなり以前、頼まれてオブジェクト指向ではない普通のアプリケーションプログラムをjsで書いたこともある。nodeのソースはすべてjsなので、すぐ理解できるだろうと、なめてかかっていたのだが、どうも甘かったようだ。

 オブジェクト指向は、C++などが出る遥か昔のSmallTalkの時代に勉強し、理論としては完全に理解しているつもりだった。ただ、C++が出たころ、実際にコーディングしてみて、余りの煩雑さに途中で投げ出したことがある。

 C++はSmallTalkのように理論的に美しくもなく、既存の手続き言語を強引にオブジェクト指向化した言語だ。まともなクラスを作るのには結局アセンブラープログラムが必要だったり、グループで開発するならともかく、個人でプログラムを書くときに、効率の良い方法とはとても思えなかった。

P4127059 しかし、今度はそうも言ってはいられない。暫くもがいていたが、やっぱりjsそのものを理解しないと先に進めない感じがしてきた。 どんどん先祖へ戻る一番効率の悪いアプローチだが、ウェブ上で評判の高いこの本を買って来た。本当は、こちらなのだろうが、べらぼうな厚さの参考書をいちから読み進めるのは、この際、勘弁申し上げたい。

 買って読んでみてやっぱり後悔する。言語仕様そのものが好きな人には面白いかもしれない。オブジェクト指向の勉強にはいいが、実践的なところが少ない。どうも、このところ電子工作の参考書の選択は、恰好をつけすぎて失敗ばかりしている。これまでに参考書が役に立ったためしがない。

 しかたなくウェブサイトにもどって片っ端から、実際にコーディングしながら学ぶことにした。所長は、ウェブのアプリケーションプログラムの開発は殆ど未経験である。Perlで見よう見まねのCGIはやってはいるが本格的な開発はやったことがない。それでも最初のうちは好調だった。簡単にサーバーが作れる。

 node入門の記事に最初に出てくるコードはどこも殆ど同じで、これは問題なく動く。しかし、次のステップから一気に難しくなる。nodeではサーバーの構築は、色々な付加的なモジュールを使って進めるのが常道のようで、Edisonのサーバースクリプトにも使われているexpressがやはり定番のようだ。こちらも当然、expressを導入することにした。

node.jsのモジュールexpressが動かない。Lチカを超えられない(4/17/2015)
 ところが、このexpressが入らないのである。ウェブにはnodeについては無数の入門記事がある。Windowsだけの状況かもしれないが、多くの導入方法があり少しづつやりかたが違うが殆ど同じ手順だ。nodeのインストールはどれも順調に終わるが、expressに関してはいつも同じところで引っかかる。

 一見エラーもなく、expressはインストールされる。しかし、入っているように見えても、サンプルコードを動かすと、「そんなコマンドはない」というエラーではねられる。不思議なことにnodeはパスを必要とするのに、expressは必要としない(パスを通しても動かないことは同じ)。

 どうも、バージョンが変わるとインストール方法なども変わり、expressが所定のところに入っていない感じだ。新しいバージョンでは、npm install expressではなく、express-generatorを最初に入れないといけないのだそうだ。しかし、そうしてもexpressが動かない状況は変わらない。

 不思議なことに、カレントディレクトリー(サーバー環境の一番上のディレクトリ)には、expressをインストールするたびに、C;という一般には使わない記名のサブディレクトリが必ず定義され、ここにexpress関係が入ってしまう(セミコロンはCUIでは無効になる)。

 そもそも、nodeそのもののインストールからしていくつかの方法がある。あるところでは、「WindowsではNodistが良い」というし、本拠地のサイトから一式をダウンロードするのではなく、npm(nodeにおけるパッケージ管理環境)で新しいバージョンをいつも更新できる環境の方が良いとも言われる。

 いずれにしても、expressサーバーのスクリプトは動かない。色々なサイトを巡って片っ端から前の環境を消しては新たにnodeやexpressをインストールするが、全滅である。

 バージョンに合ったインストールをしていないことが、この混迷の原因だと思うのだが、今となってはもう遅い。Nodistという既にアンインストールしたはずのパッケージのディレクトリ名が、あのC;のディレクトリーの中に出現したりして、もうわけがわからない。

 そのうち、何故かいつもこういう状態でこれまで挫折していることに気が付いて愕然とする。雑誌の付録基板などのときも同じだ。言われるままにLチカまで進むが、少し先に進もうとすると一気に難しくなり先に進めなくなる。

 PID制御や、サーボモーターの時もそうだった。初歩の実験や理論については山ほど情報があるし、簡単に動くのだが、その先がわからない。今度もnodeサーバーが動くまでは至極簡単なのだが、その先に進もうとすると、こうして阻まれる。

 今の人たちは大変だなと思う。昔はベンダーに囲い込まれていたから、開発環境や、言語は選びようがなかった(歯を食いしばって頑張るしかなかった)。しかし、現在はオープンシステムで、それも百花繚乱、こうやって挫折しても次に移れる。しかし、簡単に移れることは逆に不幸なことなのだ(また同じ繰り返しになる)。

 このブログにも再三書いていることだが、理解できなくても我慢して浴びるように情報を摂取していれば、いずれは突然霧が晴れるように全貌が見える時が来る。これが電子工作(いやお稽古ごと全般)の醍醐味なのだが、現実となるとそう強がりも言っていられない。

 本当にnodeをこのまま勉強して行って、ものになるのか自信がなくなってきた。PCに向かっては、ため息をつく時間が過ぎる。そういうときは、何も考えず手を動かす作業が一番気が紛れる。このあいだの雑誌付録のUSB-DACのケースを作ったりして遊ぶ。P4237063

会社のPCでexpressは動いた。自宅でもなんとか成功(4/21/2015)
 それが、奇妙なことで解決したのである。自宅のPCでは何かゴミが残っているらしく、どうやってもexpressがうまくインストールできない。それではというので、仕事の出先のPC(Win8.1)に、まっさらからnodeをインストールしてみた(最近の仕事は開店休業状態で時間はたっぷりある)。

 手順の中では一番まとまっているこれを選ぶしかし、3のexpressの導入で引っかかる。前と同じだ。ただ、今度はこれまでに起きていた変なC;というディレクトリが作られる現象は止まった。ふーむ、少しは前進したか。

 次に、expressではなく、express-generatorだよと教えてくれたこのサイトの手順を試してみる。やっぱり、expressはコマンドとしては動かない。しかし、だめもとで、サンプルコードを動かしてみると、正常にサーバーが立ち上がったのである! 

 え、えー、ほんとか。間違いなくexpressを入れたHTTPサーバーが動いている。コンソールに直接expressを入れてもnot foundなのにnodeスクリプトとしては動く。わけはわからないが動いたことは事実である。

Express_test  帰宅して、とるのもとりあえず地下のPCルームにこもる。もう一度、全く新しいディレクトリを作り、環境変数も入念に今までのnode関係のものがないかチェックし、Program Filesの中も隈なく調べてnode関係がないことを確かめたあと、事務所で動いた2番目の手順をインストールした。

 おやー、事務所では出てこなかったC;というディレクトリが出来ている。やっぱりどこかにゴミが残っている。既に消したはずの、Nodistとか、最初に作ったワークディレクトリのNODEというサブディレクトリが出来ている。expressは危惧した通り、サンプルコードも動かない。

 しかし、このあたりになると、expressのディレクトリー構造がわかってきている。少し閃いたので、C;に入っていたexpressのディレクトリチェーンの中味を本来あるべきところへ強引にコピーし、C;ディレクトリを消して動かしてみた。

 ピンポーン!だった。見事に自宅でも、expressが動いてサーバーが立ち上がった。いやあ手間がかかった。こんなにnodeをインストールするのが大変とは思わなかった。原因は明らかに、C;という変なディレクトリを作る操作がインストールの途中で紛れ込み、それがexpressを動かなくしていたことは間違いない。

 しかし、それがなぜ起きているのかについてはまだ解明出来ない。また、expressそのものはまだコマンドとして単独では動かない。疑問はまだまだ残るけれど、expressはその後、処理を増やしていっても問題なく動いている。まあ、一山は越しただろう。やっとこれでブログに報告できるというものだ。

| | コメント (3) | トラックバック (0)