VC0706 Camera module Problem

Hello I bought a VC0706 Camera module and I want to connect it to arduino capture a photo and send it to sd card through sd card module.

I tried the Snapshot example at VC0706 Arduino Library. In console everything seems to work fine, But when i open the photo in my pc either the file is corrupted or it shows grey images with some noise.

I also tried the VC0706 Comm tool and it works fine . The picture is saved successfully in my pc and it is shown correctly.

So the problem is when the image is transfered to my sd card.
I also tried another sd card (32 and 16gb thats what i had in my posession).

I attached the corrupted photos and the console screenshot that sais everything worked fine.

Every help is appreciated… If you need more info tell me please.

I want the code so i can do this operation automatic and not manually.

IMAGE00.JPG

Did you use the Adafruit library?

Did you see the big red warning on this page?

The camera is not the waterproof model. Yes i mean the adafruit library and the snapshot example that is shown in the link you attached before. If anyone want me to share the code here tell me. What do you think is the problem ?

What model Arduino are you using? Which pins do you have the camera connected to?

I am using Arduino uno and the connection is the following

VC0706 -> UNO

gnd -> gnd
5v -> 5v
Rx -> pin 3
Tx -> pin 2

Micro SD module -> UNO

gnd -> gnd
Vcc -> 5v
CS -> pin 10
MOSI -> pin 11
MISO -> pin 12
SCK -> pin 13

The camera module is from eBay.
The default baud rate of the camera is 115200 and the snapshot example was giving me camera not found always and I so a video on YouTube of someone who modified baud rate in the adafruit_vc0706.cpp of the library and I did it as well and then the camera was recognized.

Does the image get corrupted cause it should have been 9600 baud rate ? Does any1 knows how to change the baud rate ?
I found some commands for the camera but don't know what to do .

Should I post this topic in another category ?
Is it just too difficult so nobody can help me ?
I really need support from the community :frowning:

So the "VC0706 Comm" tool works when you have the camera connected to pins 0 and 1 but when you switch to 2 and 3 and use the sketch, all appears fine except the resulting image. I'm fairly sure that the serial data is being sent by the camera and successfully received by the sketch or you would not get the "Storing 58232 byte image... done!" message. My next guess would be that there is some command that the "VC0706 Comm" tool sends to the camera that the sketch doesn't. Maybe the 'contrast' setting defaults to zero? If the library has a way to set the brightness, contrast, saturation, hue... you could try setting them all to the midpoint.

Hello i searched at the adafruit library and found the functions that the sketch is using and the commands that the module needs to read in order to achieve what the comm tool program does .
Here is the snapshot example

#include <Adafruit_VC0706.h>
#include <SPI.h>
#include <SD.h>

// On Uno: camera TX connected to pin 2, camera RX to pin 3:
#include <SoftwareSerial.h>         
SoftwareSerial cameraconnection(2, 3);

Adafruit_VC0706 cam = Adafruit_VC0706(&cameraconnection);

#define chipSelect 10

void setup() {
  #if !defined(SOFTWARE_SPI)
    #if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
      if(chipSelect != 53) pinMode(53, OUTPUT); // SS on Mega
    #else
      if(chipSelect != 10) pinMode(10, OUTPUT); // SS on Uno, etc.
    #endif
  #endif
  delay(10000);
  Serial.begin(9600);
  Serial.println("VC0706 Camera snapshot test");
  
  // see if the card is present and can be initialized:
  if (!SD.begin(chipSelect)) {
    Serial.println("Card failed, or not present");
    // don't do anything more:
    return;
  }
  
  // Try to locate the camera
  if (cam.begin()) {
    Serial.println("Camera Found:");
  } else {
    Serial.println("No camera found?");
    return;
  }
  // Print out the camera version information (optional)
  char *reply = cam.getVersion();
  if (reply == 0) {
    Serial.print("Failed to get version");
  } else {
    Serial.println("-----------------");
    Serial.print(reply);
    Serial.println("-----------------");
  }

  // Set the picture size - you can choose one of 640x480, 320x240 or 160x120 
  // Remember that bigger pictures take longer to transmit!
  
  cam.setImageSize(VC0706_640x480);        // biggest
  //cam.setImageSize(VC0706_320x240);        // medium
  //cam.setImageSize(VC0706_160x120);          // small

  // You can read the size back from the camera (optional, but maybe useful?)
  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");
  Serial.println("Snap in 3 secs...");
  delay(3000);

  if (! cam.takePicture()) 
    Serial.println("Failed to snap!");
  else 
    Serial.println("Picture taken!");
  
  // Create an image with the name IMAGExx.JPG
  char filename[13];
  strcpy(filename, "IMAGE00.JPG");
  for (int i = 0; i < 100; i++) {
    filename[5] = '0' + i/10;
    filename[6] = '0' + i%10;
    // create if does not exist, do not open existing, write, sync after write
    if (! SD.exists(filename)) {
      break;
    }
  }
  
  // Open the file for writing
  File imgFile = SD.open(filename, FILE_WRITE);

  if (!imgFile) {
        Serial.println("Open Failed !");
    }
    else{
        Serial.println("Open done !");
    }
    
  // Get the size of the image (frame) taken  
  uint16_t jpglen = cam.frameLength();
  Serial.print("Storing ");
  Serial.print(jpglen, DEC);
  Serial.print(" byte image.");

  int32_t time = millis();
  pinMode(8, OUTPUT);
  // Read all the data up to # bytes!
  byte wCount = 0; // For counting # of writes
  while (jpglen > 0) {
    // read 32 bytes at a time;
    uint8_t *buffer;
    uint8_t bytesToRead = min((uint16_t)32, jpglen); // change 32 to 64 for a speedup but may not work with all setups!
    buffer = cam.readPicture(bytesToRead);
    //Serial.println(cam.readPicture(bytesToRead));
    imgFile.write(buffer, bytesToRead);
    if(++wCount >= 64) { // Every 2K, give a little feedback so it doesn't appear locked up
      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");
}
void loop() {
}

report.pdf (97.6 KB)

  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");
  Serial.println("Snap in 3 secs...");

The screenshot you posted doesn't show anything between "Image size: " and "Snap in 3 secs..." so the image size you got back from the camera does not match any of the three image sizes the sketch is looking for. Perhaps you should try the other two image sizes to see if either of them read back correctly:

  cam.setImageSize(VC0706_640x480);        // biggest
  //cam.setImageSize(VC0706_320x240);        // medium
  //cam.setImageSize(VC0706_160x120);          // small

Hello thank you for answering.

I tried with all of the 3 image options and none is printed.

Here is the "setImageSize" function in Adafruit_VC0706.h

/**************************************************************************/
/*!
    @brief  Set image size with VC0706_WRITE_DATA
    @param x VC0706_640x480, VC0706_320x240 or VC0706_160x120
    @return True on command success
*/
/**************************************************************************/
boolean Adafruit_VC0706::setImageSize(uint8_t x) {
  uint8_t args[] = {0x05, 0x04, 0x01, 0x00, 0x19, x};

  return runCommand(VC0706_WRITE_DATA, args, sizeof(args), 5);
}
#define VC0706_WRITE_DATA 0x31
#define VC0706_640x480 0x00
#define VC0706_320x240 0x11
#define VC0706_160x120 0x22

So maybe the problem could be that the Image quality isnt configured successfully?
I Haven't modified the library at all by the way.

Edit: From Documents i Found this:
Set photo size command:
56 00 31 05 04 01 00 19 11 (320240)
56 00 31 05 04 01 00 19 00 (640
480)

So the command in the library is right . Have no clue why it isn't printed . I'm not an expert myself.

What value are you getting back from cam.getImageSize();?

I tried with all 3 sizes and the serial.print is always the same value of “255”.
I attached a new console log.

Here is the GetImageSize And SetImageSize functions:

/**************************************************************************/
/*!
    @brief  Get image size with VC0706_READ_DATA
    @return VC0706_640x480, VC0706_320x240 or VC0706_160x120
*/
/**************************************************************************/
uint8_t Adafruit_VC0706::getImageSize() {
  uint8_t args[] = {0x4, 0x4, 0x1, 0x00, 0x19};
  if (!runCommand(VC0706_READ_DATA, args, sizeof(args), 6))
    return -1;

  return camerabuff[5];
}
#define VC0706_READ_DATA 0x30

/**************************************************************************/
/*!
    @brief  Set image size with VC0706_WRITE_DATA
    @param x VC0706_640x480, VC0706_320x240 or VC0706_160x120
    @return True on command success
*/
/**************************************************************************/
boolean Adafruit_VC0706::setImageSize(uint8_t x) {
  uint8_t args[] = {0x05, 0x04, 0x01, 0x00, 0x19, x};

  return runCommand(VC0706_WRITE_DATA, args, sizeof(args), 5);
}
#define VC0706_WRITE_DATA 0x31

Edit: In the log it sais now Image Size 640x480 but its not correct.
Even if i change the image size it still sais 640x480.
I havent changed anything i dont know why it wasnt displayed before.

uint8_t Adafruit_VC0706::getImageSize() {
  uint8_t args[] = {0x4, 0x4, 0x1, 0x00, 0x19};
  if (!runCommand(VC0706_READ_DATA, args, sizeof(args), 6))
    return -1;

  return camerabuff[5];
}

It looks like this returns -1 for the size code when the 'runCommand()' function returns 'false'. Sounds like something is failing with that command. I guess you'll have to debug the library to see why that function is failing.

I found a different code that doesnt use the adafruit library. Maybe it will be easier for you to help me like this. It still doesnt work. It creates a file is sd but it is corrupted.

here is the code . Tell me your opinion about on what code i should continue with. this one or the adafruit snapshot example.

//  File SerialCamera.pde for camera.
//  25/7/2011 by Piggy
//  Modify by Deray  08/08/2012 
//  Demo code for using seeeduino or Arduino board to cature jpg format 
//  picture from seeed serial camera and save it into sd card. Push the 
//  button to take the a picture .
 
//  For more details about the product please check http://www.seeedstudio.com/depot/

#include <SPI.h>
#include <SD.h>
#include <SoftwareSerial.h>
       
SoftwareSerial cameraconnection(2, 3);

#define PIC_BUF_LEN 64       //data length of each read

char cmdRST[] = {0x56,0x00,0x26,0x00};        //Reset command

char cmdCAP[] = {0x56,0x00,0x36,0x01,0x00};  //Take picture command

char cmdGetLen[] = {0x56,0x00,0x34,0x01,0x00};   //Read JPEG file size command

char cmdGetDat[] = {0x56,0x00,0x32,0x0c,0x00,0x0a,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0a}; //Read JPEG data command

char cmdConti[] = {0x56,0x00,0x36,0x01,0x02};   //Take next picture command

char cmdClrCache[] = {0x56,0x00,0x36,0x01,0x02}; //Clear Photo Cache command

char cmdCompress[] = {0x56,0x00,0x31,0x05,0x01,0x01,0x12,0x04,0x36};  //Compression Ratio Command
  
unsigned int picTotalLen = 0;  // picture length

#define chipSelect 10

void setup()
{
  Serial.begin(115200);
  delay(3000);
  cameraconnection.begin(115200);
  
  Serial.println("Initializing SD card....");
  if(chipSelect != 10) pinMode(10, OUTPUT); // SS on Uno, etc.
   
  if (!SD.begin(chipSelect)) {
    Serial.println("initialzation failed");
    return;
  }
  Serial.println("initialization done.");
  Restart();
  delay(3000);
  CompressRatio();
  delay(1000);
  Capture();
  delay(1000);
  GetData();
  delay(1000);
  ClrCache();
}

void loop()
{
  cameraconnection.flush();
  ContCapture();
  delay(1000);
  GetData();
  delay(1000);
  ClrCache();
  Serial.println("Taking pictures success");
  delay(3000);
}

 void sendCmd(char cmd[] ,int cmd_len)
{
  for(char i = 0; i < cmd_len; i++)
    cameraconnection.print(cmd[i]);  
}

void Capture()
{
  sendCmd(cmdCAP,5);
  delay(50);
  while(cameraconnection.available() > 0){
    cameraconnection.read();
  }
}

void ContCapture()
{
  sendCmd(cmdConti,5);
  delay(50);
  while(cameraconnection.available() > 0){
    cameraconnection.write(cameraconnection.read());
  }
}

void ClrCache()
{
  sendCmd(cmdClrCache,5);
  delay(50);
  while(cameraconnection.available() > 0){
    cameraconnection.read();
  }
}

void CompressRatio()
{
  sendCmd(cmdCompress,9);
  delay(50);
  while(cameraconnection.available() > 0){
    cameraconnection.read();
  }
}

void GetData()
{
  unsigned int picTotalLen;
  sendCmd(cmdGetLen,5);
  delay(50);
  for(char i = 0; i < 7; i++){
    cameraconnection.read();
  }
  picTotalLen = 0;
  int high = cameraconnection.read();
  picTotalLen |= high ;
  int low  = cameraconnection.read();
  picTotalLen = picTotalLen << 8 ;
  picTotalLen |= low ;                      //get the length of picture 
  
  unsigned int addr = 0;
  cmdGetDat[8] = 0;
  cmdGetDat[9] = 0;
  unsigned int count = picTotalLen / PIC_BUF_LEN;
  char tail = picTotalLen % PIC_BUF_LEN;
  cmdGetDat[13] = PIC_BUF_LEN;              //the length of each read data
  
  // Create an image with the name IMAGExx.JPG
  char picName[13];
  strcpy(picName, "IMAGE00.JPG");
  for (int i = 0; i < 100; i++) {
    picName[5] = '0' + i/10;
    picName[6] = '0' + i%10;
    // create if does not exist, do not open existing, write, sync after write
    if (! SD.exists(picName)) {
      break;
    }
  }
  Serial.println(picName);
  
  File myFile = SD.open(picName, FILE_WRITE);
  
  if(!myFile){
    Serial.println("Open Failed !");
  }
  else{
    Serial.println("Open done !");
    for(char i = 0; i < count; i++){      //get and save count*PIC_BUF_LEN data
      sendCmd(cmdGetDat,16);
      delay(10);
      readCamSaveToFile(myFile, PIC_BUF_LEN);
      addr += PIC_BUF_LEN;
      cmdGetDat[8] = addr >> 8;
      cmdGetDat[9] = addr & 0x00FF;
    }
    cmdGetDat[13] = tail;                  //get rest part of the pic data
    sendCmd(cmdGetDat,16);
    delay(10);
    readCamSaveToFile(myFile, tail);      
  }
  myFile.close();
}

void readCamSaveToFile(File &myFile,int toBeReadLen)
{
  char readLen = 0;
  for(char i = 0;i < 5;i ++){//read the signal that tells us that it's ready to send data 
    cameraconnection.read();
  }
  while(readLen < toBeReadLen){//read and store the JPG data that starts with 0xFF 0xDB
      myFile.write(cameraconnection.read());
      readLen++;
  }
  for(char i = 0;i < 5;i ++){ //read the signal of sussessful sending
    cameraconnection.read();
  }
}

void Restart()
{
  sendCmd(cmdRST,4);
  delay(1000);
  while(cameraconnection.available() > 0)
    cameraconnection.write(cameraconnection.read());
  Serial.println("Camera initialization done.");
}

I put some Serial.print to check the values of some vars.

I attached the new console log.

After some research I found about this protocol

Step 1:Send 56 00 36 01 00 to stop current frame

Step 2:Send 56 00 34 01 00 to obtain the data length of current frame

Receive returned data:76 00 34 00 04FF FF FF FF(red indicates bytes of BUFF, 4 bytes)

Step 3:Send:56 00 32 0C 00 0A00 00 00 00FF FF FF FF10 00(blue indicates that the data is with fixed value)

Returned data from the serial port:76 00 32 00 00FF D8 …Image data… FF D976 00 32 00 00

Step 4:Send :56 00 36 01 03 to recover frame, back to normal working status

So basically i need to send the command in step 2 in order to read what values has those FF FF FF FF and then send them back with the command in step 3 to get the image data .
Every help is appreciated… I’m total noob to these stuff.

themtsil:
here is the code . Tell me your opinion about on what code i should continue with. this one or the adafruit snapshot example.

I can't tell by reading the code if it works on your hardware. Does it work?

The previous code wasnt working.

I made some more digging in the adafruit library and i found the function printBuff();
That prints in my console what the camera module returns in every command.

I attached the full console log in a txt.
and a screenshot of the console log that shows the 0x76 0x0 0x34 0x0 return command that starts the data flow.
and if you see it starts normally and then after some writes the data stop being in a row.
dont know if it is something important but it is odd.

my problem is that the the file is either corrupted or it shows a small part so it must have something to do with those data that have different structure.

console-log.txt (53.7 KB)

themtsil:
I made some more digging in the adafruit library and i found the function printBuff();
That prints in my console what the camera module returns in every command.

I don't see anything useful in the receive buffer.
I still wonder why "runCommand(VC0706_READ_DATA, args, sizeof(args), 6)" is returning 'false' when the code tries to get the image size. I think that would be a clue to why the returned image is faulty.

How should I resolve this issue with the getimage function then ?
I really have no clue of debugging.
Can I do something through arduino or I have to use another software to debug the adafruit.h and adafruit .cpp ?

themtsil:
How should I resolve this issue with the getimage function then ?

Use the editor of your choice to add Serial.println() statements to functions in the library to show what they are doing. be sure to save the changes before you re-upload the sketch.