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の凄さを感じます。

今後の予定

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

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