code for taking image and saving to SD card

Dependencies:   SDFileSystem mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 /*******************************************************************************************************
00002 This code uses the LS-Y202 camera module to take an image, and save it an SD card.
00003 The SD card is interfaced via an SD card shield.
00004 
00005 Porting example Arduino code for camera module:
00006 http://learn.linksprite.com/jpeg-camera/tutorial-of-using-linksprite-2mp-uart-jpeg-camera-with-arduino/
00007 ********************************************************************************************************/
00008 
00009 #include "mbed.h"
00010 #include "SDFileSystem.h" // for SD card interface
00011 #include "stdio.h" 
00012 #include "stdlib.h"
00013 
00014 Serial pc(USBTX, USBRX); // tx, rx, communicate with PC
00015 //Serial cam(D8, D2); // tx, rx, (Camera to) Nucleo
00016 Serial cam(PA_11, PA_12);
00017 //SDFileSystem sd(D11, D12, D13, D10, "sd"); // mosi, miso, sclk, cs, name
00018 SDFileSystem sd(PB_15, PB_14, PB_13, D4, "sd");
00019  
00020 uint8_t ZERO = 0x00;
00021 uint8_t incomingbyte;
00022 long int addr_var = 0x0000;
00023 uint8_t MH, ML;
00024 bool EndFlag=0;
00025 
00026 ///// UART FIFO Buffer functions ////////////////////////////////////////////////////
00027 volatile int rx_in=0; // FIFO buffer end
00028 volatile int rx_out=0; // FIFO buffer beginning
00029 const int buffer_size = 255; // 
00030 char rx_buffer[buffer_size+1]; // actual FIFO buffer
00031  
00032 // Interrupt when UART recieve
00033 void cam_Rx_interrupt() {
00034 // Loop just in case more than one character is in UART's receive FIFO buffer
00035 // Stop if buffer full
00036     while ((cam.readable()) && (((rx_in + 1) % buffer_size) != rx_out)) {
00037         rx_buffer[rx_in] = cam.getc();
00038         rx_in = (rx_in + 1) % buffer_size;
00039     }
00040     return;
00041 }
00042 
00043 // Read and throw away camera return (ACK) bytes
00044 // Currently coded for five bytes,
00045 // but may want to allow calling with an input parameter.
00046 void read_ack() {
00047     char ack_bytes[7]; //
00048     int i = 0; // loop counter
00049 
00050     // wait for 5 ack bytes
00051     while((rx_in >= rx_out) && (rx_in - rx_out < 5) || (rx_in < rx_out) && (rx_in + buffer_size - rx_out < 5));
00052     
00053     __disable_irq(); // disable interrupt while reading to ack_bytes buffer
00054     
00055     for(i=0; i<5; i++) { // fill buffer and throw away
00056         ack_bytes[i] = rx_buffer[rx_out];
00057         rx_out = (rx_out + 1) % buffer_size; 
00058     }
00059     ack_bytes[i+1] = NULL; // add null to end for print string
00060     
00061     pc.printf("\n\rAck bytes: %s\n\r", ack_bytes);
00062     
00063     __enable_irq(); // 
00064     return;
00065 }
00066 
00067 char get_byte(){ // get a byte from UART buffer
00068     char p;
00069     while(rx_in == rx_out);// wait for byte
00070     __disable_irq(); // disable interrupts
00071     p = rx_buffer[rx_out]; // get byte
00072     rx_out = (rx_out + 1) % buffer_size; // update buffer start
00073     __enable_irq(); // enable interrrupts
00074     return p; // return byte
00075 }
00076 ///////////////////////////////////////////////////////////////////////////////
00077 
00078 // Camera Functions ///
00079 void SendResetCmd()
00080 {
00081   cam.putc(0x56);
00082   cam.putc(ZERO);
00083   cam.putc(0x26);
00084   cam.putc(ZERO);
00085 }
00086  
00087 /*************************************
00088  Set ImageSize :
00089  <1> 0x22 : 160*120
00090  <2> 0x11 : 320*240
00091  <3> 0x00 : 640*480
00092  <4> 0x1D : 800*600
00093  <5> 0x1C : 1024*768
00094  <6> 0x1B : 1280*960
00095  <7> 0x21 : 1600*1200
00096 ************************************/
00097 void SetImageSizeCmd(char Size)
00098 {
00099   cam.putc(0x56);
00100   cam.putc(ZERO);
00101   cam.putc(0x54);
00102   cam.putc(0x01);
00103   cam.putc(Size);
00104 }
00105  
00106 /*************************************
00107  Set BaudRate :
00108  <1> 0xAE  :   9600
00109  <2> 0x2A  :   38400
00110  <3> 0x1C  :   57600
00111  <4> 0x0D  :   115200
00112  <5> 0xAE  :   128000
00113  <6> 0x56  :   256000
00114 *************************************/
00115 void SetBaudRateCmd(char baudrateHigh, char baudrateLow)
00116 {
00117   cam.putc(0x56);
00118   cam.putc(ZERO);
00119   cam.putc(0x24);
00120   cam.putc(0x03);
00121   cam.putc(0x01);
00122   cam.putc(baudrateHigh);
00123   cam.putc(baudrateLow);
00124 }
00125  
00126 void SendTakePhotoCmd()
00127 {
00128   cam.putc(0x56);
00129   cam.putc(ZERO);
00130   cam.putc(0x36);
00131   cam.putc(0x01);
00132   cam.putc(ZERO);
00133 }
00134  
00135 void SendReadDataCmd()
00136 {
00137   MH=addr_var/0x100;
00138   ML=addr_var%0x100;
00139   cam.putc(0x56);
00140   cam.putc(ZERO);
00141   cam.putc(0x32);
00142   cam.putc(0x0c);
00143   cam.putc(ZERO);
00144   cam.putc(0x0a);
00145   cam.putc(ZERO);
00146   cam.putc(ZERO);
00147   cam.putc(MH);
00148   cam.putc(ML);
00149   cam.putc(ZERO);
00150   cam.putc(ZERO);
00151   cam.putc(ZERO);
00152   cam.putc(0x20);
00153   cam.putc(ZERO);
00154   cam.putc(0x0a);
00155   addr_var+=0x20;
00156 }
00157  
00158 void StopTakePhotoCmd()
00159 {
00160   cam.putc(0x56);
00161   cam.putc(ZERO);
00162   cam.putc(0x36);
00163   cam.putc(0x01);
00164   cam.putc(0x03);
00165 }
00166  
00167 int main(void)
00168 {
00169   pc.baud(115200); // for PC terminal display/communications
00170   pc.printf("\n\rStarting...\n\r"); // 
00171   
00172   cam.attach(&cam_Rx_interrupt, Serial::RxIrq); // attach ISR to cam UART recieve
00173   
00174   uint8_t a[32];
00175   int j, count, ii;       
00176   cam.baud(38400);
00177   wait(0.200);
00178   SendResetCmd();//Wait 2-3 second to send take picture command
00179   wait(2.000);
00180   // baud bytes = ((27E6 / baudrate) * 16 ) - 256
00181   // 0x2A, 0xF2 = 38400
00182   // 0x1C, 0x4C = 57600
00183   // 0x0D, 0xA6 = 115200
00184   // 0x0C, 0x2F = 128000 ??? (0xAE from DS) ???
00185   // 0x56, 0x = 256000 ??? (0x56 from DS)
00186   SetBaudRateCmd(0x0D, 0xA6);
00187   wait(0.100);
00188   cam.baud(115200);
00189   wait(0.100);
00190   // 0x22 = 160*120, 0x11 = 320*240, 0x00 = 640*480, 0x1D = 800*600
00191   // 0x1C = 1024*768, 0x1B = 1280*960, 0x21 = 1600*1200
00192   SetImageSizeCmd(0x00);
00193   wait(0.100);
00194   SendTakePhotoCmd();
00195   wait(3);  
00196   
00197   // Open SD card dir and file
00198   mkdir("/sd/mydir", 0777);
00199   char tmp[50];
00200   //sprintf(
00201   FILE *fp = fopen("/sd/mydir/sdtest640x480.jpg", "w");
00202   if(fp == NULL) {
00203     error("\n\rCould not open file for write\n\r");
00204   }
00205   
00206   rx_in = rx_out; // reset FIFO
00207   
00208   while(!EndFlag) // loop until end of image data
00209   {
00210     j=0; // reset counters (this is done 32 bytes at a time)
00211     count=0;
00212     SendReadDataCmd(); // 
00213     read_ack(); // throw away ack/response bytes from read_data command
00214     while(rx_in == rx_out); // wait for data
00215     // data comes in 32 byte packets 
00216     while((count < 32)) // fill 'a' buffer one byte at a time
00217     {
00218         a[count] = get_byte();
00219         if((a[count-1]==0xFF)&&(a[count]==0xD9))
00220         {     //tell if the picture is finished
00221             EndFlag=1; // end of image
00222             count++;
00223             break;
00224         }
00225         count++; 
00226     }
00227     
00228     pc.printf("count: %d \n\r", count);
00229     
00230     // print data to PC 
00231     for(j=0; j<count; j++)
00232     {
00233       if(a[j]<0x10)  pc.printf("0");
00234       pc.printf("%x", a[j]);
00235       pc.printf(" ");
00236     }
00237     pc.printf("\n\r");
00238     
00239     // send data to SD card
00240     for(ii=0; ii<count; ii++)
00241       fputc(a[ii],fp);
00242       
00243     read_ack();// throw away ack/response from end of read_data dat packet
00244   }
00245  
00246   fclose(fp); 
00247   pc.printf("\n\rFinished writing data to file\n\r");
00248   while(1);
00249   
00250 }
00251