netshのメリットと限界

netshとは?

netsh(ネットシェル)は、Windowsに標準で備わっているコマンドプログラムです。画面はなく、コマンドプロンプトなどからコマンド文を打ち込んで使用します。Windowsのコントロールパネルやチャームの設定メニューの画面から設定するのと同様のことができます。
Windowsは、どちらの方法でもネットワーク設定が可能
同じ目的を満たす手段が2つあるのは、無用な混乱を招くだけなのでは?と思われる方もいるかもしれません。しかし、netshには独自の使い方があります。

netshのいいところ

設定画面は、利用者が設定を変更したい時に操作することを前提としています。一方、netshはあまりそういう使い方をしません。

Windowsに詳しい人は、コマンドプロンプトを立ち上げて、真っ黒なコンソールにコマンドをスラスラと入力できるかもしれませんが、普通の人はnetshコマンドのスペルを思い出すこともままならず、手が止まってしまうのがオチです。(かくいう私も、コマンドを暗記できた試しがありません)
netshは、設定を「入力する時」と実際に「適用する時」を分離できるのが強みです。netshに限らず、コマンドプロンプトから入力できるコマンド全般に言えることなのですが、コマンドというのは、別の見方をするとメールやツィッターの本文と同じタダの文字列です。
タダの文字列なので、ファイルに保存することができます。メールは、本文を書いたら直ちに送信しなければならないわけではありません。「下書き」という状態のまま手元に残しておいて、後日、送信することができます。
同様に、苦労して入力したnetshコマンドをファイルに保存しておき、その適用を、本当に必要になるその時まで先送りできるのです。
コマンドを記録したファイルのことを、「バッチファイル(拡張子は.bat)」と言います。
設定画面だと、こういう使い方はできません。画面をずっと開いたままにしておくことはできず、閉じようとすると「適用」または「キャンセル」のいずれかを選択させられます。
入力と適用の時間差
これは、ノートPCやタブレットを普段持ち歩く方にとって特に便利です。
日常的に利用する場所のネットワーク設定を予め別々のバッチファイルに保存しておいて、場所を移るたびに、対応するバッチファイルを起動して設定を即座に切り替えることができます。
このやり方を勧める記事を、ネットでよく見かけます。マイクロソフトも、きっとそういう使い方を想定してnetshを提供しているのだと思います。

netshの限界

しかし私は、この方法は一部の人しか救えないと考えています。それほどパソコンに詳しくない方にとって、バッチファイルというハードルは高すぎるのです。
たとえ自分一人しか使わないようなバッチファイルであっても、きちんと動くものを作ろうとすればそれなりの基礎知識と経験が必要になります。
それらを備えている方であればnetshという選択肢はありなのですが、そうでない方々にとっては解決策になりません。

その限界を乗り越える

そういう不満もあって、私は「NCSwitch」を作りました。このツールは、利用者がWindowsの設定画面に入力した内容を吸い上げて、ファイルに保存することができます。NCSwitchのウィザード画面を数回クリックして、バッチファイルを
自動生成するイメージです。
NCSwitchの仕組み
更に、接続先ネットワークが変わったことを自動的に検出して、自動的に設定を復元できます。バッチファイルのように、利用者が起動するバッチファイルを選択する必要もありません。
これらは全て、Windowsに詳しくない普通のユーザーに使っていただくことを念頭に設計された機能です。1.0のリリースから10年以上経ちますが、今も変わらず多くの利用者にご愛用いただいております。
ネットワーク設定の切り替えでお悩みの方は、ぜひお試しください。こちらからダウンロードできます。

360度カメラを自作しようとして、180度という顛末に (4 of 4)

 

前回からの続きです。

EdisonのI2Cハードを使わずにI2C通信する

数日間ずっと暗い気持ちでモヤモヤしていたのですが、ふと、全く別のアプローチを思いつきました。Edisonが提供しているI2Cハードを使うのをやめて、汎用のデジタルIOピン上でI2C通信する処理を自前で実装するのです。(Bit Bangingと呼ばれる手法です)

基本的な実装は思ったほど難しくなかったのですが、いざ動かしてみると、ここにも一つ落とし穴がありました。

通常、汎用のI/Oピンは、データの方向(INPUT/OUTPUT)を設定してから、電圧レベル(HIGH/LOW)を読み書きします。今回はI2C通信をエミュレートするため、データ方向を頻繁に切り替える必要がありました。(I2Cは、データの送受信を1本の線でまかないます)

データ方向の切り替えはArduino互換ライブラリのpinMode関数を使って行ったのですが、この関数を呼び出すと、なんと、切り替えと関係ない「他のIOピン」の電圧が一瞬上下に振れます。I2Cプロトコルに準じた波形を作るために苦労している中で、こんな副作用があっては困ってしまいます。

想定外のクロック生成

試行錯誤した結果、今回は、pinMode関数を呼び出すタイミングを調整することで、なんとか副作用を抑えることができました。

Bit Bangingが救いの神だった

Bit Bangingの実装が終わったところで、デモプログラムのI2C処理を置き換えて、動作確認してみました。どうせダメでしょ・・・くらいに思っていたのですが、なんとなんと、全てのパラメーター書き込みに成功しました!

結局、EdisonのI2CハードとArduCAMの相性が悪かったんですね・・・。

カメラモジュールを1台繋げた状態でうまくいったので、今度は、2台繋げて検証してみました。いろいろ試した結果、2kHz程度のクロック周波数なら、複数台繋いでもうまくいくことが分かりました。(10kHzだと、一方は正常に動作するものの、他方はパラメーター設定に失敗して変な画像が出力されたりしました)

2kHzと言うと、I2C仕様の中で最も低速なスタンダードモードの100kHzより50倍遅いことになります。とはいえ、今回の自作カメラにおいては、I2C通信はカメラモジュールの初期化時に1回走るだけです。初期化後のシャッター制御や画像読み取りは高速なSPI通信で制御されるので、実用上の問題はありません。

ようやく、自作カメラがまともに動く

幾多の困難を乗り越えて、ようやくArduCAMがEdison上で動くようになりました。

動かし始めた頃は、EdisonからSDカードを抜き、自機のMAC OS Xに差し、画像を確認し、Edisonに再び差し直す・・・という作業を繰り返していました。ただ、これを数十回も繰り返しているうち、いい加減面倒になってきました。

そこで、Expressというnode.js用のWebサーバーAPIを使って、SDカードのJPEG画像を自機のWebブラウザから直接見られるようにしました。

$ vi app.js
var express = require(‘express’);
var app = express();

// Edisonは、SD Card を /media/sdcardにマウントする
app.use(‘/sdcard’, express.static(‘/media/sdcard’));

app.listen(3000, function () {
console.log(‘Example app listening on port 3000!’);
});

$ node app.js   #webサーバ起動

特にトラブることなく、あっさり成功。I2Cの苦労を思えば、まさに瞬殺です。こういうことがサクッとできるところに、Edisonの凄さを感じます。

今後の予定

冒頭でも述べた通り、本当にやりたい事はカメラから画像出力した先の処理なのですが、今回は、画像出力までで力尽きました。

でも、これでようやくスタートラインに立てました。これから色々試してみて、随時、本ブログに結果報告していきたいと思います。

 

360度カメラを自作しようとして、180度という顛末に (3 of 4)

 

前回からの続きです。

複数のカメラを繋ぐと上手くいかない

I2C通信に問題があることが判明しました。次は、それがデモプログラムの組み方の問題なのか、もっとハードウェア寄りの問題なのかを見極める必要があります。

そこで、Edison上のLinuxに同梱されている、i2c-toolsというI2C通信用コマンドセットを使って、現象の再現を試みました。再現しないならデモプログラムの問題で、再現するならハードの問題という事になります。

まず、i2cdetectコマンドを使って、接続されているI2C機器(今回の場合はカメラモジュール)のアドレスを取得できるか確認しました。1台のカメラを接続した状態であれば100%取得できます。(”30″というのが、ArduCAMのアドレスです)

I2Cデバイスの識別成功

2台繋ぐと少し取得の成功率が下がり、3台を超えると全く取得できなくなりました。

I2Cデバイスの識別できず

i2cdumpコマンドによるパラメーターの読み出しも試みましたが、同じ傾向が見られます。

EdisonのI2CバスにArduCAMを複数台繋げると、通信障害が起きるようです。結局、ハードの問題でした。(プログラムの問題なら対処も簡単だったのに・・・現実は厳しい)

とはいえ、手元のArduCAMカメラモジュールがJPEG画像を出力したところを一度も見たことがない自分としては、そもそも初期不良なのでは?という不安も払拭しきれません。

Arduino UNO なら問題なし

そこで、初期不良かどうかはっきりさせる為に、Arduino UNOも購入することにしました。

現品の到着後、早速、Edison for ArduinoをArduino UNOに差し替えてリトライしました。1台でも複数台でも、ちゃんと動きます。これで、初期不良ではないことがはっきりしました。

余談ですが、実はArduino UNO上で動かす時に、少々ハマりました。Arduino UNOは、Edisonと違ってメモリ領域の制限が厳しい為、デバッグ用にSerial.print(“xxx”)を挟みすぎると、文字列定数(“xxx”の部分)が貴重なメモリ領域を圧迫してしまいます。これが一定量を超えると、変数の読み書きが正しく行えず、プログラムの挙動が不安定になります。(本家サイトにも注意書きがありました)

結局、1台だけでも上手く行かない

この自作カメラは、1本のI2Cバス上に、同じI2Cアドレスを持つArduCAMカメラモジュールを複数台繋げる構成になっています。普通は、複数の機器を同一バスに繋ぐのであれば、それぞれが異なるアドレスを持つべきです。しかし、開発者本人は、「確かに良い設計とは言えない。でも、動くよ。」という見解のようです。実際、Arduino UNOで動くことは私も確認しました。でも、EdisonのI2Cバスにはその力技が通用しないという事なのかもしれません。

そこで、一旦複数台のカメラを繋ぐ事は先送りして、1台だけつないだ状態で動かしてみる事にしました。1台のみであれば、I2C通信に問題がないことは前述のi2c-toolsで確認済みです。

ところが・・・デモプログラムは動きません。

デモプログラムを動かす為には数十個のパラメーターを設定する必要があるのですが、ある特定のパラメーターに書き込みすると、それ以降、どのパラメーター書き込みもエラーになるのです。しかも、動作電圧(3.3V / 5V)によって、エラーの引き金となるパラメーターが異なります。加えて、3.3Vなら、同じパラメーター書き込みを何度も繰り返しているうちにいずれ成功するのですが、5Vだと、どれだけリトライしても失敗し続けます。

もはや説明がつきません。EdisonとArducamは相性が悪いのでしょうか?

デジアナを買って、原因を追求

それでも、ここまで来たら諦めきれません。I2C通信の波形を見れば、何かヒントが得られるかも知れないと思い、Analog Discovery 2 というデジタルアナライザを購入しました。(今回の自作は、結構な額を出費しています(泣))

早速、波形を観測してみました。

エラー応答(NACK)

I2C通信のプロトコルシーケンス自体に問題はなく、Arducamがエラー応答(NAK)を返しているように見えます。

ちなみに、書き込みに成功した場合は以下のシーケンスになります。

正常応答(ACK)

残念ながら、カメラセンサーの内部構造を知らない私には、NAKを返す原因を調べる術がありません。

通信速度を落としてみるも効果なし

実は、デジアナであれこれ調べている時に、NAKとは別にもう1つ気になる点がありました。EdisonとArduino UNOの波形が少し違うのです。

i2c_voltage

Arduinoと比べると、Edisonの方はクロックのHI電圧が上がりきっていないように見えます。これが問題の原因とは考えにくいものの、他にやれることも見当たらないので、ここに対策を打ちます。

いろいろ調べた結果、Arduino UNOは100kHzのスタンダードモードがデフォルト設定で、一方のEdisonは400kHzのファーストモードがデフォルト設定だと知りました。

そこで、Edisonをスタンダードモードに落とした状態で、再度波形を観測してみます。

理想的な波形になりました。なったのですが・・・やはり、NAKを返す問題は解消されませんでした。

もう、打てる手がありません。