创意人生 发表于 2023-9-19 11:37:43

Arduino+TTL摄像头自制拉风数码相机

Arduino支持SPI或TTL接口的摄像头(30万像素,最高画质640*480).所以自己制作的话就很容易了.目前国内外使用的TTL摄像头基本只有一种,就是采用中星微VC0706芯片的产品.这种TTL/RS232接口的摄像头万能的淘宝上有卖的,自己选就行了.还有一种是同时带SPI和TTL/RS232接口的.SPI的速度远快于TTL的,所以如果有要求更快处理速度的应用,可以考虑使用SPI的版本.

#include <Adafruit_VC0706.h>
#include <SD.h>#include <SoftwareSerial.h>      #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);
#endifAdafruit_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;
                            strcpy(filename, "IMAGE00.JPG");
                            for (int i = 0; i < 99; i++) {
                              filename = '0' + i/10;
                              filename = '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;//按钮值重新设为低
}

修飞机的不是我 发表于 2023-9-19 11:37:43

感谢分享!论坛有您更精彩!
页: [1]
查看完整版本: Arduino+TTL摄像头自制拉风数码相机