code for taking image and saving to SD card
Dependencies: SDFileSystem mbed
main.cpp@4:c22ccc2df5dc, 2015-04-12 (annotated)
- Committer:
- bontr007
- Date:
- Sun Apr 12 02:14:26 2015 +0000
- Revision:
- 4:c22ccc2df5dc
- Parent:
- 3:2f9cbbda52e8
Kevin's version with SD card and camera IO ports changed
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
bontr007 | 4:c22ccc2df5dc | 1 | /******************************************************************************************************* |
mcgoverna | 1:43abfc6827c6 | 2 | This code uses the LS-Y202 camera module to take an image, and save it an SD card. |
mcgoverna | 1:43abfc6827c6 | 3 | The SD card is interfaced via an SD card shield. |
mcgoverna | 1:43abfc6827c6 | 4 | |
mcgoverna | 1:43abfc6827c6 | 5 | Porting example Arduino code for camera module: |
mcgoverna | 0:c88af26224b8 | 6 | http://learn.linksprite.com/jpeg-camera/tutorial-of-using-linksprite-2mp-uart-jpeg-camera-with-arduino/ |
mcgoverna | 1:43abfc6827c6 | 7 | ********************************************************************************************************/ |
mcgoverna | 0:c88af26224b8 | 8 | |
mcgoverna | 0:c88af26224b8 | 9 | #include "mbed.h" |
mcgoverna | 1:43abfc6827c6 | 10 | #include "SDFileSystem.h" // for SD card interface |
mcgoverna | 1:43abfc6827c6 | 11 | #include "stdio.h" |
mcgoverna | 1:43abfc6827c6 | 12 | #include "stdlib.h" |
mcgoverna | 0:c88af26224b8 | 13 | |
mcgoverna | 1:43abfc6827c6 | 14 | Serial pc(USBTX, USBRX); // tx, rx, communicate with PC |
bontr007 | 4:c22ccc2df5dc | 15 | //Serial cam(D8, D2); // tx, rx, (Camera to) Nucleo |
bontr007 | 4:c22ccc2df5dc | 16 | Serial cam(PA_11, PA_12); |
bontr007 | 4:c22ccc2df5dc | 17 | //SDFileSystem sd(D11, D12, D13, D10, "sd"); // mosi, miso, sclk, cs, name |
bontr007 | 4:c22ccc2df5dc | 18 | SDFileSystem sd(PB_15, PB_14, PB_13, D4, "sd"); |
mcgoverna | 0:c88af26224b8 | 19 | |
mcgoverna | 1:43abfc6827c6 | 20 | uint8_t ZERO = 0x00; |
mcgoverna | 1:43abfc6827c6 | 21 | uint8_t incomingbyte; |
mcgoverna | 1:43abfc6827c6 | 22 | long int addr_var = 0x0000; |
mcgoverna | 1:43abfc6827c6 | 23 | uint8_t MH, ML; |
mcgoverna | 1:43abfc6827c6 | 24 | bool EndFlag=0; |
mcgoverna | 1:43abfc6827c6 | 25 | |
mcgoverna | 1:43abfc6827c6 | 26 | ///// UART FIFO Buffer functions //////////////////////////////////////////////////// |
mcgoverna | 1:43abfc6827c6 | 27 | volatile int rx_in=0; // FIFO buffer end |
mcgoverna | 1:43abfc6827c6 | 28 | volatile int rx_out=0; // FIFO buffer beginning |
mcgoverna | 1:43abfc6827c6 | 29 | const int buffer_size = 255; // |
mcgoverna | 1:43abfc6827c6 | 30 | char rx_buffer[buffer_size+1]; // actual FIFO buffer |
mcgoverna | 0:c88af26224b8 | 31 | |
mcgoverna | 1:43abfc6827c6 | 32 | // Interrupt when UART recieve |
mcgoverna | 1:43abfc6827c6 | 33 | void cam_Rx_interrupt() { |
mcgoverna | 1:43abfc6827c6 | 34 | // Loop just in case more than one character is in UART's receive FIFO buffer |
mcgoverna | 1:43abfc6827c6 | 35 | // Stop if buffer full |
mcgoverna | 1:43abfc6827c6 | 36 | while ((cam.readable()) && (((rx_in + 1) % buffer_size) != rx_out)) { |
mcgoverna | 1:43abfc6827c6 | 37 | rx_buffer[rx_in] = cam.getc(); |
mcgoverna | 1:43abfc6827c6 | 38 | rx_in = (rx_in + 1) % buffer_size; |
mcgoverna | 1:43abfc6827c6 | 39 | } |
mcgoverna | 1:43abfc6827c6 | 40 | return; |
mcgoverna | 1:43abfc6827c6 | 41 | } |
mcgoverna | 1:43abfc6827c6 | 42 | |
mcgoverna | 1:43abfc6827c6 | 43 | // Read and throw away camera return (ACK) bytes |
mcgoverna | 1:43abfc6827c6 | 44 | // Currently coded for five bytes, |
mcgoverna | 1:43abfc6827c6 | 45 | // but may want to allow calling with an input parameter. |
mcgoverna | 1:43abfc6827c6 | 46 | void read_ack() { |
mcgoverna | 1:43abfc6827c6 | 47 | char ack_bytes[7]; // |
mcgoverna | 1:43abfc6827c6 | 48 | int i = 0; // loop counter |
mcgoverna | 1:43abfc6827c6 | 49 | |
mcgoverna | 1:43abfc6827c6 | 50 | // wait for 5 ack bytes |
mcgoverna | 1:43abfc6827c6 | 51 | while((rx_in >= rx_out) && (rx_in - rx_out < 5) || (rx_in < rx_out) && (rx_in + buffer_size - rx_out < 5)); |
mcgoverna | 1:43abfc6827c6 | 52 | |
mcgoverna | 1:43abfc6827c6 | 53 | __disable_irq(); // disable interrupt while reading to ack_bytes buffer |
mcgoverna | 1:43abfc6827c6 | 54 | |
mcgoverna | 1:43abfc6827c6 | 55 | for(i=0; i<5; i++) { // fill buffer and throw away |
mcgoverna | 1:43abfc6827c6 | 56 | ack_bytes[i] = rx_buffer[rx_out]; |
mcgoverna | 1:43abfc6827c6 | 57 | rx_out = (rx_out + 1) % buffer_size; |
mcgoverna | 1:43abfc6827c6 | 58 | } |
mcgoverna | 1:43abfc6827c6 | 59 | ack_bytes[i+1] = NULL; // add null to end for print string |
mcgoverna | 1:43abfc6827c6 | 60 | |
mcgoverna | 1:43abfc6827c6 | 61 | pc.printf("\n\rAck bytes: %s\n\r", ack_bytes); |
mcgoverna | 1:43abfc6827c6 | 62 | |
mcgoverna | 1:43abfc6827c6 | 63 | __enable_irq(); // |
mcgoverna | 1:43abfc6827c6 | 64 | return; |
mcgoverna | 1:43abfc6827c6 | 65 | } |
mcgoverna | 1:43abfc6827c6 | 66 | |
mcgoverna | 1:43abfc6827c6 | 67 | char get_byte(){ // get a byte from UART buffer |
mcgoverna | 1:43abfc6827c6 | 68 | char p; |
mcgoverna | 1:43abfc6827c6 | 69 | while(rx_in == rx_out);// wait for byte |
mcgoverna | 1:43abfc6827c6 | 70 | __disable_irq(); // disable interrupts |
mcgoverna | 1:43abfc6827c6 | 71 | p = rx_buffer[rx_out]; // get byte |
mcgoverna | 1:43abfc6827c6 | 72 | rx_out = (rx_out + 1) % buffer_size; // update buffer start |
mcgoverna | 1:43abfc6827c6 | 73 | __enable_irq(); // enable interrrupts |
mcgoverna | 1:43abfc6827c6 | 74 | return p; // return byte |
mcgoverna | 1:43abfc6827c6 | 75 | } |
mcgoverna | 1:43abfc6827c6 | 76 | /////////////////////////////////////////////////////////////////////////////// |
mcgoverna | 1:43abfc6827c6 | 77 | |
mcgoverna | 1:43abfc6827c6 | 78 | // Camera Functions /// |
mcgoverna | 0:c88af26224b8 | 79 | void SendResetCmd() |
mcgoverna | 0:c88af26224b8 | 80 | { |
mcgoverna | 1:43abfc6827c6 | 81 | cam.putc(0x56); |
mcgoverna | 1:43abfc6827c6 | 82 | cam.putc(ZERO); |
mcgoverna | 1:43abfc6827c6 | 83 | cam.putc(0x26); |
mcgoverna | 1:43abfc6827c6 | 84 | cam.putc(ZERO); |
mcgoverna | 0:c88af26224b8 | 85 | } |
mcgoverna | 0:c88af26224b8 | 86 | |
mcgoverna | 1:43abfc6827c6 | 87 | /************************************* |
mcgoverna | 1:43abfc6827c6 | 88 | Set ImageSize : |
mcgoverna | 1:43abfc6827c6 | 89 | <1> 0x22 : 160*120 |
mcgoverna | 1:43abfc6827c6 | 90 | <2> 0x11 : 320*240 |
mcgoverna | 1:43abfc6827c6 | 91 | <3> 0x00 : 640*480 |
mcgoverna | 1:43abfc6827c6 | 92 | <4> 0x1D : 800*600 |
mcgoverna | 1:43abfc6827c6 | 93 | <5> 0x1C : 1024*768 |
mcgoverna | 1:43abfc6827c6 | 94 | <6> 0x1B : 1280*960 |
mcgoverna | 1:43abfc6827c6 | 95 | <7> 0x21 : 1600*1200 |
mcgoverna | 1:43abfc6827c6 | 96 | ************************************/ |
mcgoverna | 1:43abfc6827c6 | 97 | void SetImageSizeCmd(char Size) |
mcgoverna | 0:c88af26224b8 | 98 | { |
mcgoverna | 1:43abfc6827c6 | 99 | cam.putc(0x56); |
mcgoverna | 1:43abfc6827c6 | 100 | cam.putc(ZERO); |
mcgoverna | 1:43abfc6827c6 | 101 | cam.putc(0x54); |
mcgoverna | 1:43abfc6827c6 | 102 | cam.putc(0x01); |
mcgoverna | 1:43abfc6827c6 | 103 | cam.putc(Size); |
mcgoverna | 0:c88af26224b8 | 104 | } |
mcgoverna | 0:c88af26224b8 | 105 | |
mcgoverna | 1:43abfc6827c6 | 106 | /************************************* |
mcgoverna | 1:43abfc6827c6 | 107 | Set BaudRate : |
mcgoverna | 1:43abfc6827c6 | 108 | <1> 0xAE : 9600 |
mcgoverna | 1:43abfc6827c6 | 109 | <2> 0x2A : 38400 |
mcgoverna | 1:43abfc6827c6 | 110 | <3> 0x1C : 57600 |
mcgoverna | 1:43abfc6827c6 | 111 | <4> 0x0D : 115200 |
mcgoverna | 1:43abfc6827c6 | 112 | <5> 0xAE : 128000 |
mcgoverna | 1:43abfc6827c6 | 113 | <6> 0x56 : 256000 |
mcgoverna | 1:43abfc6827c6 | 114 | *************************************/ |
mcgoverna | 2:2b3a04c086da | 115 | void SetBaudRateCmd(char baudrateHigh, char baudrateLow) |
mcgoverna | 0:c88af26224b8 | 116 | { |
mcgoverna | 1:43abfc6827c6 | 117 | cam.putc(0x56); |
mcgoverna | 1:43abfc6827c6 | 118 | cam.putc(ZERO); |
mcgoverna | 1:43abfc6827c6 | 119 | cam.putc(0x24); |
mcgoverna | 1:43abfc6827c6 | 120 | cam.putc(0x03); |
mcgoverna | 1:43abfc6827c6 | 121 | cam.putc(0x01); |
mcgoverna | 2:2b3a04c086da | 122 | cam.putc(baudrateHigh); |
mcgoverna | 2:2b3a04c086da | 123 | cam.putc(baudrateLow); |
mcgoverna | 0:c88af26224b8 | 124 | } |
mcgoverna | 0:c88af26224b8 | 125 | |
mcgoverna | 0:c88af26224b8 | 126 | void SendTakePhotoCmd() |
mcgoverna | 0:c88af26224b8 | 127 | { |
mcgoverna | 1:43abfc6827c6 | 128 | cam.putc(0x56); |
mcgoverna | 1:43abfc6827c6 | 129 | cam.putc(ZERO); |
mcgoverna | 1:43abfc6827c6 | 130 | cam.putc(0x36); |
mcgoverna | 1:43abfc6827c6 | 131 | cam.putc(0x01); |
mcgoverna | 1:43abfc6827c6 | 132 | cam.putc(ZERO); |
mcgoverna | 0:c88af26224b8 | 133 | } |
mcgoverna | 0:c88af26224b8 | 134 | |
mcgoverna | 0:c88af26224b8 | 135 | void SendReadDataCmd() |
mcgoverna | 0:c88af26224b8 | 136 | { |
mcgoverna | 1:43abfc6827c6 | 137 | MH=addr_var/0x100; |
mcgoverna | 1:43abfc6827c6 | 138 | ML=addr_var%0x100; |
mcgoverna | 1:43abfc6827c6 | 139 | cam.putc(0x56); |
mcgoverna | 1:43abfc6827c6 | 140 | cam.putc(ZERO); |
mcgoverna | 1:43abfc6827c6 | 141 | cam.putc(0x32); |
mcgoverna | 1:43abfc6827c6 | 142 | cam.putc(0x0c); |
mcgoverna | 1:43abfc6827c6 | 143 | cam.putc(ZERO); |
mcgoverna | 1:43abfc6827c6 | 144 | cam.putc(0x0a); |
mcgoverna | 1:43abfc6827c6 | 145 | cam.putc(ZERO); |
mcgoverna | 1:43abfc6827c6 | 146 | cam.putc(ZERO); |
mcgoverna | 1:43abfc6827c6 | 147 | cam.putc(MH); |
mcgoverna | 1:43abfc6827c6 | 148 | cam.putc(ML); |
mcgoverna | 1:43abfc6827c6 | 149 | cam.putc(ZERO); |
mcgoverna | 1:43abfc6827c6 | 150 | cam.putc(ZERO); |
mcgoverna | 1:43abfc6827c6 | 151 | cam.putc(ZERO); |
mcgoverna | 1:43abfc6827c6 | 152 | cam.putc(0x20); |
mcgoverna | 1:43abfc6827c6 | 153 | cam.putc(ZERO); |
mcgoverna | 1:43abfc6827c6 | 154 | cam.putc(0x0a); |
mcgoverna | 1:43abfc6827c6 | 155 | addr_var+=0x20; |
mcgoverna | 0:c88af26224b8 | 156 | } |
mcgoverna | 0:c88af26224b8 | 157 | |
mcgoverna | 0:c88af26224b8 | 158 | void StopTakePhotoCmd() |
mcgoverna | 0:c88af26224b8 | 159 | { |
mcgoverna | 1:43abfc6827c6 | 160 | cam.putc(0x56); |
mcgoverna | 1:43abfc6827c6 | 161 | cam.putc(ZERO); |
mcgoverna | 1:43abfc6827c6 | 162 | cam.putc(0x36); |
mcgoverna | 1:43abfc6827c6 | 163 | cam.putc(0x01); |
mcgoverna | 1:43abfc6827c6 | 164 | cam.putc(0x03); |
mcgoverna | 0:c88af26224b8 | 165 | } |
mcgoverna | 0:c88af26224b8 | 166 | |
mcgoverna | 1:43abfc6827c6 | 167 | int main(void) |
mcgoverna | 0:c88af26224b8 | 168 | { |
bontr007 | 4:c22ccc2df5dc | 169 | pc.baud(115200); // for PC terminal display/communications |
mcgoverna | 1:43abfc6827c6 | 170 | pc.printf("\n\rStarting...\n\r"); // |
mcgoverna | 1:43abfc6827c6 | 171 | |
mcgoverna | 1:43abfc6827c6 | 172 | cam.attach(&cam_Rx_interrupt, Serial::RxIrq); // attach ISR to cam UART recieve |
mcgoverna | 1:43abfc6827c6 | 173 | |
mcgoverna | 1:43abfc6827c6 | 174 | uint8_t a[32]; |
mcgoverna | 1:43abfc6827c6 | 175 | int j, count, ii; |
mcgoverna | 2:2b3a04c086da | 176 | cam.baud(38400); |
mcgoverna | 1:43abfc6827c6 | 177 | wait(0.200); |
mcgoverna | 0:c88af26224b8 | 178 | SendResetCmd();//Wait 2-3 second to send take picture command |
mcgoverna | 1:43abfc6827c6 | 179 | wait(2.000); |
mcgoverna | 2:2b3a04c086da | 180 | // baud bytes = ((27E6 / baudrate) * 16 ) - 256 |
mcgoverna | 2:2b3a04c086da | 181 | // 0x2A, 0xF2 = 38400 |
mcgoverna | 2:2b3a04c086da | 182 | // 0x1C, 0x4C = 57600 |
mcgoverna | 2:2b3a04c086da | 183 | // 0x0D, 0xA6 = 115200 |
mcgoverna | 2:2b3a04c086da | 184 | // 0x0C, 0x2F = 128000 ??? (0xAE from DS) ??? |
mcgoverna | 2:2b3a04c086da | 185 | // 0x56, 0x = 256000 ??? (0x56 from DS) |
mcgoverna | 2:2b3a04c086da | 186 | SetBaudRateCmd(0x0D, 0xA6); |
mcgoverna | 1:43abfc6827c6 | 187 | wait(0.100); |
mcgoverna | 2:2b3a04c086da | 188 | cam.baud(115200); |
mcgoverna | 1:43abfc6827c6 | 189 | wait(0.100); |
mcgoverna | 2:2b3a04c086da | 190 | // 0x22 = 160*120, 0x11 = 320*240, 0x00 = 640*480, 0x1D = 800*600 |
mcgoverna | 2:2b3a04c086da | 191 | // 0x1C = 1024*768, 0x1B = 1280*960, 0x21 = 1600*1200 |
bontr007 | 4:c22ccc2df5dc | 192 | SetImageSizeCmd(0x00); |
mcgoverna | 1:43abfc6827c6 | 193 | wait(0.100); |
mcgoverna | 0:c88af26224b8 | 194 | SendTakePhotoCmd(); |
mcgoverna | 1:43abfc6827c6 | 195 | wait(3); |
mcgoverna | 1:43abfc6827c6 | 196 | |
mcgoverna | 1:43abfc6827c6 | 197 | // Open SD card dir and file |
mcgoverna | 1:43abfc6827c6 | 198 | mkdir("/sd/mydir", 0777); |
bontr007 | 4:c22ccc2df5dc | 199 | char tmp[50]; |
bontr007 | 4:c22ccc2df5dc | 200 | //sprintf( |
bontr007 | 4:c22ccc2df5dc | 201 | FILE *fp = fopen("/sd/mydir/sdtest640x480.jpg", "w"); |
mcgoverna | 1:43abfc6827c6 | 202 | if(fp == NULL) { |
mcgoverna | 1:43abfc6827c6 | 203 | error("\n\rCould not open file for write\n\r"); |
mcgoverna | 1:43abfc6827c6 | 204 | } |
mcgoverna | 1:43abfc6827c6 | 205 | |
mcgoverna | 1:43abfc6827c6 | 206 | rx_in = rx_out; // reset FIFO |
mcgoverna | 1:43abfc6827c6 | 207 | |
mcgoverna | 1:43abfc6827c6 | 208 | while(!EndFlag) // loop until end of image data |
mcgoverna | 0:c88af26224b8 | 209 | { |
mcgoverna | 1:43abfc6827c6 | 210 | j=0; // reset counters (this is done 32 bytes at a time) |
mcgoverna | 0:c88af26224b8 | 211 | count=0; |
mcgoverna | 1:43abfc6827c6 | 212 | SendReadDataCmd(); // |
mcgoverna | 1:43abfc6827c6 | 213 | read_ack(); // throw away ack/response bytes from read_data command |
mcgoverna | 1:43abfc6827c6 | 214 | while(rx_in == rx_out); // wait for data |
mcgoverna | 1:43abfc6827c6 | 215 | // data comes in 32 byte packets |
mcgoverna | 1:43abfc6827c6 | 216 | while((count < 32)) // fill 'a' buffer one byte at a time |
mcgoverna | 0:c88af26224b8 | 217 | { |
mcgoverna | 1:43abfc6827c6 | 218 | a[count] = get_byte(); |
mcgoverna | 1:43abfc6827c6 | 219 | if((a[count-1]==0xFF)&&(a[count]==0xD9)) |
mcgoverna | 1:43abfc6827c6 | 220 | { //tell if the picture is finished |
mcgoverna | 1:43abfc6827c6 | 221 | EndFlag=1; // end of image |
mcgoverna | 1:43abfc6827c6 | 222 | count++; |
mcgoverna | 1:43abfc6827c6 | 223 | break; |
mcgoverna | 1:43abfc6827c6 | 224 | } |
mcgoverna | 1:43abfc6827c6 | 225 | count++; |
mcgoverna | 1:43abfc6827c6 | 226 | } |
mcgoverna | 1:43abfc6827c6 | 227 | |
mcgoverna | 1:43abfc6827c6 | 228 | pc.printf("count: %d \n\r", count); |
mcgoverna | 1:43abfc6827c6 | 229 | |
mcgoverna | 1:43abfc6827c6 | 230 | // print data to PC |
mcgoverna | 1:43abfc6827c6 | 231 | for(j=0; j<count; j++) |
mcgoverna | 0:c88af26224b8 | 232 | { |
mcgoverna | 1:43abfc6827c6 | 233 | if(a[j]<0x10) pc.printf("0"); |
mcgoverna | 1:43abfc6827c6 | 234 | pc.printf("%x", a[j]); |
mcgoverna | 1:43abfc6827c6 | 235 | pc.printf(" "); |
mcgoverna | 0:c88af26224b8 | 236 | } |
mcgoverna | 1:43abfc6827c6 | 237 | pc.printf("\n\r"); |
mcgoverna | 1:43abfc6827c6 | 238 | |
mcgoverna | 1:43abfc6827c6 | 239 | // send data to SD card |
mcgoverna | 0:c88af26224b8 | 240 | for(ii=0; ii<count; ii++) |
mcgoverna | 1:43abfc6827c6 | 241 | fputc(a[ii],fp); |
mcgoverna | 1:43abfc6827c6 | 242 | |
mcgoverna | 1:43abfc6827c6 | 243 | read_ack();// throw away ack/response from end of read_data dat packet |
mcgoverna | 0:c88af26224b8 | 244 | } |
mcgoverna | 1:43abfc6827c6 | 245 | |
mcgoverna | 1:43abfc6827c6 | 246 | fclose(fp); |
mcgoverna | 1:43abfc6827c6 | 247 | pc.printf("\n\rFinished writing data to file\n\r"); |
mcgoverna | 0:c88af26224b8 | 248 | while(1); |
mcgoverna | 1:43abfc6827c6 | 249 | |
mcgoverna | 0:c88af26224b8 | 250 | } |
mcgoverna | 1:43abfc6827c6 | 251 |