当别人都是长枪大炮地挤在一起拍照时,你夹在当中用狗头来照相,当然显不出你的个性.如果换成是自己DIY的个性化数码相机,那就完全不一样了.
Arduino支持SPI或TTL接口的摄像头(30万像素,最高画质640*480).所以自己制作的话就很容易了.目前国内外使用的TTL摄像头基本只有一种,就是采用中星微VC0706芯片的产品.这种TTL/RS232接口的摄像头万能的淘宝上有卖的,自己选就行了.还有一种是同时带SPI和TTL/RS232接口的.SPI的速度远快于TTL的,所以如果有要求更快处理速度的应用,可以考虑使用SPI的版本.
玩Arduino的Ada女士网站上有这个摄像头的运行库和例程,可以直接下载并测试.
从淘宝上买的摄像头没注意,发过来的是RS232的版本,所以需要把MAX3232的芯片拆掉后,才能接到Arduino UNO的板子上.由于摄像头输出的TTL电平是3.3V的,所以在与5V的Arduino板接线时,输入端最好用两个10K左右的电阻做一下分压,以免人品不好损坏电路.
自己DIY相机的元件清单:
1/Arduino板一个,我用的是UNO版本的
2/VC0706摄像头一个
3/按钮2个
4/带开关的4节5号电池盒一个
5/10K电阻3个
6/LED一个
7/SD转接板一个
8/格式化为FAT格式的SD卡一张(如果用shield板的话,TF卡也可以)
9/导线若干
10/面包板一个
国外有个Arduino+TTL摄像头的网页,国内有网页还翻译成了中文.那个制作的作者到目前为止还没有公布代码.他用的是锂电板,变压成5V给UNO使用.但那个方案是有问题的.因为UNO板子外接电源时,不能自动工作,只有按RESET复位按钮电路才能正常工作.但他公布的电路图中,并没有外接复位按钮的部分.估计这也是其没有公布源代码的原因之一吧.
接线如下图.这个图是之前的版本,我的这个图也没有接复位按钮,只接了拍照按钮.按照按钮的接线应该接到Digital接口7上.图中的接线是之前随便接的.不正确.如果是使用USB来供电,电路是正常没问题的.如果外接电池的话,需要按板子上的复位按钮才行.图中也没有接存储指示灯的LED.实际接线时,直接串2K以上的电阻到digital 13脚并接地即可.
摄像头的TTL接线并不是接于UNO板的物理TX和RX脚,而是接于digital 2/3脚.通过虚拟串口来进行通信.
UNO与SD的通信,通过SPI接口,需要根据SD转接板的接口定义来设置.我的板子接线是这样的,请注意接线颜色:
UNO端从digital 10-13,接线颜色分别为白绿蓝黄.
Ada女士的TTL摄像头例程并不能用于相机的功能.所以需要做修改,以下是我根据接线情况修改后的拍照程序,使用Arduino 1.04版IDE编译通过:
#include
#include
#include
#define chipSelect 10
#define Button 7 //定义拍照按钮针脚为7
int ButtonVal=0; //变量ButtonVal用来存储拍照按钮状态
#if ARDUINO >= 100
// 定义虚拟串口,对于Uno板摄像头TX脚连到Digital pin 2, 摄像头RX脚连到Digital pin 3:
SoftwareSerial cameraconnection = SoftwareSerial(2, 3);
#else
NewSoftSerial cameraconnection = NewSoftSerial(2, 3);
#endif
Adafruit_VC0706 cam = Adafruit_VC0706(&cameraconnection);
void setup() {
// 使用硬件SPI时, SS必须设为输出
#if !defined(SOFTWARE_SPI)
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
if(chipSelect != 53) pinMode(53, OUTPUT); // 使用mega2560时SS设置
#else
if(chipSelect != 10) pinMode(10, OUTPUT); // 使用UNO时SS设置
#endif
#endif
//串口监控输出及定义:
Serial.begin(9600);
pinMode(Button, INPUT);
Serial.println("VC0706 Camera snapshot test");
// 判断SD卡是否插入并初始化:
if (!SD.begin(chipSelect)) {
Serial.println("Card failed, or not present");
// 停止:
return;
}
// 初始化摄像头
if (cam.begin()) {
Serial.println("Camera Found:");
} else {
Serial.println("No camera found?");
return;
}
// 输出摄像头版本
char *reply = cam.getVersion();
if (reply == 0) {
Serial.print("Failed to get version");
} else {
Serial.println("-----------------");
Serial.print(reply);
Serial.println("-----------------");
}
// 设置拍照尺寸,可设为640x480, 320x240及160x120
// 尺寸越大数据传输时间越长!
cam.setImageSize(VC0706_640x480); // biggest
//cam.setImageSize(VC0706_320x240); // medium
//cam.setImageSize(VC0706_160x120); // small
// 可从摄像头读取图片大小
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");
}
void loop() {
//按拍照按钮拍一张照片
ButtonVal=digitalRead(Button);
if (ButtonVal==HIGH){
Serial.println("Snaping Picture...");
delay(20);
if (! cam.takePicture())
Serial.println("Failed to snap!");
else
Serial.println("Picture taken!");
// 以IMAGExx.JPG为文件名创建图片文件
char filename[13];
strcpy(filename, "IMAGE00.JPG");
for (int i = 0; i < 99; i++) {
filename[5] = '0' + i/10;
filename[6] = '0' + i%10;
if (! SD.exists(filename)) {
break;
}
}
// 打开图像文件并写入
File imgFile = SD.open(filename, FILE_WRITE);
// 获取图像文件大小
uint16_t jpglen = cam.frameLength();
Serial.print("Storing ");
Serial.print(jpglen, DEC);
Serial.print(" byte image.");
int32_t time = millis();
pinMode(8, OUTPUT);
// 读数据到 # bytes!
byte wCount = 0; // 计数 # 来写
while (jpglen > 0) {
// 一次读取 32 bytes;
uint8_t *buffer;
uint8_t bytesToRead = min(32, jpglen);
buffer = cam.readPicture(bytesToRead);
imgFile.write(buffer, bytesToRead);
if(++wCount >= 64) { // 每2K发个反馈,以避免出现锁定现象
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");
}
cam.begin(); //摄像头重新初始清缓存
ButtonVal=0; //按钮值重新设为低
}
串口的读取速度是很慢的,640*480的照片,存储过程大约需要15秒左右.
这个摄像头默认的通信速度为38400.如果改成57600会快不少.但在面包板上试验时,可能是因为这种面包板接线电气特性问题,存储时会出问题.有可能使用焊接的时候会好一些.把摄像头默认速度改为57600可以使用中星微的官方VC0706CommTool程序设置.设置完成后断电再加电即可.
当然,改了摄像头的默认速度后,也需要修改库里面定义的通信速度,修改方法:
将摄像头库里面的Adafruit_VC0706.h文件:
boolean begin(uint16_t baud = 38400);
里面的38400改为57600即可.
程序调试无误后,就可以写到UNO板里.然后根据国外的那个人做的外壳样式,用纸壳做个个性化的外壳,把这些东西装上即可.最好焊接一下.以免出问题.
简单地把DIY个性照相机的过程写了一下.有些细节做了省略.可能并不适合新手.见谅