Network Cameraを作ってみよう(2) カメラのハンドリング
Ethernetが動き出したら、これはいったん脇においておき、次はカメラのハンドリングである。話は再び、先ほど紹介したLS_Y201のページに戻る。さて、このカメラそのものをまず入手する必要がある。こちら、国内の場合だとスイッチサイエンスで"LinkSpriteシリアル接続JPEGカラーカメラ"という名称で販売されており、筆者もスイッチサイエンスから通販で入手した。
問題はこのカメラ、LS_Y201のページの写真と異なり、5pinのコネクタがついていることだ(Photo25~27)。かなり珍しいタイプなので、秋葉原のショップあたりでも手に入るかどうか怪しいところ。あきらめてはんだで配線を引っ張り出そうとおもったのだが、試しに身の回りを探したところ、なぜか5pin→4pinのUSBケーブルを発見した(Photo28)。
Photo27:問題のコネクタ。5pinタイプはちょっと珍しい |
Photo28:どうもマザーボード側に5pinコネクタがついているという珍しいモデル用のものらしい(もうどのマザーボードにこれがついていたのか、筆者にもさっぱりわからない) |
ためしに接続してみるとコネクタもぴったりあう(Photo29)。また端子は5pinなのだが、実はこのカメラで使っているのは4pinのみ(1pinは未使用の模様)ということで、ちょうど配線もぴったりだったため、そのまま流用してしまった。とはいえこれは一般的ではないので、コネクタの取り付け部にリード線をつけて配線を引っ張り出すのが現実的な案だと思う。
さて、配線は図3の様になる。これが準備できたら、プログラムに取り掛かろう。まず先ほどのコンパイラの画面で、左上の"New"ボタンを押すと、新しいプログラムの作成メニューが出てくるので、適当な名前を入れる(Photo30)。
ついでCamera_LS_Y201のSummaryページに移動し、ここで"Import this library into a program"をクリックし、Import画面で今作成したプログラムを指定する(Photo32)。
Photo31:こちらはライブラリのみの提供で、プログラムは自分で作ることになる |
Photo32:Target Pathのところを"CameraTest"に指定すると、このプログラムでライブラリが使えるようになる |
これにより、CameraTestでカメラ用ライブラリが利用できるようになった(Photo33)。もっとも、肝心のプログラムがまだである。Newで作ると、main.cppの中身はごらんの通りでしかない(Photo34)。
Photo33:CameraTestの中に、"Camera_LS_Y201"のライブラリアイコンが出現することで、利用可能になったことが判る |
Photo34:無条件でHello World!が記述されている。まぁ消して自分のプログラムを入れろ、という事なのだが |
幸いにも先ほどのページにサンプルプログラムが掲載されているので、これをコピーしてmain.cppの中身を上書きしてしまえばいいのだが、どうもサンプルプログラムの開発にあたっては☆board Orangeを前提にしているようで
- ディレイなしでひたすら画像を撮影、書き出しを行う
- 撮影した画像はSDカードに書き出す
- LCDに撮影状態を表示する
といった仕様になっており、このままだとちょっとうまくない。そこで
- 撮影を100秒おきにするように変更
- 撮影した画像は内蔵メモリ(/localfile)に書き出す
- コンソールにのみ撮影状態を表示する
と手直しをしたのがList 1である。ちなみに何で100秒おきかというと、先にも書いたとおり内蔵メモリは2MB弱しかないので、連続撮影をするとすぐ一杯になってしまうこと、それとこれは内蔵メモリをmbedから使う場合の制約なのだが、mbedが内蔵メモリをアクセスしている間は、外部(例えばPC)からアクセスすることができないという問題がある。つまり連続撮影をされると、その画像を取り出すことができなくなってしまうわけで、あえて100秒という長めの時間設定をしている。まぁ、あくまで動作確認なので、使い勝手が悪いのはご容赦いただきたい。
コンパイル後にダウンロード、mbedにコピーしてリセットという一連の処理を行うと、コンソールにはこんな具合に撮影状態が表示され(Photo35)、IMG_0000.JPG、IMG_0001.JPG、…という具合に自動的に撮影したファイルがたまってゆく筈だ。撮影した画像は?というとこんな具合(Photo36)。まぁまぁの画質であった。
Photo35:別にファイル名を変える必要もないのだが、そこまでやると変更が大きくなるので、このあたりは元のサンプルのままとさせていただいた。出てくる数字はこのファイルのファイル名である |
Photo36:とりあえず天井に向けて撮影してみました |
List 1:
#include "mbed.h"
#include "Camera_LS_Y201.h"
LocalFileSystem local("local");
Camera_LS_Y201 cam1(p13, p14);
FILE *fp = NULL;
int datcnt = 0;
/**
* Callback function for readJpegFileContent.
*
* @param buf A pointer to a buffer.
* @param siz A size of the buffer.
void callback_func(int done, int total, uint8_t *buf, size_t siz) {
fwrite(buf, siz, 1, fp);
static int n = 0;
int tmp = done * 100 / total;
*/
void callback_func(int done, int total, uint8_t *buf, size_t siz) {
fwrite(buf, siz, 1, fp);
static int n = 0;
int tmp = done * 100 / total;
if (n != tmp) {
n = tmp;
// You can print the progress to LCD here.
}
}
int capture(int n) {
/*
* Take a picture.(L)
*/
if (cam1.takePicture() != 0) {
return -1;
}
printf("Captured.\r\n");
char fname[64];
/*
* Open file.
* Read the content.
*/
snprintf(fname, sizeof(fname) - 1, "/local/IMG_%04d.jpg", n);
fp = fopen(fname, "wb");
if (fp == NULL) {
return -2;
}
printf("Capture: %04d", n);
datcnt = 0;
if (cam1.readJpegFileContent(callback_func) != 0) {
fclose(fp);
return -3;
}
fclose(fp);
/*
* Stop taking pictures.
*/
cam1.stopTakingPictures();
return 0;
}
/**
* Entry point.
*/
int main(void) {
wait(1);
if (cam1.reset() == 0) {
printf("Reset OK.\r\n");
}
wait(1);
int cnt = 0;
// for (int i = 0; i < 10; i++) {
while (1) {
int r = capture(cnt);
if (r == 0) {
printf("[%04d]:OK.\r\n", cnt);
} else {
printf("[%04d]:NG. (code=%d)\n\n", cnt, r);
}
cnt++;
wait(30);
}
return 0;
}