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