Table of Contents
jpegカメラをどう使うの?
- Arduinoにjpegカメラを接続してSDカードに画像を保存します。カメラは、例えば1秒間に30フレームを撮影してNTSC信号で出力してディスプレイに表示する使い方を考えますが、jpegカメラは撮影した画像をjpegフォーマットで出力します。この画像をSDカードに保存します。
カメラの仕様と関連情報
- 秋月電子通商で探すとAdafruit社のjpegカメラ[小型TTLシリアルJPEGカメラ]が見つかり購入しました。
関連する記事は?
- [Arduinoとjpegカメラを使って画像撮影しました ]に購入したjpegカメラの画像を確認する方法、関連するリンク、ピン配置、等をまとめています。
必要な部品・器具は?
jpeg カメラ | 1個 |
データ ロガーシールド | 1個 |
Arduino UNO R3 | 1個 |
抵抗 [10KΩ] (秋月電子通商のjpegカメラの部品に付属していました。) | 2個 |
関連する製品・商品の購入先は?
- 秋月電子通商 — [小型TTLシリアルJPEGカメラ(NTSCビデオ出力付)]
- Amazon — [データロガーシールド]
- Amazon — [Arduino用のUNO R3 最終版スタータキット]
どのような動作をするの?
- jpegカメラの画像をデータロガーシールドのSDカードに保存します。このデータロガーシールドにはRTCモジュールとSDモジュールが実装されていて、時間情報とデータを記録できます。[Arduinoデータロガーシールドを使ってデータを記録しました ]にデータロガーシールドの使い方やスケッチをまとめています。
回路図は?
- データロガーシールドはArduino UNO R3のソケットにピンヘッダの端子を挿入して接続します。データロガーシールドにjepgカメラを接続します。
- jpegカメラのRXへの信号は附属の10KΩの抵抗で分割して電圧を半分にします。
スケッチのコードは?
- Adafruit社のjpegカメラ用のスケッチが[Downloads]からGithub[Adafruit-VC0706-Serial-Camera-Library]へリンクされています。ZIPファイルをダウンロードして解凍したフォルダをArduino IDEの[libraries]のフォルダに移動します。スケッチのコード[Snapshot.ino]も含まれており、[解凍したフォルダ]->[examples]フォルダ->[Snapshot]フォルダと探していくと見つかります。
- [Snapshot.ino]は名前の通り、撮影は一回のみです。
// This is a basic snapshot sketch using the VC0706 library.
// On start, the Arduino will find the camera and SD card and
// then snap a photo, saving it to the SD card.
// Public domain.
// If using an Arduino Mega (1280, 2560 or ADK) in conjunction
// with an SD card shield designed for conventional Arduinos
// (Uno, etc.), it's necessary to edit the library file:
// libraries/SD/utility/Sd2Card.h
// Look for this line:
// #define MEGA_SOFT_SPI 0
// change to:
// #define MEGA_SOFT_SPI 1
// This is NOT required if using an SD card breakout interfaced
// directly to the SPI bus of the Mega (pins 50-53), or if using
// a non-Mega, Uno-style board.
#include <Adafruit_VC0706.h>
#include <SPI.h>
#include <SD.h>
#if defined(__AVR__) || defined(ESP8266)
// On Uno: camera TX connected to pin 2, camera RX to pin 3:
#include <SoftwareSerial.h>
SoftwareSerial cameraconnection(2, 3);
// On Mega: camera TX connected to pin 69 (A15), camera RX to pin 3:
//SoftwareSerial cameraconnection(69, 3);
#else
// On Leonardo/M0/etc, others with hardware serial, use hardware serial!
// Using hardware serial on Mega: camera TX conn. to RX1,
// camera RX to TX1, no SoftwareSerial object is required:
#define cameraconnection Serial1
#endif
Adafruit_VC0706 cam = Adafruit_VC0706(&cameraconnection);
// SD card chip select line varies among boards/shields:
// Adafruit SD shields and modules: pin 10
// Arduino Ethernet shield: pin 4
// Sparkfun SD shield: pin 8
// Arduino Mega w/hardware SPI: pin 53
// Teensy 2.0: pin 0
// Teensy++ 2.0: pin 20
#define chipSelect 10
// Pins for camera connection are configurable.
// With the Arduino Uno, etc., most pins can be used, except for
// those already in use for the SD card (10 through 13 plus
// chipSelect, if other than pin 10).
// With the Arduino Mega, the choices are a bit more involved:
// 1) You can still use SoftwareSerial and connect the camera to
// a variety of pins...BUT the selection is limited. The TX
// pin from the camera (RX on the Arduino, and the first
// argument to SoftwareSerial()) MUST be one of: 62, 63, 64,
// 65, 66, 67, 68, or 69. If MEGA_SOFT_SPI is set (and using
// a conventional Arduino SD shield), pins 50, 51, 52 and 53
// are also available. The RX pin from the camera (TX on
// Arduino, second argument to SoftwareSerial()) can be any
// pin, again excepting those used by the SD card.
// 2) You can use any of the additional three hardware UARTs on
// the Mega board (labeled as RX1/TX1, RX2/TX2, RX3,TX3),
// but must specifically use the two pins defined by that
// UART; they are not configurable. In this case, pass the
// desired Serial object (rather than a SoftwareSerial
// object) to the VC0706 constructor.
void setup() {
// When using hardware SPI, the SS pin MUST be set to an
// output (even if not connected or used). If left as a
// floating input w/SPI on, this can cause lockuppage.
#if !defined(SOFTWARE_SPI)
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
if(chipSelect != 53) pinMode(53, OUTPUT); // SS on Mega
#else
if(chipSelect != 10) pinMode(10, OUTPUT); // SS on Uno, etc.
#endif
#endif
Serial.begin(9600);
Serial.println("VC0706 Camera snapshot test");
// see if the card is present and can be initialized:
if (!SD.begin(chipSelect)) {
Serial.println("Card failed, or not present");
// don't do anything more:
return;
}
// Try to locate the camera
if (cam.begin()) {
Serial.println("Camera Found:");
} else {
Serial.println("No camera found?");
return;
}
// Print out the camera version information (optional)
char *reply = cam.getVersion();
if (reply == 0) {
Serial.print("Failed to get version");
} else {
Serial.println("-----------------");
Serial.print(reply);
Serial.println("-----------------");
}
// Set the picture size - you can choose one of 640x480, 320x240 or 160x120
// Remember that bigger pictures take longer to transmit!
cam.setImageSize(VC0706_640x480); // biggest
//cam.setImageSize(VC0706_320x240); // medium
//cam.setImageSize(VC0706_160x120); // small
// You can read the size back from the camera (optional, but maybe useful?)
uint8_t imgsize = cam.getImageSize();
Serial.print("Image size: ");
if (imgsize == VC0706_640x480) Serial.println("640x480");
if (imgsize == VC0706_320x240) Serial.println("320x240");
if (imgsize == VC0706_160x120) Serial.println("160x120");
Serial.println("Snap in 3 secs...");
delay(3000);
if (! cam.takePicture())
Serial.println("Failed to snap!");
else
Serial.println("Picture taken!");
// Create an image with the name IMAGExx.JPG
char filename[13];
strcpy(filename, "IMAGE00.JPG");
for (int i = 0; i < 100; i++) {
filename[5] = '0' + i/10;
filename[6] = '0' + i%10;
// create if does not exist, do not open existing, write, sync after write
if (! SD.exists(filename)) {
break;
}
}
// Open the file for writing
File imgFile = SD.open(filename, FILE_WRITE);
// Get the size of the image (frame) taken
uint16_t jpglen = cam.frameLength();
Serial.print("Storing ");
Serial.print(jpglen, DEC);
Serial.print(" byte image.");
int32_t time = millis();
pinMode(8, OUTPUT);
// Read all the data up to # bytes!
byte wCount = 0; // For counting # of writes
while (jpglen > 0) {
// read 32 bytes at a time;
uint8_t *buffer;
uint8_t bytesToRead = min((uint16_t)32, jpglen); // change 32 to 64 for a speedup but may not work with all setups!
buffer = cam.readPicture(bytesToRead);
imgFile.write(buffer, bytesToRead);
if(++wCount >= 64) { // Every 2K, give a little feedback so it doesn't appear locked up
Serial.print('.');
wCount = 0;
}
//Serial.print("Read "); Serial.print(bytesToRead, DEC); Serial.println(" bytes");
jpglen -= bytesToRead;
}
imgFile.close();
time = millis() - time;
Serial.println("done!");
Serial.print(time); Serial.println(" ms elapsed");
}
void loop() {
}
- スケッチをコンパイルしてArduino UNO R3に書き込みます。コンパイルする時にwarningは発生しましたが、Arduino UNOに書き込むと撮影の動作を開始しました。シアルモニタを開くと撮影の状況が表示され、撮影終了後にはSDカードにjpegの画像ファイルが保存されていました。
関連する記事は?
- [Arduinoにjpegカメラを付けて一定間隔で撮影した画像をSDカードに保存しました]で一定間隔で撮影した画像をjpegファイルにタイムスタンプを付けてSDカードに保存する方法をまとめています。
- [jpegカメラで屋外の風景を撮影をしました]で作成したシールドを使って屋外で画像を撮影しました。
ご質問、誤植の指摘などありましたら。「問い合わせ 」のページからお願いします。