LinkSprite camera - Arduino Due

I am using the following camera: https://cdn.sparkfun.com/datasheets/Sensors/LightImaging/JPEG%20camera%202M%20UM.pdf
with an arduino due and a SD card shield. My aim is to get the camera to take a picture and to save it on the SD card and also see the "output" on the Serial Monitor. I am having a bit of trouble, and i'm not sure where i am going wrong, at the moment it has no errors, but there are only blank jpeg files on the SD card. It says that they don't contain anything. Could anyone point me to the section of code which needs work on, i'm assuming it is either the commands (which i have checked against the data sheet) or the transfer of bytes.

Here is the code i am using:

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


byte incomingbyte;                    
long int a=0x0000,j=0,k=0,count=0;                      
uint8_t MH,ML;
boolean EndFlag=0;
const int chipSelect = 4;
File imgFile;

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

void setup()
{ 
 Serial.begin(9600);
 Serial1.begin(38400);

   pinMode(10, OUTPUT);

     if (!SD.begin(chipSelect)) {
   Serial.println("Card failed, or not present");

   return;
 }

 char filename[13];
 strcpy(filename, "IMAGE00.JPG");
 for (int i = 0; i < 100; i++) {
   filename[5] = '0' + i/10;
   filename[6] = '0' + i%10;

   if (! SD.exists(filename)) {
     break;
   }
 }


 imgFile = SD.open(filename, FILE_WRITE);

}

void loop() 
{    
    SendResetCmd();
    delay(3000); 

    ChangeBaudRate(); 
    SetImageSizeCmd();  
    SendResetCmd();
    delay(3000);                             

     SendTakePhotoCmd();

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

     }   
     byte a[32];

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

         delay(25);
         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))      
              EndFlag=1;                           
              j++;
      count++;
              }
         }
        imgFile.write(a,count);            //writes it to SD
       /*  for(j=0;j<count;j++)
         {   if(a[j]<0x10)
             Serial.print("0");
             Serial.print(a[j],HEX);
             Serial.print(" ");
         }    */                                   //Edited out writes it to serial Monitor
         //Serial.println();
     }

imgFile.close(); 
   Serial.println("finished");
    while(1);
}

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

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

//Read data
void SendReadDataCmd()
{
     MH=a/0x100;
     ML=a%0x100;
     Serial1.write(0x56);
     Serial1.write(0x00);
     Serial1.write(0x32);
     Serial1.write(0x0c);
     Serial1.write(0x00); 
     Serial1.write(0x0a);
     Serial1.write(0x00);
     Serial1.write(0x00);
     Serial1.write(MH);
     Serial1.write(ML);   
     Serial1.write(0x00);
     Serial1.write(0x00);
     Serial1.write(0x00);
     Serial1.write(0x20);
     Serial1.write(0x00);  
     Serial1.write(0x0a);
     a+=0x20;                           
}

void SetImageSizeCmd()
{
     Serial1.write(0x56);
     Serial1.write(0x00);
     Serial1.write(0x54);
     Serial1.write(0x01);
     Serial1.write(0x22);

}

void StopTakePhotoCmd()
{
     Serial1.write(0x56);
     Serial1.write0x00);
     Serial1.write(0x36);
     Serial1.write(0x01);
     Serial1.write(0x03);        
}
void ChangeBaudRate()
{
     Serial1.write(0x56);
     Serial1.write(0x00);
     Serial1.write(0x24);
     Serial1.write(0x03);
     Serial1.write(0x01);        
     Serial1.write(0x0X);   
     Serial1.write(0x0D);             
}

Thank you

You did wait 30mins for the transfer from the camera to the Sd card didn't you?

Mark

Ummm..... no. I didn't think it would take that long. It is supposed to be a small image 160x120.

I have now gone to this site and basically copied in this tutorial to try and get it to work.

I have changed a few things, taken out soft serial and used the hard serial on my DUE. Added in SPI.h as i am using a SD shield.

Here is the code:

#include <SD.h>
#include <SPI.h> 
 
byte ZERO = 0x00;
 
byte incomingbyte;         
 
long int a=0x0000,j=0,k=0,count=0,i=0;
uint8_t MH,ML;
boolean EndFlag=0;
 
File  myFile;
 
void SendResetCmd();
void SetBaudRateCmd();
void SetImageSizeCmd();
void SendTakePhotoCmd();
void SendReadDataCmd();
void StopTakePhotoCmd();
 
void setup()
{
 
Serial.begin(38400);
while (!Serial) {
; // wait for serial port to connect. Needed for Leonardo only
}
 
Serial1.begin(38400);
 
Serial.print("Initializing SD card...");
// On the Ethernet Shield, CS is pin 4. It's set as an output by default.
// Note that even if it's not used as the CS pin, the hardware SS pin
// (10 on most Arduino boards, 53 on the Mega) must be left as an output
// or the SD library functions will not work.
pinMode(10, OUTPUT);
 
if (!SD.begin(4)) {
Serial.println("initialization failed!");
return;
}
Serial.println("initialization done.");
 
}
 
void loop()
{
 
byte a[32];
int ii;
 
SendResetCmd();
delay(4000);                            //Wait 2-3 second to send take picture command
 
SendTakePhotoCmd();
 
while(Serial1.available()>0)
{
incomingbyte=Serial1.read();
}
 
myFile = SD.open("pic.jpg", FILE_WRITE); //<strong><span style="color: #ff0000;">The file name should not be too long</span></strong>
 
while(!EndFlag)
{
j=0;
k=0;
count=0;
SendReadDataCmd();
 
delay(20); //250 for regular
 
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))     //tell if the picture is finished
EndFlag=1;
j++;
count++;
}
}
 
for(j=0;j<count;j++)
{
if(a[j]<0x10)
Serial.print("0");
Serial.print(a[j],HEX);           // observe the image through serial port
Serial.print(" ");
}
 
for(ii=0; ii<count; ii++)
myFile.write(a[ii]);
 
Serial.println();
 
i++;
 
}
 
myFile.close();
 
Serial.print("Finished writing data to file");
 
while(1);
 
}
 
void SendResetCmd()
{
Serial1.write(0x56);
Serial1.write(ZERO);
Serial1.write(0x26);
Serial1.write(ZERO);
}
 
void SetImageSizeCmd()
{
Serial1.write(0x56);
Serial1.write(ZERO);
Serial1.write(0x31);
Serial1.write(0x05);
Serial1.write(0x04);
Serial1.write(0x01);
Serial1.write(ZERO);
Serial1.write(0x19);
Serial1.write(0x11);
}
 
void SetBaudRateCmd()
{
Serial1.write(0x56);
Serial1.write(ZERO);
Serial1.write(0x24);
Serial1.write(0x03);
Serial1.write(0x01);
Serial1.write(0x2A);
Serial1.write(0xC8);
 
}
 
void SendTakePhotoCmd()
{
Serial1.write(0x56);
Serial1.write(ZERO);
Serial1.write(0x36);
Serial1.write(0x01);
Serial1.write(ZERO);
}
 
void SendReadDataCmd()
{
MH=a/0x100;
ML=a%0x100;
Serial1.write(0x56);
Serial1.write(ZERO);
Serial1.write(0x32);
Serial1.write(0x0c);
Serial1.write(ZERO);
Serial1.write(0x0a);
Serial1.write(ZERO);
Serial1.write(ZERO);
Serial1.write(MH);
Serial1.write(ML);
Serial1.write(ZERO);
Serial1.write(ZERO);
Serial1.write(ZERO);
Serial1.write(0x20);
Serial1.write(ZERO);
Serial1.write(0x0a);
a+=0x20;
}
 
void StopTakePhotoCmd()
{
Serial1.write(0x56);
Serial1.write(ZERO);
Serial1.write(0x36);
Serial1.write(0x01);
Serial1.write(0x03);
}

This is what i get in my serial monitor:

$�
��%���)��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������$� ��%��������������������������������������������������������

On the SD card it does make a file but it is empty. I was expecting HEX in my serial monitor but all i get are these question marks? Why is this?

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

While there is data coming from the camera, read it and throw it away. Why?

byte incomingbyte;

Why is this global?

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))     //tell if the picture is finished
EndFlag=1;
j++;
count++;
}
}

Some
piss-poorly
indented
code
that
reads
photo
data
and
effectively
discards
it.
Why?

Once the array is full, you should deal with the data in the array.

Serial.begin(38400);

Is that what you have the serial monitor set to? Why? Why use an odd serial speed to talk to the PC?

Thank you for your pointers. Some of them i can't answer, i took this from a tutorial on the manufactures website, so i assumed it would work. The baud rate should be 115200, i thought that is set up later through the SetBaudRateCMD, will look into it. Not sure why there is a global.
Will have a look at the two serial.read commands and come back with an answer....

I have changed the serial baud rate to 9600 and the camera serial to 115200 as in the instruction manual for it. I have also added a delay before the while(Serial1.available()>0) command.

I now have HEX on my serial monitor (see next post).

PaulS:

byte incomingbyte;

Why is this global?

Would this make a difference if it is global or local?

PaulS:

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))     //tell if the picture is finished
EndFlag=1;
j++;
count++;
}
}



Some
piss-poorly
indented
code
that
reads
photo
data
and
effectively
discards
it.
Why?

Once the array is full, you should deal with the data in the array.

Would this need another delay before it? I'm not too sure what needs altering here?

Here is the code:

#include <SD.h>
#include <SPI.h> 
 
byte ZERO = 0x00;
 
byte incomingbyte;         
 
long int a=0x0000,j=0,k=0,count=0,i=0;
uint8_t MH,ML;
boolean EndFlag=0;
 
File  myFile;
 
void SendResetCmd();
void SetBaudRateCmd();
void SetImageSizeCmd();
void SendTakePhotoCmd();
void SendReadDataCmd();
void StopTakePhotoCmd();
 
void setup()
{
 
Serial.begin(9600);
while (!Serial) {
; // wait for serial port to connect. Needed for Leonardo only
}
 
Serial1.begin(115200);
 
Serial.print("Initializing SD card...");
// On the Ethernet Shield, CS is pin 4. It's set as an output by default.
// Note that even if it's not used as the CS pin, the hardware SS pin
// (10 on most Arduino boards, 53 on the Mega) must be left as an output
// or the SD library functions will not work.
pinMode(10, OUTPUT);
 
if (!SD.begin(4)) {
Serial.println("initialization failed!");
return;
}
Serial.println("initialization done.");
 
}
 
void loop()
{
 
byte a[32];
int ii;
 
SendResetCmd();
delay(4000);                            //Wait 2-3 second to send take picture command
 
SendTakePhotoCmd();
 
 delay(100);
 
while(Serial1.available()>0)
{
incomingbyte=Serial1.read();
}
 
myFile = SD.open("pic.jpg", FILE_WRITE); //<strong><span style="color: #ff0000;">The file name should not be too long</span></strong>
 
while(!EndFlag)
{
j=0;
k=0;
count=0;
SendReadDataCmd();
 
delay(20); //250 for regular
 
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))     //tell if the picture is finished
EndFlag=1;
j++;
count++;
}
}
 
for(j=0;j<count;j++)
{
if(a[j]<0x10)
Serial.print("0");
Serial.print(a[j],HEX);           // observe the image through serial port
Serial.print(" ");
}
 
for(ii=0; ii<count; ii++)
myFile.write(a[ii]);
 
Serial.println();
 
i++;
 
}
 
myFile.close();
 
Serial.print("Finished writing data to file");
 
while(1);
 
}
 
void SendResetCmd()
{
Serial1.write(0x56);
Serial1.write(ZERO);
Serial1.write(0x26);
Serial1.write(ZERO);
}
 
void SetImageSizeCmd()
{
Serial1.write(0x56);
Serial1.write(ZERO);
Serial1.write(0x31);
Serial1.write(0x05);
Serial1.write(0x04);
Serial1.write(0x01);
Serial1.write(ZERO);
Serial1.write(0x19);
Serial1.write(0x11);
}
 
void SetBaudRateCmd()
{
Serial1.write(0x56);
Serial1.write(ZERO);
Serial1.write(0x24);
Serial1.write(0x03);
Serial1.write(0x01);
Serial1.write(0x2A);
Serial1.write(0xC8);
 
}
 
void SendTakePhotoCmd()
{
Serial1.write(0x56);
Serial1.write(ZERO);
Serial1.write(0x36);
Serial1.write(0x01);
Serial1.write(ZERO);
}
 
void SendReadDataCmd()
{
MH=a/0x100;
ML=a%0x100;
Serial1.write(0x56);
Serial1.write(ZERO);
Serial1.write(0x32);
Serial1.write(0x0c);
Serial1.write(ZERO);
Serial1.write(0x0a);
Serial1.write(ZERO);
Serial1.write(ZERO);
Serial1.write(MH);
Serial1.write(ML);
Serial1.write(ZERO);
Serial1.write(ZERO);
Serial1.write(ZERO);
Serial1.write(0x20);
Serial1.write(ZERO);
Serial1.write(0x0a);
a+=0x20;
}
 
void StopTakePhotoCmd()
{
Serial1.write(0x56);
Serial1.write(ZERO);
Serial1.write(0x36);
Serial1.write(0x01);
Serial1.write(0x03);
}

I expected a FF D8 at the start of the image and a FF D9 at the end. I go the end bit but not the start.

This had also meant that it is only partially (12kb) on the SD card and hence won't open.

The out put of the serial monitor is too long to post so it is in an attachment...

Serial-Monitor.doc (140 KB)

I have merged my code with another on this forum which uses:

 picFile.write(a,count);

instead of

          for(j=0;j<count;j++)
          {   if(a[j]<0x10)
              Serial.print("0");
              Serial.print(a[j],HEX);
              Serial.print(" ");
          }

and it works so i guess i just have to have a look at the previous bits to understand why it doesn't work...