Newbie needs help taking a picture with the Arduino

So I have this camera Blog - CuteDigi and I've been trying to figure out how to use it. I contacted the manufacturer, Linksprite, who directed me to that page. I'm trying to follow that tutorial with the coding so I can learn more about how to use it so I can use it in other things, but I have a hard time getting the code to work in general. I tried contacting SparkFun, but they just told me to use the older version of Arduino, which doesn't work with some of the other shields I am using.

Has anyone successfully taken a picture with the camera and saved it to an SD card?

Right now I'm getting this error:

In file included from sketch_jul31b.ino:1:
C:\Users\Filet\Documents\Arduino\libraries\JPEGCamera/JPEGCamera.h:10:22: error: WProgram.h: No such file or directory
In file included from sketch_jul31b.ino:4:
C:\Users\Filet\Documents\Arduino\libraries\NewSoftSerial/NewSoftSerial.h:71: error: conflicting return type specified for 'virtual void NewSoftSerial::write(uint8_t)'
C:\Program Files (x86)\Arduino\hardware\arduino\cores\arduino/Print.h:48: error: overriding 'virtual size_t Print::write(uint8_t)'

Does anyone know what that means? :frowning:

Any help would be greatly appreciated

Does anyone know what that means

It means it is looking for a file called WProgram.h and can't find it because it is not used any more.
You need to edit the library file called JPEGCamera.h and where it says WProgram.h replace it with Arduino.h

Okay, I fixed that and it worked... sort of.

I guess it's back to the ol' fix one problem and a bunch more surface. Now it's telling me:

In file included from sketch_jul31b.ino:4:
C:\Users\Filet\Documents\Arduino\libraries\NewSoftSerial/NewSoftSerial.h:71: error: conflicting return type specified for 'virtual void NewSoftSerial::write(uint8_t)'
C:\Program Files (x86)\Arduino\hardware\arduino\cores\arduino/Print.h:48: error: overriding 'virtual size_t Print::write(uint8_t)'

I'm guessing it has some conflicting thing with SoftwareSerial, but I don't know what, and I don't know how to fix it. Do you have any ideas?

Actually, I changed NewSoftSerial.h to SoftwareSerial.h and that's been fixed and the problems just keep multiplying...

the problems just keep multiplying

Yes that is often the case. Basically they are old libraries you are trying to use on a new system.
Maybe the advice to downgrade your arduino IDE was a good idea.

Grumpy_Mike:
Maybe the advice to downgrade your arduino IDE was a good idea.

I would, but I'm trying to make a cell phone sort of thing with a camera, and the GSM shield I'm using has the library in Arduino IDE 1.0.4 or above, and I have to modify one of them some way or the other.

Do you know if SoftwareSerial is a class? in JPEGCamera.h it says

NewSoftSerial cameraPort(2,3);

If I change NewSoftSerial to SoftwareSerial, would that be valid?

and in 'void JPEGCamera::begin()', what does the "::" mean?

Do you know if SoftwareSerial is a class?

yes it is.

'void JPEGCamera::begin()', what does the "::" mean?

it means 'begin' is a method of the class 'JPEGCamera'

So I edited the JPEGCamera library, and it stopped giving me error messages (which I hope is a good thing). I changed things like Serial.print(XXX, BYTE) to Serial.write(XXX) and changed all of the WProgram.h's to Arduino.h.

I also added a thing on the JPEGCamera library to have

SoftwareSerial cameraPort(2,3); //RX is 2, TX is 3

JPEGCamera::JPEGCamera()
{
}

//Initialize the serial connection
void JPEGCamera::begin(void)
{
	//Camera baud rate is 38400
	cameraPort.begin(38400);
}


bool JPEGCamera::isAvailable(void){
	return cameraPort.available();
}

Where that last one is the thing I added. However, when I try to use the function (i.e. camera.isAvailable()), it keeps returning false. Is there something wrong with the wiring of my camera, or is there something inherently wrong with what I am trying?

You will have to look at what that call detects to make the decision before you can tell.

So I found another library from Adafruit that works with the newer version of Arduino.

So my code currently looks like this:

// This is a motion-detect camera sketch using the Adafruit VC0706 library.
// On start, the Arduino will find the camera and SD card and turn
// on motion detection.  If motion is detected, the camera will
// snap a photo, saving it to the SD card.
// Public domain.

// If using an Arduino Mega (1280, 2560 or ADK) in conjunction
// with an SD card shield designed for conventional Arduinos
// (Uno, etc.), it's necessary to edit the library file:
//   libraries/SD/utility/Sd2Card.h
// Look for this line:
//   #define MEGA_SOFT_SPI 0
// change to:
//   #define MEGA_SOFT_SPI 1
// This is NOT required if using an SD card breakout interfaced
// directly to the SPI bus of the Mega (pins 50-53), or if using
// a non-Mega, Uno-style board.

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



// comment out this line if using Arduino V23 or earlier
#include <SoftwareSerial.h>         

// uncomment this line if using Arduino V23 or earlier
// #include <NewSoftSerial.h>       



// SD card chip select line varies among boards/shields:
// Adafruit SD shields and modules: pin 10
// Arduino Ethernet shield: pin 4
// Sparkfun SD shield: pin 8
// Arduino Mega w/hardware SPI: pin 53
// Teensy 2.0: pin 0
// Teensy++ 2.0: pin 20
#define chipSelect 10

// Pins for camera connection are configurable.
// With the Arduino Uno, etc., most pins can be used, except for
// those already in use for the SD card (10 through 13 plus
// chipSelect, if other than pin 10).
// With the Arduino Mega, the choices are a bit more involved:
// 1) You can still use SoftwareSerial and connect the camera to
//    a variety of pins...BUT the selection is limited.  The TX
//    pin from the camera (RX on the Arduino, and the first
//    argument to SoftwareSerial()) MUST be one of: 62, 63, 64,
//    65, 66, 67, 68, or 69.  If MEGA_SOFT_SPI is set (and using
//    a conventional Arduino SD shield), pins 50, 51, 52 and 53
//    are also available.  The RX pin from the camera (TX on
//    Arduino, second argument to SoftwareSerial()) can be any
//    pin, again excepting those used by the SD card.
// 2) You can use any of the additional three hardware UARTs on
//    the Mega board (labeled as RX1/TX1, RX2/TX2, RX3,TX3),
//    but must specifically use the two pins defined by that
//    UART; they are not configurable.  In this case, pass the
//    desired Serial object (rather than a SoftwareSerial
//    object) to the Adafruit_VC0706 constructor.

// Using SoftwareSerial (Arduino 1.0+) or NewSoftSerial (Arduino 0023 & prior):
#if ARDUINO >= 100
// On Uno: camera TX connected to pin 2, camera RX to pin 3:
SoftwareSerial cameraconnection = SoftwareSerial(4, 5);
// On Mega: camera TX connected to pin 69 (A15), camera RX to pin 3:
//SoftwareSerial cameraconnection = SoftwareSerial(69, 3);
#else
NewSoftSerial cameraconnection = NewSoftSerial(4, 5);
#endif
Adafruit_VC0706 cam = Adafruit_VC0706(&cameraconnection);

// Using hardware serial on Mega: camera TX conn. to RX1,
// camera RX to TX1, no SoftwareSerial object is required:
//Adafruit_VC0706 cam = Adafruit_VC0706(&Serial1);


void setup() {
  
/******************** CAMERA INITIALIZE *****************************/

  // When using hardware SPI, the SS pin MUST be set to an
  // output (even if not connected or used).  If left as a
  // floating input w/SPI on, this can cause lockuppage.
#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

  Serial.begin(9600);
  Serial.println("SMS Trigger");

  // 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");

/****************************************CAMERA SETUP*******************************************/

}




void loop() {
  longSnap();
  Serial.println("Taking picture in 3 seconds...");
  delay(3000);


}

void longSnap(){
  if (!cam.takePicture()) {
    Serial.println("Failed to snap!");
    while(true){}
  }
  else 
    Serial.println("Picture taken!");

  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;
    }
  }

  File imgFile = SD.open(filename, FILE_WRITE);

  uint16_t jpglen = cam.frameLength();
  Serial.print(jpglen, DEC);
  Serial.println(" byte image");

  Serial.print("Writing image to "); 
  Serial.print(filename);

  while (jpglen > 0) {
    // read 32 bytes at a time;
    uint8_t *buffer;
    uint8_t bytesToRead = min(32, jpglen); // change 32 to 64 for a speedup but may not work with all setups!
    buffer = cam.readPicture(bytesToRead);
    imgFile.write(buffer, bytesToRead);

    //Serial.print("Read ");  Serial.print(bytesToRead, DEC); Serial.println(" bytes");

    jpglen -= bytesToRead;
  }
  imgFile.close();
  Serial.println("...Done!");

  
  delay(3000);
  
  imgFile.flush();
  
  cam.resumeVideo();
  

  }

And it gives me these error messages:

C:\Program Files (x86)\Arduino\hardware\tools\avr\bin\avr-ar: unable to rename 'core.a'; reason: File exists
SoftwareSerial\SoftwareSerial.cpp.o: In function __vector_3': C:\Program Files (x86)\Arduino\libraries\SoftwareSerial/SoftwareSerial.cpp:305: multiple definition of __vector_3'
GSM\GSM3SoftSerial.cpp.o:C:\Program Files (x86)\Arduino\libraries\GSM/GSM3SoftSerial.cpp:511: first defined here
SoftwareSerial\SoftwareSerial.cpp.o: In function __vector_4': C:\Program Files (x86)\Arduino\libraries\SoftwareSerial/SoftwareSerial.cpp:312: multiple definition of __vector_4'
GSM\GSM3SoftSerial.cpp.o:C:\Program Files (x86)\Arduino\libraries\GSM/GSM3SoftSerial.cpp:518: first defined here
SoftwareSerial\SoftwareSerial.cpp.o: In function __vector_5': C:\Program Files (x86)\Arduino\libraries\SoftwareSerial/SoftwareSerial.cpp:319: multiple definition of __vector_5'
GSM\GSM3SoftSerial.cpp.o:C:\Program Files (x86)\Arduino\libraries\GSM/GSM3SoftSerial.cpp:525: first defined here

I'm not sure what they mean or how I can fix it, but I do know that the program runs perfectly fine until I add the line

"#include <GSM.h>"

but I need to have that library as well. I feel like there's something conflicting, but I'm not sure what and I don't know how to fix it.

Thanks again in advance.

Those messages mean that two pieces of code both want the interrupt vectors. You are into a major rewrite of one of the libaries I fear.