Sychronize JPEG camera and SD card

Hi!
I'm working on a project where I try to take a foto with a JPEG camera and stock it on my SD card. The codes of taking the foto and writing to the card have been taken out from example codes, I've already tested it and it works well. It happens that the SD card only takes text files, so I used an algorythm (also taken out from example codes concerning both the camera and the card at a time) to transform the .jpg to .txt, and it also worked fine. But, when I tried to invert the process to get back my foto, I followed the instructions on a commentary of the sample code:

//The file has to be renamed to .jpg when copied to a computer.

So I just took it out the card, copied it into my computer and renamed it... But it didn't work. It told me:

Not a JPEG file: starts with 0xff 0xec

So, if any of you could tell me why this happens or how to fix it, I'd be extremely thankful :smiley:

It happens that the SD card only takes text files

That's a very strange statement.

You post is missing a great deal of useful information.

That's right, I'm sorry. The actual fact is that I misunderstood a comment: it's not the card but the library I'm using that only accepts txt: MemoryCard.h

//NOTE: The memoryCard libary can only create text files.

I will post you my loop function, it will be easier that way...

    //deactivate the flag eof
    eof = 0;

    //Reset
    count=camera.reset(response);
    delay(3000);

    //Take a foto
    count=camera.takePicture(response);

    //Take the size of the pic
    count = camera.getSize(response, &size);

    /*Those comments have been just copy-pasted, it's not me who wrote them:
    //Create a file called 'test.txt' on the SD card.
    //NOTE: The memoryCard libary can only create text files.
    //The file has to be renamed to .jpg when copied to a computer.
    */
    MemoryCard.open("/test.txt", true);

    //Read the camera and write the data to the card
    while(address < size)
    {
      //Starts reading at the current address
      count=camera.readData(response, address);

      //Stock it at the SD card
      for(int i=0; i<count; i++)
      {
        //If the end of file achieved (0xFF, 0xD9), active the eof flag
        if((response[i] == (char)0xD9) && (response[i-1]==(char)0xFF))eof=1;

        //Write the data to the card
        MemoryCard.file.print(response[i], BYTE);

        //If eof achieved, stop reading data
        if(eof==1)break;
      }

      //Increase the current adress by the number of data read
      address+=count;

      //Get out of the while loop if eof has been found
      if(eof==1)break;

    }
    //Close the file
    MemoryCard.close();

I'd also like to signal that I need the foto to be transformed into text, for further interests of my project, that's why I don't even try to keep the foto in jpg format.

Not a JPEG file: starts with 0xff 0xec

A JPEG should start with 0xFF 0xD8, I think.

FFEC is application-specific data.

It sounds like the data from the camera may need some wrappers before it is a true JPEG-format image.

Need more detail - I don't have any of this gear.

For a small amount of info on the APP12 header type (0xFFEC) see here JPEG Tags APP12 is picture info.

The JPEG APP12 "Picture Info" segment was used by some older cameras, and contains ASCII-based meta information.

Maybe if you could attach one of these files you have, we could investigate further.

A JPEG should start with 0xFF 0xD8, I think.

That's also right. After some research, I found out that that's the "magic number" of the .jpg files, and I tried to "force" the future files to begin with this number, by writing it into each file before the foto translation and transport. But I got another error message...
However, I attach to this post the TEXT.txt file so you can read it and eventually fix it; I'd be infinitely thankful.

TEST.txt (12.3 KB)

You talk of sample code you used. Can you post links to the camera your using or it's datasheet and any links to the sample code. Hopefully one of them will have pointers to extracting the data.

Unfortunately, the link to the web where I bought the camera seems to be broken... Anyway, I attach you every single file I've got about the camera and the SD library, where you can find all the source codes and sample codes. The most relevant sample code can be found at ./JPEGCamera/examples/JPEG_Sample/JPEG_Sample.pde. I must admit that I tried to jump into the source codes of both the camera and the card, and I found out that, for the writing, they both use a function called write (obviously overloaded, not the same for both), whose source code is also available on the .zip file I attached to you, but it's too complicated to me to understand :sweat_smile: I thank you the efforts you're doing to help me.

JPEG Camera Libraries.zip (94.2 KB)

According to the manual for this camera

JPEG file start from FF D8 end by FF D9

So it looks like your either not getting all the data or not storing it all. Try sending the data to the Serial monitor and then copy/paste it into a text file and attach it here. I don't have this hardware but if you running version 1.0+ of the Arduino IDE then try the below code. Note the camera is connected to pins 4 & 5 here.

/* Linksprite */

#include <SoftwareSerial.h>

byte incomingbyte;
SoftwareSerial mySerial(4,5);                       //Configure pin 4 and 5 as soft serial port
int address=0x0000,j=0,k=0,count=0;                 //Read Starting address       
boolean EndFlag=0;

void SendResetCmd();
void SendTakePhotoCmd();
void SendReadDataCmd();
void StopTakePhotoCmd();

void setup()
{ 
    Serial.begin(19200);
    mySerial.begin(38400);
}

void loop() 
{
    SendResetCmd();
    delay(4000);                                    //After reset, wait 2-3 second to send take picture command

    SendTakePhotoCmd();

    while(mySerial.available()>0)
    {
        incomingbyte=mySerial.read();

    }   
    byte a[32];

    while(!EndFlag)
    {  
        j=0;
        k=0;
        count=0;
        SendReadDataCmd();

        delay(25);
        while(mySerial.available()>0)
        {
            incomingbyte=mySerial.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.println();
    }      
    while(1);
}

//Send Reset command
void SendResetCmd()
{
    mySerial.print((char)0x56);
    mySerial.print((char)0x00);
    mySerial.print((char)0x26);
    mySerial.print((char)0x00);
}

//Send take picture command
void SendTakePhotoCmd()
{
    mySerial.print((char)0x56);
    mySerial.print((char)0x00);
    mySerial.print((char)0x36);
    mySerial.print((char)0x01);
    mySerial.print((char)0x00);  
}

//Read data
void SendReadDataCmd()
{
    uint8_t MH,ML;
    MH=address/0x100;
    ML=address%0x100;
    mySerial.print((char)0x56);
    mySerial.print((char)0x00);
    mySerial.print((char)0x32);
    mySerial.print((char)0x0c);
    mySerial.print((char)0x00); 
    mySerial.print((char)0x0a);
    mySerial.print((char)0x00);
    mySerial.print((char)0x00);
    mySerial.print((char)MH);
    mySerial.print((char)ML);   
    mySerial.print((char)0x00);
    mySerial.print((char)0x00);
    mySerial.print((char)0x00);
    mySerial.print((char)0x20);
    mySerial.print((char)0x00);  
    mySerial.print((char)0x0a);
    address+=0x20;                            //address increases 32 bytes according to buffer size
}

void StopTakePhotoCmd()
{
    mySerial.print((char)0x56);
    mySerial.print((char)0x00);
    mySerial.print((char)0x36);
    mySerial.print((char)0x01);
    mySerial.print((char)0x03); 
}

Also the code you supplied used old versions of libraries that are present in Arduino 1.0+ so maybe using the later versions would help.

Well, I tried your code, and got a quite strange result. I got four characters repeating infinitely on one only line of the Serial: æ, a square with 0080 written inside, another one with 0098, and the one with 0080 again. I'm using arduino 1.0.1, but I was normally using arduino 0023 until now. What does it all mean?

PS: Actually, as I'm working on a team project, I was supposed to finish with this today. It's just an amateur project, and there's no problem if it's not finished, but it would be nice if I could finish it. What I mean is that I would need the solution as soon as possible, because for now on I've more or less three hours to present the results of my work...

Attached is another version I found that uses the NewSoftSerial library. Give it a try and see if you can send the data direct to the serial monitor. Note the camera needs connecting to pins 4 & 5 in this example. Sorry but as I don't have the hardware your using it is very difficult to debug.

Linksprite.ino (3.03 KB)