2017/02/22

ArduCAM OV5642 擷取影像至SD Card

板子為Arduino UNO R3
鏡頭為OV5642
擴充版為ArduCAM Shield V2
函式庫是由ArduCAM所提供
使用前記得修改函式庫

執行結果:



Code:
/*
Name:  CaptureToSD.ino
Created: 2/15/2017 11:42:33 AM
Author: C.Y.Fang
*/
#include <ArduCAM.h>
#include <memorysaver.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>

#define SD_CS 9
#define BAUD_RATE 115200
const int SPI_CS = 10;
ArduCAM myCAM(OV5642, SPI_CS);

// the setup function runs once when you press reset or power the board
void setup() {
 Wire.begin();
 Serial.begin(BAUD_RATE);
 Serial.println(F("ArduCAM Start!"));
 pinMode(SPI_CS, OUTPUT);
 SPI.begin();
 InitCamera();
 delay(1000);
}

// the loop function runs over and over again until power down or reset
void loop() {
 CaptureImage();
 delay(3000);
}

void InitCamera() {
 uint8_t vid, pid;
 uint8_t temp;

 while (1) {
  myCAM.write_reg(ARDUCHIP_TEST1, 0x55);
  temp = myCAM.read_reg(ARDUCHIP_TEST1);
  if (temp != 0x55) {
   Serial.println(("SPI interface Error!"));
   delay(1000);
   continue;
  }
  else {
   break;
  }
 }

 while (!SD.begin(SD_CS)) {
  Serial.println("SD Card error");
  delay(1000);
 }

 while (1) {
  myCAM.wrSensorReg16_8(0xff, 0x01);
  myCAM.rdSensorReg16_8(OV5642_CHIPID_HIGH, &vid);
  myCAM.rdSensorReg16_8(OV5642_CHIPID_LOW, &pid);
  if ((vid != 0x56) || (pid != 0x42)) {
   Serial.println(F("Can't find OV5642 module!"));
   delay(1000);
   continue;
  }
  else {
   break;
  }
 }

 myCAM.set_format(JPEG);
 myCAM.write_reg(ARDUCHIP_TIM, VSYNC_LEVEL_MASK);
 myCAM.OV5642_set_JPEG_size(OV5642_2592x1944);
 myCAM.InitCAM();
}


void CaptureImage() {
 char str[8];
 byte buff[256];
 static int i = 0;
 static int k = 0;
 uint8_t temp = 0, temp_last = 0;
 uint32_t length = 0;
 bool is_header = false;
 File outFile;


 myCAM.flush_fifo();
 myCAM.clear_fifo_flag();
 myCAM.start_capture();
 while (!myCAM.get_bit(ARDUCHIP_TRIG, CAP_DONE_MASK));

 length = myCAM.read_fifo_length();
 if (length >= MAX_FIFO_SIZE)
 {
  //8M
  Serial.println("8M");
  return;
 }
 else if (length == 0) {
  //0KB
  Serial.println("0KB");
  return;
 }

 k++;
 itoa(k, str, 10);
 strcat(str, ".jpg");
 outFile = SD.open(str, O_WRITE | O_CREAT | O_TRUNC);
 if (!outFile) {
  Serial.println("SD Card");
  return;
 }

 i = 0;
 myCAM.CS_LOW();
 myCAM.set_fifo_burst();

 while (length--)
 {
  temp_last = temp;
  temp = SPI.transfer(0x00);
  if ((temp == 0xD9) && (temp_last == 0xFF))
  {
   buff[i++] = temp;
   myCAM.CS_HIGH();
   outFile.write(buff, i);
   outFile.flush();
   outFile.close();
   Serial.println(F("Image save OK!"));
   is_header = false;
   i = 0;
  }
  if (is_header == true)
  {
   if (i < 256)
    buff[i++] = temp;
   else
   {
    myCAM.CS_HIGH();
    outFile.write(buff, 256);
    i = 0;
    buff[i++] = temp;
    myCAM.CS_LOW();
    myCAM.set_fifo_burst();
   }
  }
  else if ((temp == 0xD8) & (temp_last == 0xFF))
  {
   is_header = true;
   buff[i++] = temp_last;
   buff[i++] = temp;
  }
 }
}