當別人都是長槍大炮地擠在一起拍照時,你夾在當中用狗頭來照相,當然顯不出你的個性.如果換成是自己DIY的個性化數(shù)碼相機,那就完全不一樣了.
Arduino支持SPI或TTL接口的攝像頭(30萬像素,最高畫質(zhì)640*480).所以自己制作的話就很容易了.目前國內(nèi)外使用的TTL攝像頭基本只有一種,就是采用中星微VC0706芯片的產(chǎn)品.這種TTL/RS232接口的攝像頭萬能的淘寶上有賣的,自己選就行了.還有一種是同時帶SPI和TTL/RS232接口的.SPI的速度遠快于TTL的,所以如果有要求更快處理速度的應用,可以考慮使用SPI的版本.
玩Arduino的Ada女士網(wǎng)站上有這個攝像頭的運行庫和例程,可以直接下載并測試.
從淘寶上買的攝像頭沒注意,發(fā)過來的是RS232的版本,所以需要把MAX3232的芯片拆掉后,才能接到Arduino UNO的板子上.由于攝像頭輸出的TTL電平是3.3V的,所以在與5V的Arduino板接線時,輸入端最好用兩個10K左右的電阻做一下分壓,以免人品不好損壞電路.
自己DIY相機的元件清單:
1/Arduino板一個,我用的是UNO版本的
2/VC0706攝像頭一個
3/按鈕2個
4/帶開關(guān)的4節(jié)5號電池盒一個
5/10K電阻3個
6/LED一個
7/SD轉(zhuǎn)接板一個
8/格式化為FAT格式的SD卡一張(如果用shield板的話,TF卡也可以)
9/導線若干
10/面包板一個
國外有個Arduino+TTL攝像頭的網(wǎng)頁,國內(nèi)有網(wǎng)頁還翻譯成了中文.那個制作的作者到目前為止還沒有公布代碼.他用的是鋰電板,變壓成5V給UNO使用.但那個方案是有問題的.因為UNO板子外接電源時,不能自動工作,只有按RESET復位按鈕電路才能正常工作.但他公布的電路圖中,并沒有外接復位按鈕的部分.估計這也是其沒有公布源代碼的原因之一吧.
接線如下圖.這個圖是之前的版本,我的這個圖也沒有接復位按鈕,只接了拍照按鈕.按照按鈕的接線應該接到Digital接口7上.圖中的接線是之前隨便接的.不正確.如果是使用USB來供電,電路是正常沒問題的.如果外接電池的話,需要按板子上的復位按鈕才行.圖中也沒有接存儲指示燈的LED.實際接線時,直接串2K以上的電阻到digital 13腳并接地即可.
攝像頭的TTL接線并不是接于UNO板的物理TX和RX腳,而是接于digital 2/3腳.通過虛擬串口來進行通信.
UNO與SD的通信,通過SPI接口,需要根據(jù)SD轉(zhuǎn)接板的接口定義來設(shè)置.我的板子接線是這樣的,請注意接線顏色:
UNO端從digital 10-13,接線顏色分別為白綠藍黃.
Ada女士的TTL攝像頭例程并不能用于相機的功能.所以需要做修改,以下是我根據(jù)接線情況修改后的拍照程序,使用Arduino 1.04版IDE編譯通過:
#include <Adafruit_VC0706.h> #include <SD.h>
#include <SoftwareSerial.h>
#define chipSelect 10 #define Button 7 //定義拍照按鈕針腳為7 int ButtonVal=0; //變量ButtonVal用來存儲拍照按鈕狀態(tài)
#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必須設(shè)為輸出 #if !defined(SOFTWARE_SPI) #if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) if(chipSelect != 53) pinMode(53, OUTPUT); // 使用mega2560時SS設(shè)置 #else if(chipSelect != 10) pinMode(10, OUTPUT); // 使用UNO時SS設(shè)置
#endif #endif
//串口監(jiān)控輸出及定義:
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("-----------------"); }
// 設(shè)置拍照尺寸,可設(shè)為640x480, 320x240及160x120 // 尺寸越大數(shù)據(jù)傳輸時間越長! 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為文件名創(chuàng)建圖片文件 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); // 讀數(shù)據(jù)到 # bytes! byte wCount = 0; // 計數(shù) # 來寫 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發(fā)個反饋,以避免出現(xiàn)鎖定現(xiàn)象 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; //按鈕值重新設(shè)為低 }
串口的讀取速度是很慢的,640*480的照片,存儲過程大約需要15秒左右.
這個攝像頭默認的通信速度為38400.如果改成57600會快不少.但在面包板上試驗時,可能是因為這種面包板接線電氣特性問題,存儲時會出問題.有可能使用焊接的時候會好一些.把攝像頭默認速度改為57600可以使用中星微的官方VC0706CommTool程序設(shè)置.設(shè)置完成后斷電再加電即可.
當然,改了攝像頭的默認速度后,也需要修改庫里面定義的通信速度,修改方法:
將攝像頭庫里面的Adafruit_VC0706.h文件:
boolean begin(uint16_t baud = 38400);
里面的38400改為57600即可.
程序調(diào)試無誤后,就可以寫到UNO板里.然后根據(jù)國外的那個人做的外殼樣式,用紙殼做個個性化的外殼,把這些東西裝上即可.最好焊接一下.以免出問題.
簡單地把DIY個性照相機的過程寫了一下.有些細節(jié)做了省略.可能并不適合新手.見諒.
|