JPEGカメラを試してみる その3
(Arduinoに接続しSDカードに保存してみる編)

〔PCで動作編〕 〔PICで接続編〕   〔メール通知編〕 〔マイコンのトップに戻る〕


前のページ"その1"では、カメラをUART通信でパソコンに 接続して動作確認を行いました。
このページでは、カメラをArduino Unoに接続してSDカー ドに写真を記録させて見たいと思います。

JPEGカメラは、UARTで接続しコマンドをArduinoから送信する事により動作させる事が出来ますが、
私の手に入れたカメラに因るのか不明ですがコマンドによっては上手く動作しない物が有るようです。
データシートによると結構機能が有る様に見受けられるのですがぁ...
取りあえずは写真を撮る機能は動作するのでその辺の記事のみとなります。

《通信コマンドの説明》

VC706プロトコル説明書は、adafruit.comこちらか らダウンロードしましょう。

マイコンからカメラへのコマンドフォーマット

[0x56] [カメラ番号] [コマンド番号] [データ数] [データ0-16]........

カメラからの通知フォーマット


[0x76] [カメラ番号] [コマンド番号] [通信状況] [データ数] [データ0-16]........

※ ”カメラ番号”は初期値は0で、2個以上ぶら下げる なら"SET_SERIAL_NUMBER(0x21)" コマンドで
   変更します(0-255の範囲)。
※ ”データ数”はコマンドにより変わりこのバイトより 後ろのデータ長を示します。
※ ”通信状況”は送信したコマンドに対するカメラの返 答です。
   0=コマンドを正しく実行します。(正常時)
   1=システムはコマンドを受信しません。
   2=データ長がエラーです。
   3=データフォーマットエラー。
   4=コマンドは今実行できません。
   5=コマンドが受信されましたが、正しく実行されませんでした

画像データ(FBUF)の読み込みフォーマット

1フレーム分の読み込み指示コマンド(0x32)データ

[0x56] [0] [0x32] [12]
 [FBUFのフレーム] [制御モード] [FBUFアドレスx4byte][読込みデータ長x4byte][待ち時間x2byte]

※ ”FBUFのフレーム”は、0=カレントのフレーム 1=ネクスト フレームを選択
※ ”制御モード”は画像データ 転送モードの指定を8 ビットで行います。
  0000[101][0=MCU 1=DMA]とビットで設定、でも参照したサンプルのプログラムのデータ
  [101]はデータシー トでは[111]に見えるがぁ[111]だと動作しなかったがぁ、良くわからん。
  DMAにするとデータの転送速度が上がると書いて有るが使い方不明。
※ ”FBUFアドレス”読み込むデータバッファのアド レス、8の整数倍で指定する
※ ”読込みデータ長”指定は4の倍数を設定する、ここ で指定した分が1フレームとして送られて来る
  のでJPEG画像のデータ数分繰り返す
  画像のデータ数は"GET_FBUF_LEN(0x34)" コマンドで得る事が出来ます。
※ "待ち時間"は送信されるデータのインターバル時間 で、単位は0.01msです。

返信される1フレーム分のデータ

[0x76] [0] [0x32] [0] [0] (インターバル時間)
[データ1]から[データn]
(インターバル時間) [0x76] [0] [0x32] [通信状況] [0]

※ 送信データの長さは指定した分送られて来る、このページでは64byteとする
  (Arduinoの"SoftwareSerial"受信バッファが
64byteなのでぇ)

《JPEGフォーマットについて》

JPEGのファイルデータは"FF D8"で始まり"FF D9"のコードで終わります。
詳しい説明は、こちらの”JpegAnalyzer Plus オンラインヘルプ”を参照下さい。
又、この"JpegAnalyzer"のツールはこちらからダウンロード可能です。 *1)

《実態配線図》

実験部品のマイクロSDカードシールドはスイッチサイエンスで購入しましたが、現在は販売終了で
代替えがこちらで す。
尚、このシールドはピン番号8(CS)、11,12、13を使用するので他には使用出来ません。
又、10番ピンもSPIライブラリの関連で使用出来ないらしい?
実態配線図
回路の電源は5.0Vです、
カメラI/Oが3.3Vでなのでカメラ受信側のみ10KΩ抵抗で分圧(2.5V)しています。
 カメラモジュールの端子配列は左から[TVOUT][RX][TX][GND][VCC]で[TVOUT]は無配線。
Arduino側は”SoftwareSerial”を使って、RX(2番)/TX(3番)でカメラと通信しています。
スイッチはシャッター代わりです。尚、スイッチのプルアップ抵抗 はArduino内蔵を利用しています。
又、USBシリアルでArduinoIDEシリアルモニタに動作時の状況を表示しています。

《サンプルプログラムについて》

↓ここからArduino用サンプルスケッチファイルをダウンロードして下さい。
skVC0706.zip

解凍すると下の様に展開されます。
[skVC0706]──┬─[examples]───┬─[jpegCamera]------- jpegCamera.ino
├ skVC0706.cpp └─[MotionMonitor]---- MotionMonitor.ino
├ skVC0706.h
└ keywords.txt
ArduinoIDE 1.8.1 がインストールされているフォ ルダー、インストール先を変更していないなら
[C:\Program Files\arduino-1.8.1\libraries]です。
この場所に上記解凍ファイルを[skVC0706]ディレクトリ丸ごと移動します。
また、ライブラリの登録や利用方法などの話はこ ちらを参考にして下さい。

jpegCamera.ino  ・・・・・・本体のサンプルスケッチ(スナップ写真を撮るサンプル)
MotionMonitor.ino  ・・・・本体のサンプルスケッチ(動きを監視するサンプル)
skVC0706.cpp ・・・・・・・VC0706-chip用関数ライブラリのソースファイル
skVC0706.h ・・・・・・・・・VC0706-chip用関数のヘッダファイル
keywords.txt ・・・・・・・・・キーワードファイル

jpegCamera.ino

スナップ写真を撮るサンプルです、jpegCamera.inoを開くには、
IDEを起動して、メニューバーの「ファイル」→「スケッチの例」→「skVC0706」→[jpegCamera]
をクリック操作すればファイルが開かれます。
次に、IDEツールバーの「Upload」ボタンをクリックしてコンパイルとarduinoボードに書込みを行います。

カメラの動作表示1 左が動作させた時のシリアルモニタ出力の例で す。

 "<<< Now, please take a picture! >>>"が表示されたら
 スイッチを押せばSDに写真が保存されます。

 起動させた時にSDカードが挿入されていなかったり
 SDの初期化が失敗すれば"SD card failed, or not
 present
"が表示されます。

 カメラにコマンドを発行しエラーが返された時は、
 "GetVersion Error cmdNo=0x?? ErrNo=xx"
 と表示されます、 ??:コマンド番号 xx:エラー番号

 ファイルのオープンエラー時は"FailOpen"が表示されるでしょう。

ファイル名について

IMG?????.JPG
?????に"00000"から撮影毎に+1されていきます、ですが電源を切ればまた"00000"から
カウントされるので同じファイル名は上書きされるでしょう。
それが嫌な場合はEEPROMに番号などを書き込んで処理をしましょう。

MotionMonitor.ino

動きを監視するサンプルですMotionMonitor.inoを開くには、
IDEを起動して、メニューバーの「ファイル」→「スケッチの例」→「skVC0706」→[MotionMonitor]
をクリック操作すればファイルが開かれます。
次に、IDEツールバーの「Upload」ボタンをクリックしてコンパイルとarduinoボードに書込みを行います。

カメラの動作表示2 左が動作させた時のシリアルモニタ出力の例です。

 "<<< Start motion monitoring! >>>"が表示されたら
 動きの監視が始まっています。

 動きを検知したら"Detected movement!!" を表示します。

 このサンプルは"Detected movement!!"を表示する
 だけですので後はご自分で、写真を保存するなり
 警報を出すなりご自由に行いましょう。

 このカメラには、動きを監視する為の微調整を行う設定が出来るらしいがぁ...
 どんなにやったら良いかわからん。

カメラの実写2
そのままの写真です、加工無し
我が家裏の"県指定樹木"、ツルウメモドキとムクノキです。
でもぉ、カメラ何処に向けているか解らないんだよね...orz

《ライブラリの説明》

skVC0706.h

#define VC070X_READDATA_BUFFSZ        64    // 画像データ受信バッファサイズ
の行が有りますが、これは"SoftwareSerial"受信バッファが64byteな のでそうしたのですが
もし上手く機能しない場合は"32"として見て下さ い、但しデータの保存時間が掛かります。

skVC0706.cpp

VC0706-chipとUSART通信で制御を行う為の関数集です。
まず利用する場合は下記3行をスケッチの最初に記述します。
#include <SoftwareSerial.h>
#include <SD.h>
#include <skVC0706.h>

関数の使い方を説明します。

ソフトシリアルとVC0706カメラの関数ライブラリを使用する為に必要な宣言を行います。

SoftwareSerial mySerial = SoftwareSerial(2,3) ;   // ソフトシリアルのオブジェクト作成(RX,TX)
skVC070x  VC0706(&mySerial) ;                       // VC0706カメラのオブジェクト作成

シリアル通信のピン指定はRX=2番ピン TX=3番ピンとしました。
skVC070xのオブジェクトにはソフトシリアルのオブジェクトポインターを渡します。
VC0706の名前は変更出来ますが、以下の例は"VC0706"で の説明です。

VC0706.begin(baud)
 初期化処理
 SoftwareSerialの初期化を行います。
 ここでボーレートを変更してもカメラ自体の通信速度の変更は出来ません!

 uint32_t baud: SoftwareSerialの通信速度を指定します、デフォルトは38400bpsです。

 ※ カメラの通信速度変更は実験していません、壊れるとぉ泣いちゃうのでぇ...

VC0706.flush( )
 ソフトシリアル受信バッファの消去処理
 溜まっている分の受信データをバッファ内から読み捨てます。

ans = VC0706.GetError( )
 エラー情報を得る処理
 最後に受信した時のエラー番号を返します。
 なので、関数をコールしてエラーだった場合はこの関数でエラー内容を知る事が出来ます。

 uint16_t ans:1byte目に”コマンド番号” 2byte目に"エラー番号"で返します。
          エラー番号
                     0 = コマンドを正しく実行します。(正常時)
                     1 = システムはコマンドを受信しません。
                     2 = データ長がエラーです。
                     3 = データフォーマットエラー。
                     4 = コマンドは今実行できません。
                     5 = コマンドが受信されましたが、正しく実行されませんでした
                    
10 = 送信したコマンドの返答でない物を受信した。
             11 = 返答を待ったがタイムオーバー
  例)
union VC070X_ERROR_t Err ;
char *p ;

p = VC0706.GetVersion() ;
if (p == 0) {
Err.info = VC0706.GetError() ;
printf("GetVersion error cmd=%d err=%d",Err.cmd_no,Err.err_no) ;
} else printf("%s",p) ;

ans = VC0706.Reset( )
 カメラのリセットを行う処理
 リセットすると電源ON時と同じメッセージを送信して来るので、関数内で1秒待ち読み捨てています。
 電源ON後2-3秒程してコマンド指示を開始する様にデータシートに書いて有るので、
 リセットしたら2-3秒程待った方が良さげかもね。

 int ans:成功時は0を返し、失敗時は-1を返します

ans = VC0706.GetVersion( )
 ファームウェアのバージョンを得る処理

 char *ans:成功時はバージョン情報文字列へのアドレスを 返します(例:"VC0703 1.00\0")
        失敗時は0を返します。

ans = VC0706.PowerCtl(info,time)
 省電力モードの制御を行う処理(この処理は未実験)

 int        info: 0=OFF 1=ON その他 = 指定time時間で省電力モードに入ります
 unit16_t time:10ms単位で指定(0x0000- 0xFFFF)します
 int         ans:成功時は0を返し、失敗時は-1を返します

ans = VC0706.GetCompression( )
 画像の圧縮比を得る処理

 int  ans: 成功時は0x00〜0xFFを返し、失敗時は-1を返します

ans = VC0706.SetCompression( val)
 画像の圧縮比を設定する処理
 リセット(電源ON)すると元に戻ります、Myカメラのデフォルト値は0x35でした。

 int   val:画像圧縮比の指定をしま す、0x00〜0xFFです(数値が高いと圧縮比も高い)
 int  ans:成功時は0を返し、失敗時は-1を返 します

ans = VC0706.GetColorSts( )
 COLORのモードを得る処理

 int  ans:成功時は 0=自動設定  1=COLORモード  2=白黒モード
               失敗時は-1を返します。

ans = VC0706.SetColorCtl( val)
 COLORのモードを設定する処理(この処理は上手く動作せず)
 白黒モードにして見たがぁ、色落ち?になっただけで白黒にならなかったが?
 自動は、光加減で切り替わるらしいのでぇ夜になったら白黒に切り替わるのでは?

 int   val:COLORのモードの指 定をします(0=自動設定  1=COLORモード  2=白黒モード)
 int  ans:成功時は0を返し、失敗時は-1を返 します

ans = VC0706.GetImageSize( )
 画像の大きさを得る処理

 int  ans:成功時は  0(0x00)="640x480"  17(0x11)="320x240"  34(0x22)="160x120"
               失敗時は-1を返します。

  画像の大きさを設定する処理を行って見たのですが、設定後リセットしたり等いろいろ
   いじってみたのですがぁ...上手く動作させる事が出来ず"640x480"から変わりませんでした。

ans = VC0706.MotionCtlEnable( )
 モーション監視を許可する処理

 int  ans:成功時は0を返し、失敗時は-1を返 します

ans = VC0706.SetMotionCtl(val)
 動きのモニターリングを制御する処理

 int   val:1=モニターリング開始   0=モニターリング停止
 int  ans:成功時は0を返し、失敗時は-1を返 します

ans = VC0706.MotionDetect( )
 モーション監視を行う処理
 カメラのフレーム内で動きが有った場合に"COMM_MOTION_DETECTED(0x39)" が通知されます、
 なので、この関数はloop( )内で常にコールする必要が有ります。("MotionMonitor.ino"を参照)

 int  ans:-1 = 何も受信していないか或いはエラーを受信した
               それ以外は、受信したコマンド番号を返します。

  "COMM_MOTION_DETECTED(0x39)"以外の コマンドも受信する所に注意しましょう。

ans = VC0706.TakePicture( )
 画像をキャプチャーする処理
 この関数をコールする場合は、ビデオが起動している事が前提です。

 uint32_t ans:成功時はキャプチャーした画像のファイ ルサイズを返します
                     失敗時は0を返します。

ans = VC0706.ReadPicture(adrs,len)
 画像データを読み込む処理
 キャプチャーした画像データを、指定したFBUFのアドレスから指定した分だけ読み込みます。

 uint16_t adrs:読み込むFBUFのアドレスを指定し ます(8の整数倍で指定)
 int         len:読み込むデータの長さ指定します
                       (VC070x_READDATA_BUFFSIZ未満とし、4の整数倍で指定)
 int      ans:成功時は読み込ん だデータの格納先を返します

ans = VC0706.ResumeVideo( )
 ビデオを再開する処理
 写真を取り込んだらこの関数でビデオを再開させます。

 int ans:成功時は0を返し、失敗時は-1を返します

  "プロトコル説明書"のFBUF_CTRLで、resumeは0x02となっていますが0x03の間違いと思います。

《FlashAirの話》

SD カードソケットに"FlashAir"を挿入すれば動作します、 なので、こちらを 参考に操作すれば
保存された画像ファイルをPCや携帯にダウンロードしたり、"iSDIO" の機能を利用してブラウザから
動画撮影やそれをブラウザに表示させたりとか出来ると思います。
ここではその実験は行いませんが...

 但し、SDカードソケットは標準サイズで、上記の記事はPICで の話がほとんどですがぁ....

PS. 実験を行いました、PICでの話ですがぁ”メール通知編”を参照下さい。

《その他》

"adafruit"のF.A.Q.ページに
?Why is the color washed out? It looks like a monochrome image.
Because it was designed for surveillance, the sensitivity of the camera extends into the infrared range.
This means that objects that reflect or emit infrared rays will appear lighter than the do to the human eye.
In some cases the image will appear washed out and almost monochromatic.
A more natural rendering can be achieved using an IR blocking filter such as a B+W 486.

?なぜ、色が洗い流されたのですか? モノクロ画像のように見えます。
監視用に設計されているため、カメラの感度は赤外線範囲に及んでいます。
これは、赤外線を反射または放射する物体が、人間の目の光よりも明るく見えることを意味する。
場合によっては、画像は洗い流されてほぼ単色に見えます。
より自然なレンダリングは、B + W 486などのIRブロックフィルタを使用して実現できます


 Google翻訳による

こんな感じでぇ、写真がぁ白黒ぽく撮れる場合が多々有るのですよぉ〜。
ああ、って事はぁ、赤外線LEDを取り付ければ夜でもバッチリって事ですねぇ。

他のカメラを手に入れてもう一度(他の機能等)実験したい気分だがぁ、先立つ物がない....orz....
まあ、あくまで監視用カメラって所ですね、画質には期待しない方がよさげぇ。



リンクの見直し(*1) 2020/03/17


【きむ茶工房ガレージハウス】
Copyright (C) 2006-2020 Shigehiro Kimura All Rights Reserved.