Storing Jpeg Image to SD card

I am using an Arduino with a micro-SD slot and a small jpeg camera to capture images. But even at the obscenely low resolution of 160x120, the rate that I can store an image to the SD card is 1.4 seconds per photo.

The photos are about 3400 bytes. Is there something other than the default SD library that would be able to improve this Writing speed?

Is there something other than the default SD library that would be able to improve this Writing speed?

More likely, the problem is with your code for storing the data. Show us that code, first.

More likely, the problem is with your code for storing the data. Show us that code, first.

This is all of my code pertaining to the camera, I am using a status holder to store most of my values but you should be able to follow along.

String takePic(int ImageSize) {
  // Try to locate the camera
  if (!camStatus) {
    Serial.println("Camera Fail");
    return "";
  }
  //cam.begin(); //Need to ensure it worked
  cam.setImageSize(ImageSize);//cam.setImageSize(VC0706_160x120);

  if (!cam.takePicture()) {
    Serial.println("Take Failure");
    return "";
  } else {
    StatusHolder.numPhotos++;
    Serial.print("Picture taken! ");
  }

  // Create an image with the name Axxxx.JPG //ALTER THIS TO STORE THE NEXT AVAILABLE FILENAME
  char filename[9];
  strcpy(filename, "A0000.JPG");
  for (int i = 0; i < 9999; i++) {
    filename[1] = '0' + i / 1000;
    filename[2] = '0' + i % 1000 / 100;
    filename[3] = '0' + i % 1000 % 100 / 10;
    filename[4] = '0' + i % 1000 % 100 % 10;
    if (!SD.exists(filename)) {
      Serial.print("File created: ");
      Serial.println(filename);
      break;
    }
  }
  File imgFile = SD.open(filename, FILE_WRITE); //Open Image File
  uint16_t jpglen = cam.frameLength(); //Image Size in Bytes
  uint16_t bytesWritten = 0;

  //int32_t time = millis();
  pinMode(8, OUTPUT);
  // Read all the data up to # bytes!
  byte wCount = 0; // For counting # of writes
  long startT = millis();
  while (jpglen > 0 && 1) { //(millis() - startT <= 3000)) {
    uint8_t *databuffer;
    uint8_t bytesToRead = min(64, jpglen); // 64 Byte Reads
    databuffer = cam.readPicture(bytesToRead);
    bytesWritten += imgFile.write(databuffer, bytesToRead); //Returns bytes written if needed
    if (++wCount >= 64) { // Every 2K, give a little feedback so it doesn't appear locked up
      //Reset Timer Here
      wCount = 0;
    }
    jpglen -= bytesToRead;
    //Serial.println(jpglen);
  }
  
  Serial.print("capture time:");
  Serial.println(millis()-startT);
  //  if (millis() - startT <= 3000) {
  //    Serial.println("Photo Write Timeout");
  //  }
  imgFile.close();
  //time = millis() - time;
  camStatus = false;
  return filename;
}

[code]
  while (jpglen > 0 && 1) { //(millis() - startT <= 3000)) {

While there is remaining data AND 1… What possible reason is there for the logical AND?

If you comment out the write to file, how long does it take to read the data from the camera?

Not-A-Bot:
This is all of my code pertaining to the camera, I am using a status holder to store most of my values but you should be able to follow along.

String takePic(int ImageSize) {

// Try to locate the camera
 if (!camStatus) {
   Serial.println(“Camera Fail”);
   return “”;
 }
 //cam.begin(); //Need to ensure it worked
 cam.setImageSize(ImageSize);//cam.setImageSize(VC0706_160x120);

if (!cam.takePicture()) {
   Serial.println(“Take Failure”);
   return “”;
 } else {
   StatusHolder.numPhotos++;
   Serial.print("Picture taken! ");
 }

// Create an image with the name Axxxx.JPG //ALTER THIS TO STORE THE NEXT AVAILABLE FILENAME
 char filename[9];
 strcpy(filename, “A0000.JPG”);
 for (int i = 0; i < 9999; i++) {
   filename[1] = ‘0’ + i / 1000;
   filename[2] = ‘0’ + i % 1000 / 100;
   filename[3] = ‘0’ + i % 1000 % 100 / 10;
   filename[4] = ‘0’ + i % 1000 % 100 % 10;
   if (!SD.exists(filename)) {
     Serial.print("File created: ");
     Serial.println(filename);
     break;
   }
 }
 File imgFile = SD.open(filename, FILE_WRITE); //Open Image File
 uint16_t jpglen = cam.frameLength(); //Image Size in Bytes
 uint16_t bytesWritten = 0;

//int32_t time = millis();
 pinMode(8, OUTPUT);
 // Read all the data up to # bytes!
 byte wCount = 0; // For counting # of writes
 long startT = millis();
 while (jpglen > 0 && 1) { //(millis() - startT <= 3000)) {
   uint8_t *databuffer;
   uint8_t bytesToRead = min(64, jpglen); // 64 Byte Reads
   databuffer = cam.readPicture(bytesToRead);
   bytesWritten += imgFile.write(databuffer, bytesToRead); //Returns bytes written if needed
   if (++wCount >= 64) { // Every 2K, give a little feedback so it doesn’t appear locked up
     //Reset Timer Here
     wCount = 0;
   }
   jpglen -= bytesToRead;
   //Serial.println(jpglen);
 }
 
 Serial.print(“capture time:”);
 Serial.println(millis()-startT);
 //  if (millis() - startT <= 3000) {
 //    Serial.println(“Photo Write Timeout”);
 //  }
 imgFile.close();
 //time = millis() - time;
 camStatus = false;
 return filename;
}

when using ‘cstrings’ remember to include space for the trailing NULL:

  char filename[9];
  strcpy(filename, "A0000.JPG");

Needs to be at least:

  char filename[10];
  strcpy(filename, "A0000.JPG");

Where is databuffer pointing? is it pointing to a memory buffer internal to the cam() object?

 uint8_t *databuffer;
    uint8_t bytesToRead = min(64, jpglen); // 64 Byte Reads
    databuffer = cam.readPicture(bytesToRead);
    bytesWritten += imgFile.write(databuffer, bytesToRead); //Returns bytes written if needed
    if (++wCount >= 64) { // Every 2K, give a little feedback so it doesn't appear locked up
      //Reset Timer Here
      wCount = 0;
    }
    jpglen -= bytesToRead;
    //Serial.println(jpglen);
  }

Is uint8_t* cam.readPicture(uint8_t bufsize); actually:
uint8_t* cam.readPictureNextBytes(uint8_t bufsize);?

Does the cam() object maintain a ‘current’ position for the ‘read’ function?

Chuck.