前回、実用性が期待できないネコ型スパイカメラを作りました。核となるインターネットで撮影データを送る仕組みは、Obnizを利用しています。開発過程を参考まで記録します。
小箱からネコが顔を出し写真撮影
改めて開発したスパイカメラを紹介します。
挙動
- ブラウザで指定のURLを開くと、スパイカメラがリモートで起動します。
- スパイカメラに仕込まれたサーボモーターが動き、ネコが箱から飛び出します。
- ネコの持っているカメラが作動し、20秒くらいかけて撮影したデータを手元のブラウザに送信します。
- ネコが箱の中に戻ります。
・・・無駄の多いギミック。本気でスパイカメラを作ると、いろいろ問題が起こりそうなので、実用より遊びの気持ちが大きかったと思います。
使用部品
- Obniz Board ×1
- カメラ「JpegSerialCam」 ×1
- サーボモーター「SG90」 ×1
- 白色LED ×1
- 330Ω抵抗 ×1
- ユニバーサル基板 少々
- 小さいブレッドボード ×1
- ネコの人形 ×1 (3Dプリンターで造形)
- 歯車と直線移動機構 ×1セット (3Dプリンターで造形)
- ジャンパーワイヤー 少々
- ネジ 少々
- 木の小箱
- 木の板 ×2 (のこぎりで箱に合わせてカット)
3Dプリンターでトライアル&エラー
ネコ、歯車と直線移動機構は、3Dプリンターで造形しています。特に直線移動機構の設計ミスが多く、30回以上出力しています。
小箱が小さいほど、設計は難しくなると思います。(単純に私が不慣れなだけかもしれません。)
なお、3Dモデリングを0からやるのは難しいと考え、Thingiverseで共有されているネコと歯車を使わせてもらい、改造して作りました。
カメラは「JpegSerialCam」じゃない方が良かったかも
撮影用のカメラを用意します。
2020年5月現在、Obnizのパーツライブラリには2つのカメラが紹介されています。
私はピンの数が少なくて楽そうな「JpegSerialCam」を私は選びました。しかし、解像度が最大640×480。もっと解像度が高い画像が欲しい場合、「ArduCAMMini」の方が選んだ方が良いです。最大1600×1200まで撮影可能です。
「JpegSerialCam」で困ったのがピンの幅。通常のブレッドボードに挿せる穴ピッチではありません。
仕方ないのでピンヘッダを1本ずつ切り取り、プラスチック部分を削ってはんだ付けしていきました。
放射状にピンが広げると、とりあえずブレッドボードにも刺さります。
暗所撮影用のLEDも用意
スパイカメラは暗闇で使う可能性があります。気づかれないよう、不可視の赤外線LEDを使うのがセオリーのような気がします。しかし、今回は白色LEDを使います。
機能性は置いといて、ネコの目を光らせたいからです。
白色LED、330Ω抵抗、ジャンパーワイヤーを、小さくカットしたユニバーサル基板にはんだ付けします。
モバイルバッテリーから5Vの電源を取り込めるマイクロUSBコネクタがあると、テストは便利です。
ネコとカメラとLEDを合体
カメラは小さなブレッドボードに挿します。ついでにカメラボディも3Dプリントして装着しました。
LEDの基盤とブレッドボードのジョイントも3Dプリントしました。
LEDはネコの中に差し込み、カメラはネコの手に装着します。
通電して確認。ネコを光らせると、ちょっと怖い。
小箱に収まるように組み立て
小箱の底と同じサイズに、木の板をカットします。
板の上で組み立て、最後に小箱に入れましょう。直接小箱にねじ止めしていくより楽です。
サーボモーターに歯車を付け、直線移動機構と連結。
Obnizも板にねじ止め。配線をつないでいきます。
配線
- io0 – サーボモーター:gnd
- io1 – サーボモーター:vcc
- io2 – サーボモーター:signal
- io3 – カメラ:追加電源vcc
- io4 – カメラ:追加電源gnd
- io5 – カメラ:vcc
- io6 – カメラ:tx
- io7 – カメラ:rx
- io10 – LED:vcc
- io11 – LED:gnd
いっぱいつなぐと、配線がごちゃごちゃします。
ジャンパーワイヤーが絡まらないように、バンドで止めました。バンドも即席で3Dプリントしています。
コードを書く
仕上げにコードを書きます。まずはHTMLから。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width,initial-scale=1.0"> <title>スパイカメラ</title> <script src="https://obniz.io/js/jquery-3.2.1.min.js"></script> <script src="https://unpkg.com/obniz@3.4.0-beta.0/obniz.js" crossorigin="anonymous"></script> </head> <body> <main> <div id="obniz-debug"></div> <input type="range" id="servo1" value="0" max="130" min="0"> <img id="image" src="" alt=""> </main> <script src="main.js"></script> </body> </html> |
「input type=”range”」はサーボモーターのテスト用です。
サーボモーターは0~180度の範囲で回転しますが、今回作ったものは130度を超えるあたりで歯車が外れたので、制限をかけました。
続いてJavaScriptです。Obnizのパーツライブラリ「JpegSerialCam」を参考にしています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
var obniz = new Obniz("OBNIZ_ID_HERE"); var isOpen = false; obniz.onconnect = async function () { var servo1 = obniz.wired("ServoMotor", {gnd:0,vcc:1,signal:2}); obniz.io11.output(false); servo1.angle(0); await obniz.wait(1000); servo1.off(); obniz.io10.output(true); await obniz.wait(100); obniz.io3.output(true); obniz.io4.output(false); var cam = obniz.wired("JpegSerialCam", {vcc:5, cam_tx:6, cam_rx:7, gnd:8}); await cam.startWait({baud: 38400}); await cam.setSizeWait("640x480"); const jpegData = await cam.takeWait(); document.getElementById("image").src = "data:image/jpeg;base64," + cam.arrayToBase64(jpegData); obniz.io10.output(false); servo1.on(); servo1.angle(130); await obniz.wait(1000); servo1.off(); $("#servo1").change(function() { servo1.angle(130- $(this).val()); if($(this).val() > 110){ obniz.io10.output(true); }else{ obniz.io10.output(false); } }); }; |
localhostサーバーを用意して、ブラウザでHTMLを読み込んだら、すぐにJavaScriptが動作し、撮影を開始します。
gifアニメではカットしていますが、撮影は20秒くらいかかります。
LEDが役に立たない
暗闇で撮影を試してみると・・・撮影画像は真っ暗。ネコにLEDを仕込んだものの、この程度の明るさでは役に立たないようです。LEDを光らせるコードはコメントアウトしました。
箱に入れて完成
作った装置を小箱に入れ、ふたをすれば完成です。
しかし、カメラが半分しか飛び出さない痛恨の失敗。カメラをもっと上の方に付け替えたほうが良さそうです。
撮影画像は逆さだけど
クマのぬいぐるみをテスト撮影。
ブラウザに送られてきた画像は逆さです。
カメラの取り付けが逆だったみたいです。
しかし、これはCSSのtransform:rotateで、簡単に調整できるので致命的ではないでしょう。
目的によっては解像度不足
カメラ「JpegSerialCam」は、「誰かいる?」くらいの目的で使う分には問題ないですが、細かい文字情報を盗み見るには解像度不足です。
Obnizで本気のスパイカメラを作る場合、次回はカメラ「ArduCAMMini」を使うことにします。