code for taking image and saving to SD card

Dependencies:   SDFileSystem mbed

main.cpp

Committer:
bontr007
Date:
2015-04-12
Revision:
4:c22ccc2df5dc
Parent:
3:2f9cbbda52e8

File content as of revision 4:c22ccc2df5dc:

/*******************************************************************************************************
This code uses the LS-Y202 camera module to take an image, and save it an SD card.
The SD card is interfaced via an SD card shield.

Porting example Arduino code for camera module:
http://learn.linksprite.com/jpeg-camera/tutorial-of-using-linksprite-2mp-uart-jpeg-camera-with-arduino/
********************************************************************************************************/

#include "mbed.h"
#include "SDFileSystem.h" // for SD card interface
#include "stdio.h" 
#include "stdlib.h"

Serial pc(USBTX, USBRX); // tx, rx, communicate with PC
//Serial cam(D8, D2); // tx, rx, (Camera to) Nucleo
Serial cam(PA_11, PA_12);
//SDFileSystem sd(D11, D12, D13, D10, "sd"); // mosi, miso, sclk, cs, name
SDFileSystem sd(PB_15, PB_14, PB_13, D4, "sd");
 
uint8_t ZERO = 0x00;
uint8_t incomingbyte;
long int addr_var = 0x0000;
uint8_t MH, ML;
bool EndFlag=0;

///// UART FIFO Buffer functions ////////////////////////////////////////////////////
volatile int rx_in=0; // FIFO buffer end
volatile int rx_out=0; // FIFO buffer beginning
const int buffer_size = 255; // 
char rx_buffer[buffer_size+1]; // actual FIFO buffer
 
// Interrupt when UART recieve
void cam_Rx_interrupt() {
// Loop just in case more than one character is in UART's receive FIFO buffer
// Stop if buffer full
    while ((cam.readable()) && (((rx_in + 1) % buffer_size) != rx_out)) {
        rx_buffer[rx_in] = cam.getc();
        rx_in = (rx_in + 1) % buffer_size;
    }
    return;
}

// Read and throw away camera return (ACK) bytes
// Currently coded for five bytes,
// but may want to allow calling with an input parameter.
void read_ack() {
    char ack_bytes[7]; //
    int i = 0; // loop counter

    // wait for 5 ack bytes
    while((rx_in >= rx_out) && (rx_in - rx_out < 5) || (rx_in < rx_out) && (rx_in + buffer_size - rx_out < 5));
    
    __disable_irq(); // disable interrupt while reading to ack_bytes buffer
    
    for(i=0; i<5; i++) { // fill buffer and throw away
        ack_bytes[i] = rx_buffer[rx_out];
        rx_out = (rx_out + 1) % buffer_size; 
    }
    ack_bytes[i+1] = NULL; // add null to end for print string
    
    pc.printf("\n\rAck bytes: %s\n\r", ack_bytes);
    
    __enable_irq(); // 
    return;
}

char get_byte(){ // get a byte from UART buffer
    char p;
    while(rx_in == rx_out);// wait for byte
    __disable_irq(); // disable interrupts
    p = rx_buffer[rx_out]; // get byte
    rx_out = (rx_out + 1) % buffer_size; // update buffer start
    __enable_irq(); // enable interrrupts
    return p; // return byte
}
///////////////////////////////////////////////////////////////////////////////

// Camera Functions ///
void SendResetCmd()
{
  cam.putc(0x56);
  cam.putc(ZERO);
  cam.putc(0x26);
  cam.putc(ZERO);
}
 
/*************************************
 Set ImageSize :
 <1> 0x22 : 160*120
 <2> 0x11 : 320*240
 <3> 0x00 : 640*480
 <4> 0x1D : 800*600
 <5> 0x1C : 1024*768
 <6> 0x1B : 1280*960
 <7> 0x21 : 1600*1200
************************************/
void SetImageSizeCmd(char Size)
{
  cam.putc(0x56);
  cam.putc(ZERO);
  cam.putc(0x54);
  cam.putc(0x01);
  cam.putc(Size);
}
 
/*************************************
 Set BaudRate :
 <1> 0xAE  :   9600
 <2> 0x2A  :   38400
 <3> 0x1C  :   57600
 <4> 0x0D  :   115200
 <5> 0xAE  :   128000
 <6> 0x56  :   256000
*************************************/
void SetBaudRateCmd(char baudrateHigh, char baudrateLow)
{
  cam.putc(0x56);
  cam.putc(ZERO);
  cam.putc(0x24);
  cam.putc(0x03);
  cam.putc(0x01);
  cam.putc(baudrateHigh);
  cam.putc(baudrateLow);
}
 
void SendTakePhotoCmd()
{
  cam.putc(0x56);
  cam.putc(ZERO);
  cam.putc(0x36);
  cam.putc(0x01);
  cam.putc(ZERO);
}
 
void SendReadDataCmd()
{
  MH=addr_var/0x100;
  ML=addr_var%0x100;
  cam.putc(0x56);
  cam.putc(ZERO);
  cam.putc(0x32);
  cam.putc(0x0c);
  cam.putc(ZERO);
  cam.putc(0x0a);
  cam.putc(ZERO);
  cam.putc(ZERO);
  cam.putc(MH);
  cam.putc(ML);
  cam.putc(ZERO);
  cam.putc(ZERO);
  cam.putc(ZERO);
  cam.putc(0x20);
  cam.putc(ZERO);
  cam.putc(0x0a);
  addr_var+=0x20;
}
 
void StopTakePhotoCmd()
{
  cam.putc(0x56);
  cam.putc(ZERO);
  cam.putc(0x36);
  cam.putc(0x01);
  cam.putc(0x03);
}
 
int main(void)
{
  pc.baud(115200); // for PC terminal display/communications
  pc.printf("\n\rStarting...\n\r"); // 
  
  cam.attach(&cam_Rx_interrupt, Serial::RxIrq); // attach ISR to cam UART recieve
  
  uint8_t a[32];
  int j, count, ii;       
  cam.baud(38400);
  wait(0.200);
  SendResetCmd();//Wait 2-3 second to send take picture command
  wait(2.000);
  // baud bytes = ((27E6 / baudrate) * 16 ) - 256
  // 0x2A, 0xF2 = 38400
  // 0x1C, 0x4C = 57600
  // 0x0D, 0xA6 = 115200
  // 0x0C, 0x2F = 128000 ??? (0xAE from DS) ???
  // 0x56, 0x = 256000 ??? (0x56 from DS)
  SetBaudRateCmd(0x0D, 0xA6);
  wait(0.100);
  cam.baud(115200);
  wait(0.100);
  // 0x22 = 160*120, 0x11 = 320*240, 0x00 = 640*480, 0x1D = 800*600
  // 0x1C = 1024*768, 0x1B = 1280*960, 0x21 = 1600*1200
  SetImageSizeCmd(0x00);
  wait(0.100);
  SendTakePhotoCmd();
  wait(3);  
  
  // Open SD card dir and file
  mkdir("/sd/mydir", 0777);
  char tmp[50];
  //sprintf(
  FILE *fp = fopen("/sd/mydir/sdtest640x480.jpg", "w");
  if(fp == NULL) {
    error("\n\rCould not open file for write\n\r");
  }
  
  rx_in = rx_out; // reset FIFO
  
  while(!EndFlag) // loop until end of image data
  {
    j=0; // reset counters (this is done 32 bytes at a time)
    count=0;
    SendReadDataCmd(); // 
    read_ack(); // throw away ack/response bytes from read_data command
    while(rx_in == rx_out); // wait for data
    // data comes in 32 byte packets 
    while((count < 32)) // fill 'a' buffer one byte at a time
    {
        a[count] = get_byte();
        if((a[count-1]==0xFF)&&(a[count]==0xD9))
        {     //tell if the picture is finished
            EndFlag=1; // end of image
            count++;
            break;
        }
        count++; 
    }
    
    pc.printf("count: %d \n\r", count);
    
    // print data to PC 
    for(j=0; j<count; j++)
    {
      if(a[j]<0x10)  pc.printf("0");
      pc.printf("%x", a[j]);
      pc.printf(" ");
    }
    pc.printf("\n\r");
    
    // send data to SD card
    for(ii=0; ii<count; ii++)
      fputc(a[ii],fp);
      
    read_ack();// throw away ack/response from end of read_data dat packet
  }
 
  fclose(fp); 
  pc.printf("\n\rFinished writing data to file\n\r");
  while(1);
  
}