Making arducam work with the rest of the sketch

Hi,
I've got a project where I have to build a four legged robot controlled with bluetooth (HC05) capable of taking pictures and sending them to my computer.

I've managed to make the Arducam work in bluetooth and figured out the way to give "orders" to my servos. However I am having a hard time understanding how to include the Arducam code with the rest.

The Arducam code I use is the demo accessible on the Arducam's github

// ArduCAM Mini demo (C)2018 Lee
// Web: http://www.ArduCAM.com
// This program is a demo of how to use most of the functions
// of the library with ArduCAM Mini camera, and can run on any Arduino platform.
// This demo was made for ArduCAM_Mini_2MP.
// It needs to be used in combination with PC software.
//It supports Bluetooth module
// It can take photo continuously as video streaming.
//
// The demo sketch will do the following tasks:
// 1. Set the camera to JPEG output mode.
// 2. Read data from Serial1 port and deal with it
// 3. If receive 0x00-0x08,the resolution will be changed.
// 4. If receive 0x10,camera will capture a JPEG photo and buffer the image to FIFO.Then write datas to Serial1 port.
// 5. If receive 0x20,camera will capture JPEG photo and write datas continuously.Stop when receive 0x21.
// 6. If receive 0x30,camera will capture a BMP  photo and buffer the image to FIFO.Then write datas to Serial1 port.
// 7. If receive 0x11 ,set camera to JPEG output mode.
// 8. If receive 0x31 ,set camera to BMP  output mode.
// This program requires the ArduCAM V4.0.0 (or later) library and ArduCAM_Mini_2MP
// and use Arduino IDE 1.6.8 compiler or above
#include <Wire.h>
#include <ArduCAM.h>
#include <SPI.h>
#include "memorysaver.h"
#include <SoftwareSerial.h>



//This demo can only work on OV2640_MINI_2MP or OV5642_MINI_5MP or OV5642_MINI_5MP_BIT_ROTATION_FIXED platform.
#if !(defined OV5642_MINI_5MP || defined OV5642_MINI_5MP_BIT_ROTATION_FIXED || defined OV2640_MINI_2MP || defined OV3640_MINI_3MP)
  #error Please select the hardware platform and camera module in the ../libraries/ArduCAM/memorysaver.h file
#endif
#define BMPIMAGEOFFSET 66
const char bmp_header[BMPIMAGEOFFSET] PROGMEM =
{
  0x42, 0x4D, 0x36, 0x58, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00, 0x28, 0x00,
  0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x01, 0x00, 0x10, 0x00, 0x03, 0x00,
  0x00, 0x00, 0x00, 0x58, 0x02, 0x00, 0xC4, 0x0E, 0x00, 0x00, 0xC4, 0x0E, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x00, 0xE0, 0x07, 0x00, 0x00, 0x1F, 0x00,
  0x00, 0x00
};
// set pin 7 as the slave select for the digital pot:
const int CS = 7  ;
bool is_header = false;
int mode = 0;
uint8_t start_capture = 0;
#if defined (OV2640_MINI_2MP)
  ArduCAM myCAM( OV2640, CS );
#elif defined (OV3640_MINI_3MP)
ArduCAM myCAM( OV3640, CS );
#else
  ArduCAM myCAM( OV5642, CS );
#endifded
uint8_t read_fifo_burst(ArduCAM myCAM);
void setup() {
// put your setup code here, to run once:
uint8_t vid, pid;
uint8_t temp;
#if defined(__SAM3X8E__)
  Wire1.begin();
  Serial1.begin(9600));
#else
  Wire.begin();
  Serial1.begin(9600);
#endif
Serial1.println(F("ACK CMD ArduCAM Start! END"));
// set the CS as an output:
pinMode(CS, OUTPUT);
digitalWrite(CS, HIGH);
// initialize SPI:
//SPI.setClockDivider(SPI_CLOCK_DIV64);
SPI.begin();

//Reset the CPLD
myCAM.write_reg(0x07, 0x80);
delay(100);
myCAM.write_reg(0x07, 0x00);
delay(100);
while(1){
  //Check if the ArduCAM SPI bus is OK
  myCAM.write_reg(ARDUCHIP_TEST1, 0x55);
  temp = myCAM.read_reg(ARDUCHIP_TEST1);
  if (temp != 0x55){
    Serial1.println(F("ACK CMD SPI interface Error! END"));
    delay(1000);continue;
  }else{
    Serial1.println(F("ACK CMD SPI interface OK. END"));break;
  }
}

#if defined (OV2640_MINI_2MP)
  while(1){
    //Check if the camera module type is OV2640
    myCAM.wrSensorReg8_8(0xff, 0x01);
    myCAM.rdSensorReg8_8(OV2640_CHIPID_HIGH, &vid);
    myCAM.rdSensorReg8_8(OV2640_CHIPID_LOW, &pid);
    if ((vid != 0x26 ) && (( pid != 0x41 ) || ( pid != 0x42 ))){
      Serial1.println(F("ACK CMD Can't find OV2640 module! END"));
      delay(1000);continue;
    }
    else{
      Serial1.println(F("ACK CMD OV2640 detected. END"));break;
    } 
  }
#elif defined (OV3640_MINI_3MP)
  while(1){
    //Check if the camera module type is OV3640
    myCAM.rdSensorReg16_8(OV3640_CHIPID_HIGH, &vid);
    myCAM.rdSensorReg16_8(OV3640_CHIPID_LOW, &pid);
    if ((vid != 0x36) || (pid != 0x4C)){
      Serial1.println(F("ACK CMD Can't find OV3640 module! END"));
      delay(1000);continue; 
    }else{
      Serial1.println(F("ACK CMD OV3640 detected. END"));break;    
    }
 } 
  
#else
  while(1){
    //Check if the camera module type is OV5642
    myCAM.wrSensorReg16_8(0xff, 0x01);
    myCAM.rdSensorReg16_8(OV5642_CHIPID_HIGH, &vid);
    myCAM.rdSensorReg16_8(OV5642_CHIPID_LOW, &pid);
    if((vid != 0x56) || (pid != 0x42)){
      Serial1.println(F("ACK CMD Can't find OV5642 module! END"));
      delay(1000);continue;
    }
    else{
      Serial1.println(F("ACK CMD OV5642 detected. END"));break;
    } 
  }
#endif
//Change to JPEG capture mode and initialize the OV5642 module
myCAM.set_format(JPEG);
myCAM.InitCAM();
#if defined (OV2640_MINI_2MP)
  myCAM.OV2640_set_JPEG_size(OV2640_320x240);
#elif defined (OV3640_MINI_3MP)
  myCAM.OV3640_set_JPEG_size(OV3640_320x240);
#else
  myCAM.write_reg(ARDUCHIP_TIM, VSYNC_LEVEL_MASK);   //VSYNC is active HIGH
  myCAM.OV5642_set_JPEG_size(OV5642_320x240);
#endif
delay(1000);
myCAM.clear_fifo_flag();
#if !(defined (OV2640_MINI_2MP))
myCAM.write_reg(ARDUCHIP_FRAMES,0x00);
#endif
}
void loop() {
// put your main code here, to run repeatedly:
uint8_t temp = 0xff, temp_last = 0;
bool is_header = false;
if (Serial1.available())
{
  temp = Serial1.read();
  switch (temp)
  {
    case 0:
    #if defined (OV2640_MINI_2MP)
      myCAM.OV2640_set_JPEG_size(OV2640_160x120);delay(1000);
      Serial1.println(F("ACK CMD switch to OV2640_160x120 END"));
    #elif defined (OV3640_MINI_3MP)
      myCAM.OV3640_set_JPEG_size(OV3640_176x144);delay(1000);
      Serial1.println(F("ACK CMD switch to OV2640_160x120 END"));
    #else
      myCAM.OV5642_set_JPEG_size(OV5642_320x240);delay(1000);
      Serial1.println(F("ACK CMD switch to OV5642_320x240 END"));
    #endif
    temp = 0xff;
    break;
    case 1:
    #if defined (OV2640_MINI_2MP)
      myCAM.OV2640_set_JPEG_size(OV2640_176x144);delay(1000);
      Serial1.println(F("ACK CMD switch to OV2640_176x144 END"));
    #elif defined (OV3640_MINI_3MP)
      myCAM.OV3640_set_JPEG_size(OV3640_320x240);delay(1000);
      Serial1.println(F("ACK CMD switch to OV3640_320x240 END"));
    #else
      myCAM.OV5642_set_JPEG_size(OV5642_640x480);delay(1000);
      Serial1.println(F("ACK CMD switch to OV5642_640x480 END"));
    #endif
    temp = 0xff;
    break;
    case 2: 
    #if defined (OV2640_MINI_2MP)
      myCAM.OV2640_set_JPEG_size(OV2640_320x240);delay(1000);
      Serial1.println(F("ACK CMD switch to OV2640_320x240 END"));
     #elif defined (OV3640_MINI_3MP)
      myCAM.OV3640_set_JPEG_size(OV3640_352x288);delay(1000);
      Serial1.println(F("ACK CMD switch to OV3640_352x288 END"));
    #else
      myCAM.OV5642_set_JPEG_size(OV5642_1024x768);delay(1000);
      Serial1.println(F("ACK CMD switch to OV5642_1024x768 END"));
    #endif
    temp = 0xff;
    break;
    case 3:
    temp = 0xff;
    #if defined (OV2640_MINI_2MP)
      myCAM.OV2640_set_JPEG_size(OV2640_352x288);delay(1000);
      Serial1.println(F("ACK CMD switch to OV2640_352x288 END"));
    #elif defined (OV3640_MINI_3MP)
      myCAM.OV3640_set_JPEG_size(OV3640_640x480);delay(1000);
      Serial1.println(F("ACK CMD switch to OV3640_640x480 END"));
    #else
      myCAM.OV5642_set_JPEG_size(OV5642_1280x960);delay(1000);
      Serial1.println(F("ACK CMD switch to OV5642_1280x960 END"));
    #endif
    break;
    case 4:
    temp = 0xff;
    #if defined (OV2640_MINI_2MP)
      myCAM.OV2640_set_JPEG_size(OV2640_640x480);delay(1000);
      Serial1.println(F("ACK CMD switch to OV2640_640x480 END"));
   #elif defined (OV3640_MINI_3MP)
      myCAM.OV3640_set_JPEG_size(OV3640_800x600);delay(1000);
      Serial1.println(F("ACK CMD switch to OV3640_800x600 END"));
    #else
      myCAM.OV5642_set_JPEG_size(OV5642_1600x1200);delay(1000);
      Serial1.println(F("ACK CMD switch to OV5642_1600x1200 END"));
    #endif
    break;
    case 5:
    temp = 0xff;
    #if defined (OV2640_MINI_2MP)
      myCAM.OV2640_set_JPEG_size(OV2640_800x600);delay(1000);
      Serial1.println(F("ACK CMD switch to OV2640_800x600 END"));
    #elif defined (OV3640_MINI_3MP)
      myCAM.OV3640_set_JPEG_size(OV3640_1024x768);delay(1000);
      Serial1.println(F("ACK CMD switch to OV3640_1024x768 END"));
    #else
      myCAM.OV5642_set_JPEG_size(OV5642_2048x1536);delay(1000);
      Serial1.println(F("ACK CMD switch to OV5642_2048x1536 END"));
    #endif
    break;
    case 6:
    temp = 0xff;
    #if defined (OV2640_MINI_2MP)
      myCAM.OV2640_set_JPEG_size(OV2640_1024x768);delay(1000);
      Serial1.println(F("ACK CMD switch to OV2640_1024x768 END"));
   #elif defined (OV3640_MINI_3MP)
      myCAM.OV3640_set_JPEG_size(OV3640_1280x960);delay(1000);
      Serial1.println(F("ACK CMD switch to OV3640_1280x960 END"));
    #else
      myCAM.OV5642_set_JPEG_size(OV5642_2592x1944);delay(1000);
      Serial1.println(F("ACK CMD switch to OV5642_2592x1944 END"));
    #endif
    break;
    case 7:
    temp = 0xff;
   #if defined (OV2640_MINI_2MP)
    myCAM.OV2640_set_JPEG_size(OV2640_1280x1024);delay(1000);
    Serial1.println(F("ACK CMD switch to OV2640_1280x1024 END"));
   #else
      myCAM.OV3640_set_JPEG_size(OV3640_1600x1200);delay(1000);
      Serial1.println(F("ACK CMD switch to OV3640_1600x1200 END"));
   #endif
    break;
    case 8:
    temp = 0xff;
   #if defined (OV2640_MINI_2MP)
     myCAM.OV2640_set_JPEG_size(OV2640_1600x1200);delay(1000);
     Serial1.println(F("ACK CMD switch to OV2640_1600x1200 END"));
   #else
     myCAM.OV3640_set_JPEG_size(OV3640_2048x1536);delay(1000);
     Serial1.println(F("ACK CMD switch to OV3640_2048x1536 END"));
   #endif
    break;
    case 0x10:
    mode = 1;
    temp = 0xff;
    start_capture = 1;
    Serial1.println(F("ACK CMD CAM start single shoot. END"));
    break;
    case 0x11: 
    temp = 0xff;
    myCAM.set_format(JPEG);
    myCAM.InitCAM();
    #if !(defined (OV2640_MINI_2MP))
    myCAM.set_bit(ARDUCHIP_TIM, VSYNC_LEVEL_MASK);
    #endif
    break;
    case 0x20:
    mode = 2;
    temp = 0xff;
    start_capture = 2;
    Serial1.println(F("ACK CMD CAM start video streaming. END"));
    break;
    case 0x30:
    mode = 3;
    temp = 0xff;
    start_capture = 3;
    Serial1.println(F("ACK CMD CAM start single shoot. END"));
    break;
    case 0x31:
    temp = 0xff;
    myCAM.set_format(BMP);
    myCAM.InitCAM();
    #if !(defined (OV2640_MINI_2MP))        
    myCAM.clear_bit(ARDUCHIP_TIM, VSYNC_LEVEL_MASK);
    #endif
    myCAM.wrSensorReg16_8(0x3818, 0x81);
    myCAM.wrSensorReg16_8(0x3621, 0xA7);
    break;
    default:
    break;
  }
}
if (mode == 1)
{
  if (start_capture == 1)
  {
    myCAM.flush_fifo();
    myCAM.clear_fifo_flag();
    //Start capture
    myCAM.start_capture();
    start_capture = 0;
  }
  if (myCAM.get_bit(ARDUCHIP_TRIG, CAP_DONE_MASK))
  {
    Serial1.println(F("ACK CMD CAM Capture Done. END"));
    delay(50);
    read_fifo_burst(myCAM);
    //Clear the capture done flag
    myCAM.clear_fifo_flag();
  }
}
else if (mode == 2)
{
  while (1)
  {
    temp = Serial1.read();
    if (temp == 0x21)
    {
      start_capture = 0;
      mode = 0;
      Serial1.println(F("ACK CMD CAM stop video streaming. END"));
      break;
    }
    if (start_capture == 2)
    {
      myCAM.flush_fifo();
      myCAM.clear_fifo_flag();
      //Start capture
      myCAM.start_capture();
      start_capture = 0;
    }
    if (myCAM.get_bit(ARDUCHIP_TRIG, CAP_DONE_MASK))
    {
      uint32_t length = 0;
      length = myCAM.read_fifo_length();
      if ((length >= MAX_FIFO_SIZE) | (length == 0))
      {
        myCAM.clear_fifo_flag();
        start_capture = 2;
        continue;
      }
      myCAM.CS_LOW();
      myCAM.set_fifo_burst();//Set fifo burst mode
      temp =  SPI.transfer(0x00);
      length --;
      while ( length-- )
      {
        temp_last = temp;
        temp =  SPI.transfer(0x00);
        if (is_header == true)
        {
          Serial1.write(temp);
        }
        else if ((temp == 0xD8) & (temp_last == 0xFF))
        {
          is_header = true;
          Serial1.println(F("ACK IMG END"));
          Serial1.write(temp_last);
          Serial1.write(temp);
        }
        if ( (temp == 0xD9) && (temp_last == 0xFF) ) //If find the end ,break while,
        break;
        delayMicroseconds(15);
      }
      myCAM.CS_HIGH();
      myCAM.clear_fifo_flag();
      start_capture = 2;
      is_header = false;
    }
  }
}
else if (mode == 3)
{
  if (start_capture == 3)
  {
    //Flush the FIFO
    myCAM.flush_fifo();
    myCAM.clear_fifo_flag();
    //Start capture
    myCAM.start_capture();
    start_capture = 0;
  }
  if (myCAM.get_bit(ARDUCHIP_TRIG, CAP_DONE_MASK))
  {
    Serial1.println(F("ACK CMD CAM Capture Done. END"));
    delay(50);
    uint8_t temp, temp_last;
    uint32_t length = 0;
    length = myCAM.read_fifo_length();
    if (length >= MAX_FIFO_SIZE ) 
    {
      Serial1.println(F("ACK CMD Over size. END"));
      myCAM.clear_fifo_flag();
      return;
    }
    if (length == 0 ) //0 kb
    {
      Serial1.println(F("ACK CMD Size is 0. END"));
      myCAM.clear_fifo_flag();
      return;
    }
    myCAM.CS_LOW();
    myCAM.set_fifo_burst();//Set fifo burst mode
    
    Serial1.write(0xFF);
    Serial1.write(0xAA);
    for (temp = 0; temp < BMPIMAGEOFFSET; temp++)
    {
      Serial1.write(pgm_read_byte(&bmp_header[temp]));
    }
    SPI.transfer(0x00);
    char VH, VL;
    int i = 0, j = 0;
    for (i = 0; i < 240; i++)
    {
      for (j = 0; j < 320; j++)
      {
        VH = SPI.transfer(0x00);;
        VL = SPI.transfer(0x00);;
        Serial1.write(VL);
        delayMicroseconds(12);
        Serial1.write(VH);
        delayMicroseconds(12);
      }
    }
    Serial1.write(0xBB);
    Serial1.write(0xCC);
    myCAM.CS_HIGH();
    //Clear the capture done flag
    myCAM.clear_fifo_flag();
  }
}
}
uint8_t read_fifo_burst(ArduCAM myCAM)
{
  uint8_t temp = 0, temp_last = 0;
  uint32_t length = 0;
  length = myCAM.read_fifo_length();
  Serial1.println(length, DEC);
  if (length >= MAX_FIFO_SIZE) //512 kb
  {
    Serial1.println(F("ACK CMD Over size. END"));
    return 0;
  }
  if (length == 0 ) //0 kb
  {
    Serial1.println(F("ACK CMD Size is 0. END"));
    return 0;
  }
  myCAM.CS_LOW();
  myCAM.set_fifo_burst();//Set fifo burst mode
  temp =  SPI.transfer(0x00);
  length --;
  while ( length-- )
  {
    temp_last = temp;
    temp =  SPI.transfer(0x00);
    if (is_header == true)
    {
      Serial1.write(temp);
    }
    else if ((temp == 0xD8) & (temp_last == 0xFF))
    {
      is_header = true;
      Serial1.println(F("ACK IMG END"));
      Serial1.write(temp_last);
      Serial1.write(temp);
    }
    if ( (temp == 0xD9) && (temp_last == 0xFF) ) //If find the end ,break while,
    break;
    delayMicroseconds(15);
  }
  myCAM.CS_HIGH();
  is_header = false;
  return 1;
}

The code I currently have to move the servos is very basic :

#include <Servo.h>

Servo x,y;
const byte servoPin = 11;

void setup()
{
    x.attach(servoPin);
    y.attach(5);
    Serial.begin(9600);
    Serial1.begin(9600);
    x.write(0);
    y.write(0);
}

void loop()
{
    if (Serial1.available())  //if bluetooth module is transmitting data
    {
        int pos = Serial1.parseInt();
        Serial.println(pos);
        if (pos == 45)
          {
            x.write(45);
            delay(500);
            y.write(45);
            delay(500);
            x.write(0);
            delay(500);
            y.write(0);

          }       

    }
}

I imagine not all the arducam code is necessary, however I'm having a hard time understand every function and what can be erased. The Arducam code seem so big which makes it complicated for me to understand how to make both codes work together so that I can make my servos move and snap pictures.

Any help is appreciated !

You will have to specify the exact type of camera that you are using.

Your servo controlling code uses the same serial connection as the camera.
This means you have to add your servo-controlling code to the receive camera-commands code.

The demo-code you posted has these properties:

  • almost no empty lines to visually structure the code
  • uses hardcoded numbers instead of self-explainining names.

Some time ago I was critisized for "bashing" on code.

Well I call it judging, evaluating

This code is a poor code for the the properties like described above.
The opposite of the description would make it easier to understand what the code does.
In this sense this is a poorly written code. Bash on me for this "bashing" or not I don't care.

Here is a code-version that is modified to have empty lines to at least visually structure the code to make it somewhat easier to understand which part does what.

Determining what hardcoded number in the switch-case-statement requieres quite some effort. Which I haven't taken.

Some hints are in the comments at the beginning of the sketch

// ArduCAM Mini demo (C)2018 Lee
// Web: http://www.ArduCAM.com
// This program is a demo of how to use most of the functions
// of the library with ArduCAM Mini camera, and can run on any Arduino platform.
// This demo was made for ArduCAM_Mini_2MP.
// It needs to be used in combination with PC software.
//It supports Bluetooth module
// It can take photo continuously as video streaming.
//
// The demo sketch will do the following tasks:
// 1. Set the camera to JPEG output mode.
// 2. Read data from Serial1 port and deal with it
// 3. If receive 0x00-0x08,the resolution will be changed.
// 4. If receive 0x10,camera will capture a JPEG photo and buffer the image to FIFO.Then write datas to Serial1 port.
// 5. If receive 0x20,camera will capture JPEG photo and write datas continuously.Stop when receive 0x21.
// 6. If receive 0x30,camera will capture a BMP  photo and buffer the image to FIFO.Then write datas to Serial1 port.
// 7. If receive 0x11 ,set camera to JPEG output mode.
// 8. If receive 0x31 ,set camera to BMP  output mode.
// This program requires the ArduCAM V4.0.0 (or later) library and ArduCAM_Mini_2MP
// and use Arduino IDE 1.6.8 compiler or above
#include <Wire.h>
#include <ArduCAM.h>
#include <SPI.h>
#include "memorysaver.h"
#include <SoftwareSerial.h>



//This demo can only work on OV2640_MINI_2MP or OV5642_MINI_5MP or OV5642_MINI_5MP_BIT_ROTATION_FIXED platform.
#if !(defined OV5642_MINI_5MP || defined OV5642_MINI_5MP_BIT_ROTATION_FIXED || defined OV2640_MINI_2MP || defined OV3640_MINI_3MP)
#error Please select the hardware platform and camera module in the ../libraries/ArduCAM/memorysaver.h file
#endif
#define BMPIMAGEOFFSET 66
const char bmp_header[BMPIMAGEOFFSET] PROGMEM =
{
  0x42, 0x4D, 0x36, 0x58, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00, 0x28, 0x00,
  0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x01, 0x00, 0x10, 0x00, 0x03, 0x00,
  0x00, 0x00, 0x00, 0x58, 0x02, 0x00, 0xC4, 0x0E, 0x00, 0x00, 0xC4, 0x0E, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x00, 0xE0, 0x07, 0x00, 0x00, 0x1F, 0x00,
  0x00, 0x00
};

// set pin 7 as the slave select for the digital pot:
const int CS = 7  ;
bool is_header = false;
int mode = 0;
uint8_t start_capture = 0;

#if defined (OV2640_MINI_2MP)
ArduCAM myCAM( OV2640, CS );
#elif defined (OV3640_MINI_3MP)
ArduCAM myCAM( OV3640, CS );
#else
ArduCAM myCAM( OV5642, CS );
#endif

uint8_t read_fifo_burst(ArduCAM myCAM);


void setup() {
  // put your setup code here, to run once:
  uint8_t vid, pid;
  uint8_t temp;
  
#if defined(__SAM3X8E__)
  Wire1.begin();
  Serial1.begin(9600));
#else
  Wire.begin();
  Serial1.begin(9600);
#endif

  Serial1.println(F("ACK CMD ArduCAM Start! END"));
  // set the CS as an output:
  pinMode(CS, OUTPUT);
  digitalWrite(CS, HIGH);
  // initialize SPI:
  //SPI.setClockDivider(SPI_CLOCK_DIV64);
  SPI.begin();

  //Reset the CPLD
  myCAM.write_reg(0x07, 0x80);
  delay(100);
  myCAM.write_reg(0x07, 0x00);
  delay(100);

  while (1) {
  //Check if the ArduCAM SPI bus is OK
  myCAM.write_reg(ARDUCHIP_TEST1, 0x55);
    temp = myCAM.read_reg(ARDUCHIP_TEST1);

    if (temp != 0x55) {
      Serial1.println(F("ACK CMD SPI interface Error! END"));
      delay(1000); continue;
    } else {
      Serial1.println(F("ACK CMD SPI interface OK. END")); break;
    }
  }

#if defined (OV2640_MINI_2MP)
  while (1) {
  //Check if the camera module type is OV2640
  myCAM.wrSensorReg8_8(0xff, 0x01);
    myCAM.rdSensorReg8_8(OV2640_CHIPID_HIGH, &vid);
    myCAM.rdSensorReg8_8(OV2640_CHIPID_LOW, &pid);
    if ((vid != 0x26 ) && (( pid != 0x41 ) || ( pid != 0x42 ))) {
      Serial1.println(F("ACK CMD Can't find OV2640 module! END"));
      delay(1000); continue;
    }
    else {
      Serial1.println(F("ACK CMD OV2640 detected. END")); break;
    }
  }

#elif defined (OV3640_MINI_3MP)
  while (1) {
  //Check if the camera module type is OV3640
  myCAM.rdSensorReg16_8(OV3640_CHIPID_HIGH, &vid);
    myCAM.rdSensorReg16_8(OV3640_CHIPID_LOW, &pid);
    if ((vid != 0x36) || (pid != 0x4C)) {
      Serial1.println(F("ACK CMD Can't find OV3640 module! END"));
      delay(1000); continue;
    } else {
      Serial1.println(F("ACK CMD OV3640 detected. END")); break;
    }
  }

#else
  while (1) {
  //Check if the camera module type is OV5642
  myCAM.wrSensorReg16_8(0xff, 0x01);
    myCAM.rdSensorReg16_8(OV5642_CHIPID_HIGH, &vid);
    myCAM.rdSensorReg16_8(OV5642_CHIPID_LOW, &pid);
    if ((vid != 0x56) || (pid != 0x42)) {
      Serial1.println(F("ACK CMD Can't find OV5642 module! END"));
      delay(1000); continue;
    }
    else {
      Serial1.println(F("ACK CMD OV5642 detected. END")); break;
    }
  }
#endif

  //Change to JPEG capture mode and initialize the OV5642 module
  myCAM.set_format(JPEG);
  myCAM.InitCAM();
#if defined (OV2640_MINI_2MP)
  myCAM.OV2640_set_JPEG_size(OV2640_320x240);
#elif defined (OV3640_MINI_3MP)
  myCAM.OV3640_set_JPEG_size(OV3640_320x240);
#else
  myCAM.write_reg(ARDUCHIP_TIM, VSYNC_LEVEL_MASK);   //VSYNC is active HIGH
  myCAM.OV5642_set_JPEG_size(OV5642_320x240);
#endif

  delay(1000);
  myCAM.clear_fifo_flag();
#if !(defined (OV2640_MINI_2MP))
  myCAM.write_reg(ARDUCHIP_FRAMES, 0x00);
#endif
}


void loop() {
  // put your main code here, to run repeatedly:
  uint8_t temp = 0xff, temp_last = 0;
  bool is_header = false;

  if (Serial1.available()) {
    temp = Serial1.read();
    switch (temp) {
      case 0:
#if defined (OV2640_MINI_2MP)
        myCAM.OV2640_set_JPEG_size(OV2640_160x120); delay(1000);
        Serial1.println(F("ACK CMD switch to OV2640_160x120 END"));
#elif defined (OV3640_MINI_3MP)
        myCAM.OV3640_set_JPEG_size(OV3640_176x144); delay(1000);
        Serial1.println(F("ACK CMD switch to OV2640_160x120 END"));
#else
        myCAM.OV5642_set_JPEG_size(OV5642_320x240); delay(1000);
        Serial1.println(F("ACK CMD switch to OV5642_320x240 END"));
#endif
        temp = 0xff;
        break;

      case 1:
#if defined (OV2640_MINI_2MP)
        myCAM.OV2640_set_JPEG_size(OV2640_176x144); delay(1000);
        Serial1.println(F("ACK CMD switch to OV2640_176x144 END"));
#elif defined (OV3640_MINI_3MP)
        myCAM.OV3640_set_JPEG_size(OV3640_320x240); delay(1000);
        Serial1.println(F("ACK CMD switch to OV3640_320x240 END"));
#else
        myCAM.OV5642_set_JPEG_size(OV5642_640x480); delay(1000);
        Serial1.println(F("ACK CMD switch to OV5642_640x480 END"));
#endif
        temp = 0xff;
        break;

      case 2:
#if defined (OV2640_MINI_2MP)
        myCAM.OV2640_set_JPEG_size(OV2640_320x240); delay(1000);
        Serial1.println(F("ACK CMD switch to OV2640_320x240 END"));
#elif defined (OV3640_MINI_3MP)
        myCAM.OV3640_set_JPEG_size(OV3640_352x288); delay(1000);
        Serial1.println(F("ACK CMD switch to OV3640_352x288 END"));
#else
        myCAM.OV5642_set_JPEG_size(OV5642_1024x768); delay(1000);
        Serial1.println(F("ACK CMD switch to OV5642_1024x768 END"));
#endif
        temp = 0xff;
        break;

      case 3:
        temp = 0xff;
#if defined (OV2640_MINI_2MP)
        myCAM.OV2640_set_JPEG_size(OV2640_352x288); delay(1000);
        Serial1.println(F("ACK CMD switch to OV2640_352x288 END"));
#elif defined (OV3640_MINI_3MP)
        myCAM.OV3640_set_JPEG_size(OV3640_640x480); delay(1000);
        Serial1.println(F("ACK CMD switch to OV3640_640x480 END"));
#else
        myCAM.OV5642_set_JPEG_size(OV5642_1280x960); delay(1000);
        Serial1.println(F("ACK CMD switch to OV5642_1280x960 END"));
#endif
        break;

      case 4:
        temp = 0xff;
#if defined (OV2640_MINI_2MP)
        myCAM.OV2640_set_JPEG_size(OV2640_640x480); delay(1000);
        Serial1.println(F("ACK CMD switch to OV2640_640x480 END"));
#elif defined (OV3640_MINI_3MP)
        myCAM.OV3640_set_JPEG_size(OV3640_800x600); delay(1000);
        Serial1.println(F("ACK CMD switch to OV3640_800x600 END"));
#else
        myCAM.OV5642_set_JPEG_size(OV5642_1600x1200); delay(1000);
        Serial1.println(F("ACK CMD switch to OV5642_1600x1200 END"));
#endif
        break;

      case 5:
        temp = 0xff;
#if defined (OV2640_MINI_2MP)
        myCAM.OV2640_set_JPEG_size(OV2640_800x600); delay(1000);
        Serial1.println(F("ACK CMD switch to OV2640_800x600 END"));
#elif defined (OV3640_MINI_3MP)
        myCAM.OV3640_set_JPEG_size(OV3640_1024x768); delay(1000);
        Serial1.println(F("ACK CMD switch to OV3640_1024x768 END"));
#else
        myCAM.OV5642_set_JPEG_size(OV5642_2048x1536); delay(1000);
        Serial1.println(F("ACK CMD switch to OV5642_2048x1536 END"));
#endif
        break;

      case 6:
        temp = 0xff;
#if defined (OV2640_MINI_2MP)
        myCAM.OV2640_set_JPEG_size(OV2640_1024x768); delay(1000);
        Serial1.println(F("ACK CMD switch to OV2640_1024x768 END"));
#elif defined (OV3640_MINI_3MP)
        myCAM.OV3640_set_JPEG_size(OV3640_1280x960); delay(1000);
        Serial1.println(F("ACK CMD switch to OV3640_1280x960 END"));
#else
        myCAM.OV5642_set_JPEG_size(OV5642_2592x1944); delay(1000);
        Serial1.println(F("ACK CMD switch to OV5642_2592x1944 END"));
#endif
        break;

      case 7:
        temp = 0xff;
#if defined (OV2640_MINI_2MP)
        myCAM.OV2640_set_JPEG_size(OV2640_1280x1024); delay(1000);
        Serial1.println(F("ACK CMD switch to OV2640_1280x1024 END"));
#else
        myCAM.OV3640_set_JPEG_size(OV3640_1600x1200); delay(1000);
        Serial1.println(F("ACK CMD switch to OV3640_1600x1200 END"));
#endif
        break;

      case 8:
        temp = 0xff;
#if defined (OV2640_MINI_2MP)
        myCAM.OV2640_set_JPEG_size(OV2640_1600x1200); delay(1000);
        Serial1.println(F("ACK CMD switch to OV2640_1600x1200 END"));
#else
        myCAM.OV3640_set_JPEG_size(OV3640_2048x1536); delay(1000);
        Serial1.println(F("ACK CMD switch to OV3640_2048x1536 END"));
#endif
        break;

      case 0x10:
        mode = 1;
        temp = 0xff;
        start_capture = 1;
        Serial1.println(F("ACK CMD CAM start single shoot. END"));
        break;

      case 0x11:
        temp = 0xff;
        myCAM.set_format(JPEG);
        myCAM.InitCAM();
#if !(defined (OV2640_MINI_2MP))
        myCAM.set_bit(ARDUCHIP_TIM, VSYNC_LEVEL_MASK);
#endif
        break;

      case 0x20:
        mode = 2;
        temp = 0xff;
        start_capture = 2;
        Serial1.println(F("ACK CMD CAM start video streaming. END"));
        break;

      case 0x30:
        mode = 3;
        temp = 0xff;
        start_capture = 3;
        Serial1.println(F("ACK CMD CAM start single shoot. END"));
        break;

      case 0x31:
        temp = 0xff;
        myCAM.set_format(BMP);
        myCAM.InitCAM();
#if !(defined (OV2640_MINI_2MP))
        myCAM.clear_bit(ARDUCHIP_TIM, VSYNC_LEVEL_MASK);
#endif
        myCAM.wrSensorReg16_8(0x3818, 0x81);
        myCAM.wrSensorReg16_8(0x3621, 0xA7);
        break;
      default:
        break;
    }
  }

  if (mode == 1) {
    if (start_capture == 1) {
      myCAM.flush_fifo();
      myCAM.clear_fifo_flag();
      //Start capture
      myCAM.start_capture();
      start_capture = 0;
    }
    
    if (myCAM.get_bit(ARDUCHIP_TRIG, CAP_DONE_MASK)) {
      Serial1.println(F("ACK CMD CAM Capture Done. END"));
      delay(50);
      read_fifo_burst(myCAM);
      //Clear the capture done flag
      myCAM.clear_fifo_flag();
    }
  }
  else if (mode == 2) {
    while (1) {
      temp = Serial1.read();
      if (temp == 0x21) {
        start_capture = 0;
        mode = 0;
        Serial1.println(F("ACK CMD CAM stop video streaming. END"));
        break;
      }
      
      if (start_capture == 2) {
        myCAM.flush_fifo();
        myCAM.clear_fifo_flag();
        //Start capture
        myCAM.start_capture();
        start_capture = 0;
      }
      
      if (myCAM.get_bit(ARDUCHIP_TRIG, CAP_DONE_MASK)) {
        uint32_t length = 0;
        length = myCAM.read_fifo_length();
        if ((length >= MAX_FIFO_SIZE) | (length == 0)) {
          myCAM.clear_fifo_flag();
          start_capture = 2;
          continue;
        }
        myCAM.CS_LOW();
        myCAM.set_fifo_burst();//Set fifo burst mode
        temp =  SPI.transfer(0x00);
        length --;
        
        while ( length-- ) {
          temp_last = temp;
          temp =  SPI.transfer(0x00);
          
          if (is_header == true) {
            Serial1.write(temp);
          }
          else if ((temp == 0xD8) & (temp_last == 0xFF)) {
            is_header = true;
            Serial1.println(F("ACK IMG END"));
            Serial1.write(temp_last);
            Serial1.write(temp);
          }
          
          if ( (temp == 0xD9) && (temp_last == 0xFF) ) //If find the end ,break while,
            break;
          delayMicroseconds(15);
        }
        
        myCAM.CS_HIGH();
        myCAM.clear_fifo_flag();
        start_capture = 2;
        is_header = false;
      }
    }
  }
  else if (mode == 3) {
    if (start_capture == 3)
    {
      //Flush the FIFO
      myCAM.flush_fifo();
      myCAM.clear_fifo_flag();
      //Start capture
      myCAM.start_capture();
      start_capture = 0;
    }
    
    if (myCAM.get_bit(ARDUCHIP_TRIG, CAP_DONE_MASK)) {
      Serial1.println(F("ACK CMD CAM Capture Done. END"));
      delay(50);
      uint8_t temp, temp_last;
      uint32_t length = 0;
      length = myCAM.read_fifo_length();
      
      if (length >= MAX_FIFO_SIZE ) {
        Serial1.println(F("ACK CMD Over size. END"));
        myCAM.clear_fifo_flag();
        return;
      }
      
      if (length == 0 ) //0 kb {
        Serial1.println(F("ACK CMD Size is 0. END"));
        myCAM.clear_fifo_flag();
        return;
      }
      
      myCAM.CS_LOW();
      myCAM.set_fifo_burst();//Set fifo burst mode

      Serial1.write(0xFF);
      Serial1.write(0xAA);
      for (temp = 0; temp < BMPIMAGEOFFSET; temp++) {
        Serial1.write(pgm_read_byte(&bmp_header[temp]));
      }
      SPI.transfer(0x00);
      char VH, VL;
      int i = 0, j = 0;
      
      for (i = 0; i < 240; i++) {
        for (j = 0; j < 320; j++) {
          VH = SPI.transfer(0x00);;
          VL = SPI.transfer(0x00);;
          Serial1.write(VL);
          delayMicroseconds(12);
          Serial1.write(VH);
          delayMicroseconds(12);
        }
      }
      
      Serial1.write(0xBB);
      Serial1.write(0xCC);
      myCAM.CS_HIGH();
      //Clear the capture done flag
      myCAM.clear_fifo_flag();
    }
  }
}

uint8_t read_fifo_burst(ArduCAM myCAM) {
  uint8_t temp = 0, temp_last = 0;
  uint32_t length = 0;
  length = myCAM.read_fifo_length();
  Serial1.println(length, DEC);
  if (length >= MAX_FIFO_SIZE) //512 kb
  {
    Serial1.println(F("ACK CMD Over size. END"));
    return 0;
  }
  
  if (length == 0 ) //0 kb
  {
    Serial1.println(F("ACK CMD Size is 0. END"));
    return 0;
  }
  
  myCAM.CS_LOW();
  myCAM.set_fifo_burst();//Set fifo burst mode
  temp =  SPI.transfer(0x00);
  length --;
  while ( length-- ) {
    temp_last = temp;
    temp =  SPI.transfer(0x00);
    if (is_header == true) {
      Serial1.write(temp);
    }
    else if ((temp == 0xD8) & (temp_last == 0xFF)) {
      is_header = true;
      Serial1.println(F("ACK IMG END"));
      Serial1.write(temp_last);
      Serial1.write(temp);
    }
    
    if ( (temp == 0xD9) && (temp_last == 0xFF) ) //If find the end ,break while,
      break;
    
    delayMicroseconds(15);
  }
  
  myCAM.CS_HIGH();
  is_header = false;
  return 1;
}

I agree, the code is quite hard to read, and I've had a hard time understanding it.

I am using an ArduCAM B0067 OV2640 2MP.

I've thought about this overnight, and I think I might not be doing the right thing.
What I've basically done is made the arducam work with the sketch provided in the library, allowing me to use the Arducam App to take pictures and videos. I thought I could just use this code and make it work with my servos.

But I think I'm doing wrong,
What I want to do is to be able to move my robot freely and when I "click a button" the arducam snaps a picture and sends it to my pc via bluetooth.

i need a better understanding of the arducam library, however I am having a hard time finding similar projects.

If you have any knowledge about it I appreciate any help, I am a complete beginner in eletronics

The more important thing is:
What is your knowledge level about programming in general
and
writing code in C++ in special

I don't have knowledge about ArduCam. I have knowledge how to retrieve knowledge in general.

The most important thing is providing enough information.
The difference between a consumer-product and building DIY-projects is

for a consumer-product it is sufficient to check

"does the plug fit into the socket?"

For a DIY-project you need a lot of detail-information

It might well be that you do not yet even know what kind of information and where to get this information from.

You should google with keywords

Arduino "your-exact type of microcontroller" ArduCam

Does the ArduCam website have its own user-forum?

If you want support that really helps you will have to describe your project with much more precision.

  • What is this ArduCam App? Post a link to it
  • on what device is this App running? On a smartphone? on a tablet? on your computer?
  • what exact type of microcontroller are you using?

post links to the description and user-manual of

  • the ardu-cam sketch
  • the ardu-camera that you are using

What is your knowledge level about programming in general

I've coded in C and hated it, never coded in C++ (I'm confortable in Python and C# but I guess that's irrelevant)

  • What is this ArduCam App? Post a link to it
  • on what device is this App running? On a smartphone? on a tablet? on your computer?
  • what exact type of microcontroller are you using?

-The arducam app is inside the Arducam library : Arduino/ArduCAM/examples/host_app at master · ArduCAM/Arduino · GitHub
and looks like this :

-It is running on my computer
-My complete setup is : Arduino Mega + HC05 + ArduCAM B0067 OV2640 2MP + Servos FS90 (+ micro-SD DFR0229 but I've not used it yet)

post links to the description and user-manual of

  • the ardu-cam sketch
  • the ardu-camera that you are using

-GitHub - ArduCAM/Arduino: This is ArduCAM library for Arduino boards
-The arducam sketch I am using is there :
Arduino/ArduCAM/examples/mini/ArduCAM_Mini_Video_Streaming_Bluetooth/ArduCAM_Mini_Video_Streaming_Bluetooth.ino at master · ArduCAM/Arduino · GitHub

I am now wondering if maybe I should this sketch instead :

As it would allow me to snap picture and send it to the SD card, I would then have to find a way to send the picture to my computer from the SD Card through Bluetooth.

My main issue with the code I currently use is it looks like I have to disconnect the HC05 from my computer to then connect it with the Arducam app in order to snap pictures. So it looks like im not going in the good direction

What I want to be able to do is use my computer as an instruction sender to move my servos and snap pictures. The picture would then be sent to my computer. The goal is to be able to control my robot in first view by taking picture of what's in front of it.

The main issue however is that I can't make sense of the code, and how to structure it. I've managed to make the servos work inside the Arducam code. But the snapping pictures part won't work now. I've done it by adding the servo-controlling code to the receive camera-commands code as you said earlier. Here's the code (the only changes are at the beginning of the loop)

// ArduCAM Mini demo (C)2018 Lee
// Web: http://www.ArduCAM.com
// This program is a demo of how to use most of the functions
// of the library with ArduCAM Mini camera, and can run on any Arduino platform.
// This demo was made for ArduCAM_Mini_2MP.
// It needs to be used in combination with PC software.
//It supports Bluetooth module
// It can take photo continuously as video streaming.
//
// The demo sketch will do the following tasks:
// 1. Set the camera to JPEG output mode.
// 2. Read data from Serial1 port and deal with it
// 3. If receive 0x00-0x08,the resolution will be changed.
// 4. If receive 0x10,camera will capture a JPEG photo and buffer the image to FIFO.Then write datas to Serial1 port.
// 5. If receive 0x20,camera will capture JPEG photo and write datas continuously.Stop when receive 0x21.
// 6. If receive 0x30,camera will capture a BMP  photo and buffer the image to FIFO.Then write datas to Serial1 port.
// 7. If receive 0x11 ,set camera to JPEG output mode.
// 8. If receive 0x31 ,set camera to BMP  output mode.
// This program requires the ArduCAM V4.0.0 (or later) library and ArduCAM_Mini_2MP
// and use Arduino IDE 1.6.8 compiler or above
#include <Wire.h>
#include <ArduCAM.h>
#include <SPI.h>
#include "memorysaver.h"
#include <SoftwareSerial.h>



//This demo can only work on OV2640_MINI_2MP or OV5642_MINI_5MP or OV5642_MINI_5MP_BIT_ROTATION_FIXED platform.
#if !(defined OV5642_MINI_5MP || defined OV5642_MINI_5MP_BIT_ROTATION_FIXED || defined OV2640_MINI_2MP || defined OV3640_MINI_3MP)
  #error Please select the hardware platform and camera module in the ../libraries/ArduCAM/memorysaver.h file
#endif
#define BMPIMAGEOFFSET 66
const char bmp_header[BMPIMAGEOFFSET] PROGMEM =
{
  0x42, 0x4D, 0x36, 0x58, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00, 0x28, 0x00,
  0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x01, 0x00, 0x10, 0x00, 0x03, 0x00,
  0x00, 0x00, 0x00, 0x58, 0x02, 0x00, 0xC4, 0x0E, 0x00, 0x00, 0xC4, 0x0E, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x00, 0xE0, 0x07, 0x00, 0x00, 0x1F, 0x00,
  0x00, 0x00
};
// set pin 7 as the slave select for the digital pot:
const int CS = 7  ;
bool is_header = false;
int mode = 0;
uint8_t start_capture = 0;
#if defined (OV2640_MINI_2MP)
  ArduCAM myCAM( OV2640, CS );
#elif defined (OV3640_MINI_3MP)
ArduCAM myCAM( OV3640, CS );
#else
  ArduCAM myCAM( OV5642, CS );
#endifded
uint8_t read_fifo_burst(ArduCAM myCAM);
void setup() {
// put your setup code here, to run once:
uint8_t vid, pid;
uint8_t temp;
#if defined(__SAM3X8E__)
  Wire1.begin();
  Serial1.begin(9600));
#else
  Wire.begin();
  Serial1.begin(9600);
#endif
Serial1.println(F("ACK CMD ArduCAM Start! END"));
// set the CS as an output:
pinMode(CS, OUTPUT);
digitalWrite(CS, HIGH);
// initialize SPI:
//SPI.setClockDivider(SPI_CLOCK_DIV64);
SPI.begin();

//Reset the CPLD
myCAM.write_reg(0x07, 0x80);
delay(100);
myCAM.write_reg(0x07, 0x00);
delay(100);
while(1){
  //Check if the ArduCAM SPI bus is OK
  myCAM.write_reg(ARDUCHIP_TEST1, 0x55);
  temp = myCAM.read_reg(ARDUCHIP_TEST1);
  if (temp != 0x55){
    Serial1.println(F("ACK CMD SPI interface Error! END"));
    delay(1000);continue;
  }else{
    Serial1.println(F("ACK CMD SPI interface OK. END"));break;
  }
}

#if defined (OV2640_MINI_2MP)
  while(1){
    //Check if the camera module type is OV2640
    myCAM.wrSensorReg8_8(0xff, 0x01);
    myCAM.rdSensorReg8_8(OV2640_CHIPID_HIGH, &vid);
    myCAM.rdSensorReg8_8(OV2640_CHIPID_LOW, &pid);
    if ((vid != 0x26 ) && (( pid != 0x41 ) || ( pid != 0x42 ))){
      Serial1.println(F("ACK CMD Can't find OV2640 module! END"));
      delay(1000);continue;
    }
    else{
      Serial1.println(F("ACK CMD OV2640 detected. END"));break;
    } 
  }
#elif defined (OV3640_MINI_3MP)
  while(1){
    //Check if the camera module type is OV3640
    myCAM.rdSensorReg16_8(OV3640_CHIPID_HIGH, &vid);
    myCAM.rdSensorReg16_8(OV3640_CHIPID_LOW, &pid);
    if ((vid != 0x36) || (pid != 0x4C)){
      Serial1.println(F("ACK CMD Can't find OV3640 module! END"));
      delay(1000);continue; 
    }else{
      Serial1.println(F("ACK CMD OV3640 detected. END"));break;    
    }
 } 
  
#else
  while(1){
    //Check if the camera module type is OV5642
    myCAM.wrSensorReg16_8(0xff, 0x01);
    myCAM.rdSensorReg16_8(OV5642_CHIPID_HIGH, &vid);
    myCAM.rdSensorReg16_8(OV5642_CHIPID_LOW, &pid);
    if((vid != 0x56) || (pid != 0x42)){
      Serial1.println(F("ACK CMD Can't find OV5642 module! END"));
      delay(1000);continue;
    }
    else{
      Serial1.println(F("ACK CMD OV5642 detected. END"));break;
    } 
  }
#endif
//Change to JPEG capture mode and initialize the OV5642 module
myCAM.set_format(JPEG);
myCAM.InitCAM();
#if defined (OV2640_MINI_2MP)
  myCAM.OV2640_set_JPEG_size(OV2640_320x240);
#elif defined (OV3640_MINI_3MP)
  myCAM.OV3640_set_JPEG_size(OV3640_320x240);
#else
  myCAM.write_reg(ARDUCHIP_TIM, VSYNC_LEVEL_MASK);   //VSYNC is active HIGH
  myCAM.OV5642_set_JPEG_size(OV5642_320x240);
#endif
delay(1000);
myCAM.clear_fifo_flag();
#if !(defined (OV2640_MINI_2MP))
myCAM.write_reg(ARDUCHIP_FRAMES,0x00);
#endif
}
void loop() {
// put your main code here, to run repeatedly:
uint8_t temp = 0xff, temp_last = 0;
bool is_header = false;
if (Serial1.available())
{
  temp = Serial1.read();
  switch (temp)
  {
    case 0:
    #if defined (OV2640_MINI_2MP)
      myCAM.OV2640_set_JPEG_size(OV2640_160x120);delay(1000);
      Serial1.println(F("ACK CMD switch to OV2640_160x120 END"));
    #elif defined (OV3640_MINI_3MP)
      myCAM.OV3640_set_JPEG_size(OV3640_176x144);delay(1000);
      Serial1.println(F("ACK CMD switch to OV2640_160x120 END"));
    #else
      myCAM.OV5642_set_JPEG_size(OV5642_320x240);delay(1000);
      Serial1.println(F("ACK CMD switch to OV5642_320x240 END"));
    #endif
    temp = 0xff;
    break;
    case 1:
    #if defined (OV2640_MINI_2MP)
      myCAM.OV2640_set_JPEG_size(OV2640_176x144);delay(1000);
      Serial1.println(F("ACK CMD switch to OV2640_176x144 END"));
    #elif defined (OV3640_MINI_3MP)
      myCAM.OV3640_set_JPEG_size(OV3640_320x240);delay(1000);
      Serial1.println(F("ACK CMD switch to OV3640_320x240 END"));
    #else
      myCAM.OV5642_set_JPEG_size(OV5642_640x480);delay(1000);
      Serial1.println(F("ACK CMD switch to OV5642_640x480 END"));
    #endif
    temp = 0xff;
    break;
    case 2: 
    #if defined (OV2640_MINI_2MP)
      myCAM.OV2640_set_JPEG_size(OV2640_320x240);delay(1000);
      Serial1.println(F("ACK CMD switch to OV2640_320x240 END"));
     #elif defined (OV3640_MINI_3MP)
      myCAM.OV3640_set_JPEG_size(OV3640_352x288);delay(1000);
      Serial1.println(F("ACK CMD switch to OV3640_352x288 END"));
    #else
      myCAM.OV5642_set_JPEG_size(OV5642_1024x768);delay(1000);
      Serial1.println(F("ACK CMD switch to OV5642_1024x768 END"));
    #endif
    temp = 0xff;
    break;
    case 3:
    temp = 0xff;
    #if defined (OV2640_MINI_2MP)
      myCAM.OV2640_set_JPEG_size(OV2640_352x288);delay(1000);
      Serial1.println(F("ACK CMD switch to OV2640_352x288 END"));
    #elif defined (OV3640_MINI_3MP)
      myCAM.OV3640_set_JPEG_size(OV3640_640x480);delay(1000);
      Serial1.println(F("ACK CMD switch to OV3640_640x480 END"));
    #else
      myCAM.OV5642_set_JPEG_size(OV5642_1280x960);delay(1000);
      Serial1.println(F("ACK CMD switch to OV5642_1280x960 END"));
    #endif
    break;
    case 4:
    temp = 0xff;
    #if defined (OV2640_MINI_2MP)
      myCAM.OV2640_set_JPEG_size(OV2640_640x480);delay(1000);
      Serial1.println(F("ACK CMD switch to OV2640_640x480 END"));
   #elif defined (OV3640_MINI_3MP)
      myCAM.OV3640_set_JPEG_size(OV3640_800x600);delay(1000);
      Serial1.println(F("ACK CMD switch to OV3640_800x600 END"));
    #else
      myCAM.OV5642_set_JPEG_size(OV5642_1600x1200);delay(1000);
      Serial1.println(F("ACK CMD switch to OV5642_1600x1200 END"));
    #endif
    break;
    case 5:
    temp = 0xff;
    #if defined (OV2640_MINI_2MP)
      myCAM.OV2640_set_JPEG_size(OV2640_800x600);delay(1000);
      Serial1.println(F("ACK CMD switch to OV2640_800x600 END"));
    #elif defined (OV3640_MINI_3MP)
      myCAM.OV3640_set_JPEG_size(OV3640_1024x768);delay(1000);
      Serial1.println(F("ACK CMD switch to OV3640_1024x768 END"));
    #else
      myCAM.OV5642_set_JPEG_size(OV5642_2048x1536);delay(1000);
      Serial1.println(F("ACK CMD switch to OV5642_2048x1536 END"));
    #endif
    break;
    case 6:
    temp = 0xff;
    #if defined (OV2640_MINI_2MP)
      myCAM.OV2640_set_JPEG_size(OV2640_1024x768);delay(1000);
      Serial1.println(F("ACK CMD switch to OV2640_1024x768 END"));
   #elif defined (OV3640_MINI_3MP)
      myCAM.OV3640_set_JPEG_size(OV3640_1280x960);delay(1000);
      Serial1.println(F("ACK CMD switch to OV3640_1280x960 END"));
    #else
      myCAM.OV5642_set_JPEG_size(OV5642_2592x1944);delay(1000);
      Serial1.println(F("ACK CMD switch to OV5642_2592x1944 END"));
    #endif
    break;
    case 7:
    temp = 0xff;
   #if defined (OV2640_MINI_2MP)
    myCAM.OV2640_set_JPEG_size(OV2640_1280x1024);delay(1000);
    Serial1.println(F("ACK CMD switch to OV2640_1280x1024 END"));
   #else
      myCAM.OV3640_set_JPEG_size(OV3640_1600x1200);delay(1000);
      Serial1.println(F("ACK CMD switch to OV3640_1600x1200 END"));
   #endif
    break;
    case 8:
    temp = 0xff;
   #if defined (OV2640_MINI_2MP)
     myCAM.OV2640_set_JPEG_size(OV2640_1600x1200);delay(1000);
     Serial1.println(F("ACK CMD switch to OV2640_1600x1200 END"));
   #else
     myCAM.OV3640_set_JPEG_size(OV3640_2048x1536);delay(1000);
     Serial1.println(F("ACK CMD switch to OV3640_2048x1536 END"));
   #endif
    break;
    case 0x10:
    mode = 1;
    temp = 0xff;
    start_capture = 1;
    Serial1.println(F("ACK CMD CAM start single shoot. END"));
    break;
    case 0x11: 
    temp = 0xff;
    myCAM.set_format(JPEG);
    myCAM.InitCAM();
    #if !(defined (OV2640_MINI_2MP))
    myCAM.set_bit(ARDUCHIP_TIM, VSYNC_LEVEL_MASK);
    #endif
    break;
    case 0x20:
    mode = 2;
    temp = 0xff;
    start_capture = 2;
    Serial1.println(F("ACK CMD CAM start video streaming. END"));
    break;
    case 0x30:
    mode = 3;
    temp = 0xff;
    start_capture = 3;
    Serial1.println(F("ACK CMD CAM start single shoot. END"));
    break;
    case 0x31:
    temp = 0xff;
    myCAM.set_format(BMP);
    myCAM.InitCAM();
    #if !(defined (OV2640_MINI_2MP))        
    myCAM.clear_bit(ARDUCHIP_TIM, VSYNC_LEVEL_MASK);
    #endif
    myCAM.wrSensorReg16_8(0x3818, 0x81);
    myCAM.wrSensorReg16_8(0x3621, 0xA7);
    break;
    default:
    break;
  }
}
if (mode == 1)
{
  if (start_capture == 1)
  {
    myCAM.flush_fifo();
    myCAM.clear_fifo_flag();
    //Start capture
    myCAM.start_capture();
    start_capture = 0;
  }
  if (myCAM.get_bit(ARDUCHIP_TRIG, CAP_DONE_MASK))
  {
    Serial1.println(F("ACK CMD CAM Capture Done. END"));
    delay(50);
    read_fifo_burst(myCAM);
    //Clear the capture done flag
    myCAM.clear_fifo_flag();
  }
}
else if (mode == 2)
{
  while (1)
  {
    temp = Serial1.read();
    if (temp == 0x21)
    {
      start_capture = 0;
      mode = 0;
      Serial1.println(F("ACK CMD CAM stop video streaming. END"));
      break;
    }
    if (start_capture == 2)
    {
      myCAM.flush_fifo();
      myCAM.clear_fifo_flag();
      //Start capture
      myCAM.start_capture();
      start_capture = 0;
    }
    if (myCAM.get_bit(ARDUCHIP_TRIG, CAP_DONE_MASK))
    {
      uint32_t length = 0;
      length = myCAM.read_fifo_length();
      if ((length >= MAX_FIFO_SIZE) | (length == 0))
      {
        myCAM.clear_fifo_flag();
        start_capture = 2;
        continue;
      }
      myCAM.CS_LOW();
      myCAM.set_fifo_burst();//Set fifo burst mode
      temp =  SPI.transfer(0x00);
      length --;
      while ( length-- )
      {
        temp_last = temp;
        temp =  SPI.transfer(0x00);
        if (is_header == true)
        {
          Serial1.write(temp);
        }
        else if ((temp == 0xD8) & (temp_last == 0xFF))
        {
          is_header = true;
          Serial1.println(F("ACK IMG END"));
          Serial1.write(temp_last);
          Serial1.write(temp);
        }
        if ( (temp == 0xD9) && (temp_last == 0xFF) ) //If find the end ,break while,
        break;
        delayMicroseconds(15);
      }
      myCAM.CS_HIGH();
      myCAM.clear_fifo_flag();
      start_capture = 2;
      is_header = false;
    }
  }
}
else if (mode == 3)
{
  if (start_capture == 3)
  {
    //Flush the FIFO
    myCAM.flush_fifo();
    myCAM.clear_fifo_flag();
    //Start capture
    myCAM.start_capture();
    start_capture = 0;
  }
  if (myCAM.get_bit(ARDUCHIP_TRIG, CAP_DONE_MASK))
  {
    Serial1.println(F("ACK CMD CAM Capture Done. END"));
    delay(50);
    uint8_t temp, temp_last;
    uint32_t length = 0;
    length = myCAM.read_fifo_length();
    if (length >= MAX_FIFO_SIZE ) 
    {
      Serial1.println(F("ACK CMD Over size. END"));
      myCAM.clear_fifo_flag();
      return;
    }
    if (length == 0 ) //0 kb
    {
      Serial1.println(F("ACK CMD Size is 0. END"));
      myCAM.clear_fifo_flag();
      return;
    }
    myCAM.CS_LOW();
    myCAM.set_fifo_burst();//Set fifo burst mode
    
    Serial1.write(0xFF);
    Serial1.write(0xAA);
    for (temp = 0; temp < BMPIMAGEOFFSET; temp++)
    {
      Serial1.write(pgm_read_byte(&bmp_header[temp]));
    }
    SPI.transfer(0x00);
    char VH, VL;
    int i = 0, j = 0;
    for (i = 0; i < 240; i++)
    {
      for (j = 0; j < 320; j++)
      {
        VH = SPI.transfer(0x00);;
        VL = SPI.transfer(0x00);;
        Serial1.write(VL);
        delayMicroseconds(12);
        Serial1.write(VH);
        delayMicroseconds(12);
      }
    }
    Serial1.write(0xBB);
    Serial1.write(0xCC);
    myCAM.CS_HIGH();
    //Clear the capture done flag
    myCAM.clear_fifo_flag();
  }
}
}
uint8_t read_fifo_burst(ArduCAM myCAM)
{
  uint8_t temp = 0, temp_last = 0;
  uint32_t length = 0;
  length = myCAM.read_fifo_length();
  Serial1.println(length, DEC);
  if (length >= MAX_FIFO_SIZE) //512 kb
  {
    Serial1.println(F("ACK CMD Over size. END"));
    return 0;
  }
  if (length == 0 ) //0 kb
  {
    Serial1.println(F("ACK CMD Size is 0. END"));
    return 0;
  }
  myCAM.CS_LOW();
  myCAM.set_fifo_burst();//Set fifo burst mode
  temp =  SPI.transfer(0x00);
  length --;
  while ( length-- )
  {
    temp_last = temp;
    temp =  SPI.transfer(0x00);
    if (is_header == true)
    {
      Serial1.write(temp);
    }
    else if ((temp == 0xD8) & (temp_last == 0xFF))
    {
      is_header = true;
      Serial1.println(F("ACK IMG END"));
      Serial1.write(temp_last);
      Serial1.write(temp);
    }
    if ( (temp == 0xD9) && (temp_last == 0xFF) ) //If find the end ,break while,
    break;
    delayMicroseconds(15);
  }
  myCAM.CS_HIGH();
  is_header = false;
  return 1;
}

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.