找回密码
 邀请注册

QQ登录

只需一步,快速开始

查看: 508|回复: 0

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

[复制链接]
  • TA的每日心情
    无聊
    2024-3-25 09:23
  • 签到天数: 67 天

    [LV.6]维修爱好者2级网红

    81

    主题

    455

    回帖

    1252

    积分

    中级会员

    积分
    1252

    2023优秀会员VIP

    发表于 2023-9-19 11:37:43 | 显示全部楼层 |阅读模式

    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);
    #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;  //按钮值重新设为低
    }


    该会员没有填写今日想说内容.

    该用户从未签到

    24

    主题

    895

    回帖

    1250

    积分

    论坛元老

    积分
    1250
    发表于 2023-9-19 11:37:43 | 显示全部楼层
    感谢分享!论坛有您更精彩!
    您需要登录后才可以回帖 登录 | 邀请注册

    本版积分规则

    QQ|手机版|家电电工资料网 ( 辽ICP备17010435号-3 )|网站地图|辽公网安备 21140202000087号

    GMT+8, 2024-12-22 21:36

    Powered by Discuz! X3.5

    © 2001-2024 Discuz! Team.

    快速回复 返回顶部 返回列表