code for taking image and saving to SD card
Dependencies: SDFileSystem mbed
Diff: main.cpp
- Revision:
- 1:43abfc6827c6
- Parent:
- 0:c88af26224b8
- Child:
- 2:2b3a04c086da
diff -r c88af26224b8 -r 43abfc6827c6 main.cpp --- a/main.cpp Tue Mar 03 22:24:57 2015 +0000 +++ b/main.cpp Tue Mar 10 21:18:45 2015 +0000 @@ -1,186 +1,239 @@ -/* -Porting example Arduino code for camera module. +/******************************************************************************************************* +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" +#include "SDFileSystem.h" // for SD card interface +#include "stdio.h" +#include "stdlib.h" -//int csPin = 4; +Serial pc(USBTX, USBRX); // tx, rx, communicate with PC +Serial cam(D8, D2); // tx, rx, (Camera to) Nucleo +SDFileSystem sd(D11, D12, D13, D10, "sd"); // mosi, miso, sclk, cs, name -Serial mySerial(D0, D1); // Nucleo D0 is rx and D1 is tx for camera +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 -byte ZERO = 0x00; -byte incomingbyte; -long int j=0,k=0,count=0,i=0x0000; -uint8_t MH,ML; -boolean EndFlag=0; -File myFile; - +// 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() { - mySerial.printf(0x56); - mySerial.printf(ZERO); - mySerial.printf(0x26); - mySerial.printf(ZERO); + 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(byte Size) +/************************************* + 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) { - mySerial.printf(0x56); - mySerial.printf(ZERO); - mySerial.printf(0x54); - mySerial.printf(0x01); - mySerial.printf(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(byte baudrate) +/************************************* + Set BaudRate : + <1> 0xAE : 9600 + <2> 0x2A : 38400 + <3> 0x1C : 57600 + <4> 0x0D : 115200 + <5> 0xAE : 128000 + <6> 0x56 : 256000 +*************************************/ +void SetBaudRateCmd(char baudrate) { - mySerial.printf(0x56); - mySerial.printf(ZERO); - mySerial.printf(0x24); - mySerial.printf(0x03); - mySerial.printf(0x01); - mySerial.printf(baudrate); + cam.putc(0x56); + cam.putc(ZERO); + cam.putc(0x24); + cam.putc(0x03); + cam.putc(0x01); + cam.putc(baudrate); } void SendTakePhotoCmd() { - mySerial.printf(0x56); - mySerial.printf(ZERO); - mySerial.printf(0x36); - mySerial.printf(0x01); - mySerial.printf(ZERO); + cam.putc(0x56); + cam.putc(ZERO); + cam.putc(0x36); + cam.putc(0x01); + cam.putc(ZERO); } void SendReadDataCmd() { - MH=i/0x100; - ML=i%0x100; - mySerial.printf(0x56); - mySerial.printf(ZERO); - mySerial.printf(0x32); - mySerial.printf(0x0c); - mySerial.printf(ZERO); - mySerial.printf(0x0a); - mySerial.printf(ZERO); - mySerial.printf(ZERO); - mySerial.printf(MH); - mySerial.printf(ML); - mySerial.printf(ZERO); - mySerial.printf(ZERO); - mySerial.printf(ZERO); - mySerial.printf(0x20); - mySerial.printf(ZERO); - mySerial.printf(0x0a); - i+=0x20; + 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() { - mySerial.printf(0x56); - mySerial.printf(ZERO); - mySerial.printf(0x36); - mySerial.printf(0x01); - mySerial.printf(0x03); + cam.putc(0x56); + cam.putc(ZERO); + cam.putc(0x36); + cam.putc(0x01); + cam.putc(0x03); } -void setup() +int main(void) { -//pinMode(csPin, OUTPUT); -//Serial.begin(115200); -//while (!Serial) { -//; // wait for serial port to connect. Needed for Leonardo only -//} - -//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. -//if (!SD.begin(4)) { -//Serial.println("initialization failed!"); -//return; -} -//Serial.println("initialization done."); -//Serial.println("please waiting ...."); -//} - -void loop() -{ - byte a[32]; - int ii; - mySerial.begin(115200); - delay(200); + 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(115200); + wait(0.200); SendResetCmd();//Wait 2-3 second to send take picture command - delay(2000); + wait(2.000); SetBaudRateCmd(0x2A); - delay(100); - mySerial.begin(38400); - delay(100); - SetImageSizeCmd(0x21); - delay(100); + wait(0.100); + cam.baud(38400); + wait(0.100); + SetImageSizeCmd(0x00); + wait(0.100); SendTakePhotoCmd(); - delay(3000); - while(mySerial.available()>0) + wait(3); + + // Open SD card dir and file + mkdir("/sd/mydir", 0777); + FILE *fp = fopen("/sd/mydir/sdtest.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 { - incomingbyte=mySerial.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; + j=0; // reset counters (this is done 32 bytes at a time) count=0; - SendReadDataCmd(); - delay(5); - while(mySerial.available()>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 { - incomingbyte=mySerial.read(); - k++; - delayMicroseconds(100); - 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++) + 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) Serial.print("0"); - Serial.print(a[j],HEX); // observe the image through serial port - Serial.print(" "); + 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++) - myFile.write(a[ii]); - //Serial.println(); + fputc(a[ii],fp); + + read_ack();// throw away ack/response from end of read_data dat packet } - myFile.close(); - //Serial.print("Finished writing data to file"); + + fclose(fp); + pc.printf("\n\rFinished writing data to file\n\r"); while(1); + } +