Can't communicate with Linksprite JPEG camera

Hello all,
I've recently picked up the Linksprite TTL JPEG camera (http://www.sparkfun.com/products/10061) and i've been having a heck of a time trying to get it running. I was hoping someone has worked with this and could help me troubleshoot... At present, I just want to send a take photo command, read the data from the camera, and output it to the serial monitor (eventually i'll store the data). I've been trying to use the library and sample code on the linksprite page (http://www.linksprite.com/download/showdownload.php?id=70&lang=en), but I don't seem to be getting any data being transmitted by the camera. The sample code also didn't make clear how to wire the camera, but when I configure 'myserial(4,5)' I connect pin 4 to the Rx pin of the camera and pin 5 to Tx. I tried it the other way around too and nothing there. I am powering the camera from the 5v pin on the arduino mega board. I checked for breaks in my connecting wires but all good there. Any idea on why I am not getting any data outputted to my serial monitor when I run this code?
Thanks!

The sample code also didn't make clear how to wire the camera, but when I configure 'myserial(4,5)' I connect pin 4 to the Rx pin of the camera and pin 5 to Tx. I tried it the other way around too and nothing there. I am powering the camera from the 5v pin on the arduino mega board. I checked for breaks in my connecting wires but all good there. Any idea on why I am not getting any data outputted to my serial monitor when I run this code?

Most likely because NewSoftSerial doesn't work on the Mega. Why should it? You've got 4 hardware serial ports.

I'll give it a try using the same commands but wiring it using one of the hard serial ports. I did try the NewSoftSerial code with the camera on the Duemilanove and it didn't work there either, so i'm thinking something else is wrong too...

I'll give it a try using the same commands but wiring it using one of the hard serial ports.

Well, that's a recipe for disaster. You have the use the proper code to read from a hardware serial port. SerialN.read(), not mySerial.read(). (where N is the appropriate hardware serial port).

That's what I had planned on doing; using the same procedure for reading byte chunks, but using the Serial1.read() command instead of the mySerial command. They're both standard TTL so the timing and communication should be the same, as far as I can tell...

What is the buffer size on the Serial line by the way?
Thanks!

Ah! Works fine now. I dug in to the reference material on the home page, and it seems that the software based serial will only work on certain pins of the Mega, (Rx interrupts...); so I suppose that is why I was encountering problems.

Now to convert a hexadecimal txt file into an image file. Any ideas or links/references? I need to dig around a little on the web for this one...
Thanks!

What are you using to write the file?
Just write the byte to the file not the number. That is take the two ASCII hex bytes, combine them into a real byte, and treat that as a char to write to the file.
This is how you convert from an ASCII text character into a nibble

int convertFromHex(int ascii){ 
  if(ascii > 0x39) ascii -= 7; // adjust for hex letters upper or lower case
  return(ascii & 0xf);
}

Now to convert a hexadecimal txt file into an image file. Any ideas or links/references? I need to dig around a little on the web for this one...

Does the cam send the .jpg as a hex file, or are you seeing the bytes sent displayed in a hex format?

I am using this to print the data to the serial port:

for(j=0;j<count;j++)
{ if(a[j]<0x10)
Serial.print("0");
Serial.print(a[j],HEX);
Serial.print(" ");
} //Send jpeg picture over the serial port

It is printing the value in HEX, but the imported/stored data is Byte, I believe. So if I write a[j] which is byte format directly to file (I don't have an SD shield or other exterior storage device, but i'll pick one up eventually), and append .jpg to the end, then my computer will open it as an image file? Sorry for the ignorance, but I haven't worked with this side of stuff before...
Also, if this is the case, should I print the a[j] values with a space between (any delimiting?) or do I just print a[j] directly to file consecutively for all of the 'j' bytes that exist in the file?

Thanks for all the insight!

So if I write a[j] which is byte format directly to file (I don't have an SD shield or other exterior storage device, but i'll pick one up eventually), and append .jpg to the end, then my computer will open it as an image file?

Basically yes.

Also, if this is the case, should I print the a[j] values with a space between (any delimiting?)

You don't print at all you send that byte to your storage system if you are having the storage system on an SD card attached to your arduino.
If you are having another application on your PC read this stream and then write it to a file (something like the Processing language) then keep things as they are and have the ASCII to byte conversion like I showed earlier.

Also, if this is the case, should I print the a[j] values with a space between (any delimiting?) or do I just print a[j] directly to file consecutively for all of the 'j' bytes that exist in the file?

I'd write it exactly as received. If you add or remove anything, the file will probably fail when attempted to display as a .jpg image.

Great, thanks. I'll give it a try once I get a memory storage device.
Cheers,
-Nick

Okay, so I finally got an SD shield for the arduino, and i've configured the camera to spit out bits on the additional hard Serial1 line on the mega. I can get an intelligible response from the camera, and get valid data when I have it spit out info on to the serial monitor. When I try to write it to file, however, I can't open the .jpeg that has the bytes from the camera written to it. If anybody has an idea of how to go about troubleshooting and fixing this I would be very appreciative!

I am using the datalogger shield and SD.lib from ladyada Data-Logger Shield for Arduino
In my code, I have the camera output 32 byte segments, and I then write them to the SD card file. My guess would be that each time I write the SD card buffer data to file, it appends some information/bytes before or after each buffer flush. This would mean that the .jpeg file that I create has additional bytes between the data segments that I want to comprise the file. I'm not sure how to chop out this added info, if that is indeed the case. I don't know what the SD buffer size is, but I would assume it is quite a bit smaller than the entire image size, so I couldn't just accrue info and flush it at the end (even if I could do this I would speculate that the file would have additional bytes appended at the beginning or end).

Thanks!
-Nick

In my code, I have the camera output 32 byte segments, and I then write them to the SD card file. My guess would be that each time I write the SD card buffer data to file, it appends some information/bytes before or after each buffer flush.

Why not show us the code, so we can confirm/refute that hypothesis?

When I try to write it to file, however, I can't open the .jpeg that has the bytes from the camera written to it.

So look at the file with a hex dump application and see what bytes are written to it.
Then compare that with the first few bytes from a Jpeg file.

Thanks. What is a freeware hex dump application I could use to investigate the file? I have never used one before...

Here is the code that I am using:

//------------------------------
//CAMERA SETUP INFO

byte incomingbyte;
int a=0x0000,j=0,k=0,count=0, p=0;                    //Read Starting address       
uint8_t MH,ML;
boolean EndFlag=0;
                               
void SendResetCmd();
void SendTakePhotoCmd();
void SendReadDataCmd();
void StopTakePhotoCmd();

//------------------------------
//DATALOGGER INFO

#include <SD.h>
#include <Wire.h>
#include "RTClib.h"

// how many milliseconds between grabbing data and logging it. 1000 ms is once a second
#define LOG_INTERVAL  1000 // mills between entries (reduce to take more/faster data)

// how many milliseconds before writing the logged data permanently to disk
// set it to the LOG_INTERVAL to write each time (safest)
// set it to 10*LOG_INTERVAL to write all data every 10 datareads, you could lose up to 
// the last 10 reads if power is lost but it uses less power and is much faster!
#define SYNC_INTERVAL 1000 // mills between calls to flush() - to write data to the card
uint32_t syncTime = 0; // time of last sync()

#define ECHO_TO_SERIAL   1 // echo data to serial port
#define WAIT_TO_START    0 // Wait for serial input in setup()

// the digital pins that connect to the LEDs
#define redLEDpin 2
#define greenLEDpin 3

// The analog pins that connect to the sensors
#define photocellPin 0           // analog 0
#define tempPin 1                // analog 1
#define BANDGAPREF 14            // special indicator that we want to measure the bandgap

#define aref_voltage 3.3         // we tie 3.3V to ARef and measure it with a multimeter!
#define bandgap_voltage 1.1      // this is not super guaranteed but its not -too- off

RTC_DS1307 RTC; // define the Real Time Clock object

// for the data logging shield, we use digital pin 10 for the SD cs line
const int chipSelect = 10;

// the logging file
File logfile;

void error(char *str)
{
  Serial.print("error: ");
  Serial.println(str);
  
  // red LED indicates error
  digitalWrite(redLEDpin, HIGH);

  while(1);
}

//---------------------------------------------

void setup()
{ 
  Serial.begin(9600);  //communication with computer
  Serial1.begin(38400); //communication with camera
  
  // use debugging LEDs
  pinMode(redLEDpin, OUTPUT);
  pinMode(greenLEDpin, OUTPUT);
  
  pinMode(10, OUTPUT);
  
  // see if the card is present and can be initialized:
  if (!SD.begin(chipSelect)) 
    {
      error("Card failed, or not present");
    }
  Serial.println("card initialized.");
  
  // connect to RTC
  Wire.begin();  
  if (!RTC.begin()) {
    logfile.println("RTC failed");
#if ECHO_TO_SERIAL
    Serial.println("RTC failed");
#endif  //ECHO_TO_SERIAL
  }
   
}



//---------------------------------------------
void loop() 
{
  Serial.println("Type any character to start"); //wait for serial input to do anything
  while (!Serial.available());
  {
  }
  
  delay(1000);
  
        //--------------------------------------
 // create a new file
  char filename[] = "logger00.jpg";
  for (uint8_t i = 0; i < 100; i++) {
    filename[6] = i/10 + '0';
    filename[7] = i%10 + '0';
    if (! SD.exists(filename)) {
      // only open a new file if it doesn't exist
      logfile = SD.open(filename, FILE_WRITE); 
      break;  // leave the loop!
    }
  }
  Serial.print("Logging to: ");
  Serial.println(filename);
  //---------------------------------------------
  
  delay(1000);
  Serial.println("about to take picture...");
    
       byte a[32];
       
       SendResetCmd(); //reset camera
       delay(4000);                      //After reset, wait 2-3 second to send take picture command
        
        SendTakePhotoCmd();
    
       while(Serial1.available()>0) //clear serial1 buffer
        {
          incomingbyte=Serial1.read();
  
        }   
        
        while(!EndFlag)
        {  
           j=0;
           k=0;
           count=0;
           SendReadDataCmd();
           delay(20);
            while(Serial1.available()>0)
            {
                 incomingbyte=Serial1.read();
                 k++;
                 if((k>5)&&(j<32)&&(!EndFlag))
                 {
                 a[j]=incomingbyte;
                 if((a[j-1]==0xFF)&&(a[j]==0xD9))      //Check if the picture is over
                 EndFlag=1;                           
                 j++;
  	       count++;
                 }
            }
           
            /*for(j=0;j<count;j++)
            {  if(a[j]<0x10)
               Serial.print("0");
               Serial.print(a[j],HEX);
                Serial.print(" ");
            } 
            //Send jpeg picture over the serial port
            */
            Serial.print((char*)a);
            
            logfile.print((char*)a);
            /*for(j=0;j<count;j++)
            {
            logfile.print(a[j]);
           // logfile.print(",");
            }
           // logfile.println();
            */
            logfile.flush();
            
            p++;
            
            Serial.println();
        }
         
     logfile.close(); 
     
     while(1); //lock loop
}

//------------------------------------
//FUNCTIONS FOR CAMERA OPERATION

//Send Reset command
void SendResetCmd()
{
      Serial1.print(0x56, BYTE);
      Serial1.print(0x00, BYTE);
      Serial1.print(0x26, BYTE);
      Serial1.print(0x00, BYTE);
}

//Send take picture command
void SendTakePhotoCmd()
{
      Serial1.print(0x56, BYTE);
      Serial1.print(0x00, BYTE);
      Serial1.print(0x36, BYTE);
      Serial1.print(0x01, BYTE);
      Serial1.print(0x00, BYTE);  
}

//Read data
void SendReadDataCmd()
{
      MH=a/0x100;
      ML=a%0x100;
      Serial1.print(0x56, BYTE);
      Serial1.print(0x00, BYTE);
      Serial1.print(0x32, BYTE);
      Serial1.print(0x0c, BYTE);
      Serial1.print(0x00, BYTE); 
      Serial1.print(0x0a, BYTE);
      Serial1.print(0x00, BYTE);
      Serial1.print(0x00, BYTE);
      Serial1.print(MH, BYTE);
      Serial1.print(ML, BYTE);   
      Serial1.print(0x00, BYTE);
      Serial1.print(0x00, BYTE);
      Serial1.print(0x00, BYTE);
      Serial1.print(0x20, BYTE);
      Serial1.print(0x00, BYTE);  
      Serial1.print(0x0a, BYTE);
      a+=0x20;                            //address increases 32£¬set according to buffer size
}

void StopTakePhotoCmd()
{
      Serial1.print(0x56, BYTE);
      Serial1.print(0x00, BYTE);
      Serial1.print(0x36, BYTE);
      Serial1.print(0x01, BYTE);
      Serial1.print(0x03, BYTE);        
}

What is a freeware hex dump application I could use to investigate the file?

It depends on what OS you are running.

Please modify that post, select the code and hit the # icon and then save it.

Okay, code is up. I typically work in OSX, but Vista is well and to a lesser extent Linux. An OSX hex dump would be most useful since I typically program my arduino from the OSX.
Thanks,
-Nick

Testing to try, perhaps when the picture is captured to the SD card, remove the card, plug it into a pc, and see if it has the .jpg captured in a viewable form. Also you might try sending the commands via a terminal program that can save the returned data as a file (possibly hyperterminal or similar), then see if the returned file is viewable.