A Simple library to capture pictures from the uCam by 4D Systems
Embed:
(wiki syntax)
Show/hide line numbers
uCam.cpp
00001 #include "uCam.h" 00002 #include "mbed.h" 00003 00004 #define DEBUG 00005 00006 // Set up some memory to hold the commands 00007 const unsigned char SYNC[] = {0xAA, 0x0D, 0x00, 0x00, 0x00, 0x00}; 00008 const unsigned char ACK[] = {0xAA, 0x0E, 0x0D, 0x00, 0x00, 0x00}; 00009 const unsigned char BAUD_115200[] = {0xAA, 0x07, 0x01, 0x0F, 0x00, 0x00}; 00010 const unsigned char BAUD_737280[] = {0xAA, 0x07, 0x00, 0x04, 0x00, 0x00}; 00011 const unsigned char BAUD_921600[] = {0xAA, 0x07, 0x01, 0x01, 0x00, 0x00}; 00012 const unsigned char BAUD_1228800[] = {0xAA, 0x07, 0x02, 0x00, 0x00, 0x00}; 00013 const unsigned char GET_PICTURE[] = {0xAA, 0x04, 0x02, 0x00, 0x00, 0x00}; // take snapshot picture 00014 00015 int picture_size; // To track the current picture size 00016 DigitalOut led1(LED1),led2(LED2),led3(LED3),led4(LED4); 00017 00018 uCam::uCam(PinName tx, PinName rx, int buffer) 00019 : _uCam(tx,rx,buffer) { 00020 00021 // Set the initial baud rate 00022 _uCam.baud(115200); 00023 } 00024 00025 // Waits for an response from the uCam module and checks that a valid ACK was received 00026 int uCam::Get_Response(unsigned char type, unsigned char command) { 00027 // First wait for the uCam module to send the reply or timeout 00028 // This waits for the module to become readable or timesout after 50 ms 00029 char times = 0; // Variable to check for timeouts 00030 do { 00031 wait(0.001); // Wait 1 ms 00032 times++; // Inc variable 00033 if (_uCam.readable()) 00034 break; 00035 } while (times < 100 ); 00036 // Check if it timed out 00037 if (times > 99) { 00038 printf("\n\r Response Timeout"); 00039 return(0); 00040 } 00041 // Get the reply from the uCam module (will be 6 bytes 00042 unsigned char reply[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; 00043 for (int i=0; i<6; i++) { 00044 reply[i] = _uCam.getc(); 00045 } 00046 // Check reply was valid, A valid ACK should be 0xAA, 0x0E, Command ID, X, 0x00, 0x00 00047 if (reply[0] == 0xAA && reply[1] == type && reply[2] == command && reply[4] == 0x00 && reply[5] == 0x00) 00048 // It was an ACK so return true 00049 return(1); 00050 else { 00051 // Reply was invalid so print the reply and return false 00052 return(0); 00053 } 00054 } 00055 00056 int uCam::Sync() { 00057 // This will give 60 attempts to sync with the uCam module 00058 for (int i=0; i<=10; i ++) { 00059 // Send out the sync command 00060 for (int i=0; i<6; i++) { 00061 _uCam.putc(SYNC[i]); 00062 } 00063 // Check if the response was an ACK 00064 if (Get_Response(_ACK,SYNC[1])) { 00065 // It was an ACK so now get the next response - it should be a sync 00066 if (Get_Response(_SYNC,0x00)) { 00067 // We need a small delay (1ms) from receiving the SYNC response and sending an ACK in return 00068 wait(0.001); 00069 for (int i=0; i<6; i++) { 00070 _uCam.putc(ACK[i]); 00071 } 00072 // Everything is now complete so return true 00073 return(1); 00074 } 00075 } 00076 // Wait a while and try again 00077 wait(0.01); 00078 printf("\n\r Sync failed - trying again"); 00079 } 00080 // Something went wrong so return false 00081 return(0); 00082 } 00083 00084 int uCam::SetBaud(int baud) { 00085 // Send out the set baud command 00086 for (int i=0; i<6; i++) { 00087 // Select the correct data for the desired baud 00088 if (baud == 115200) 00089 _uCam.putc(BAUD_115200[i]); 00090 else if (baud == 737280) 00091 _uCam.putc(BAUD_737280[i]); 00092 else if (baud == 921600) 00093 _uCam.putc(BAUD_921600[i]); 00094 else if (baud == 1228800) 00095 _uCam.putc(BAUD_1228800[i]); 00096 } 00097 00098 // Check if the response was an ACK 00099 if (Get_Response(_ACK,0x07)) { 00100 // An ACk was received so we can now set the mbed to the new baud rate 00101 _uCam.baud(baud); 00102 // New baud rate confirmed - return true 00103 return(1); 00104 } else 00105 // Something went wrong - return false 00106 return(0); 00107 } 00108 00109 int uCam::Initial(unsigned char COLOUR, unsigned char RES) { 00110 // Set up a buffer to hold the uCam response 00111 unsigned char buf[6] = {0xAA, 0x01, 0x00, COLOUR, 0x00, 0x00}; 00112 00113 //Amend the initial command for the type of image 00114 if (buf[3]==0x07) { 00115 buf[5] = RES; // The image is a JPEG so set byte 5 00116 } else { 00117 buf[4] = RES; // The image is RAW so set byte 4 00118 } 00119 00120 // Get the number of bytes to be transferred 00121 // Start by finding out how many bytes per pixel 00122 if (COLOUR == GREY_8BIT || COLOUR == COLOUR_8BIT) { 00123 picture_size = 1; 00124 } else if (COLOUR == COLOUR_16BIT) { 00125 picture_size = 2; 00126 } 00127 // Then multiply this by the number of pixels 00128 if (RES == RAW_80x60) 00129 picture_size = picture_size*80*60; 00130 else if (RES == RAW_160x120) 00131 picture_size = picture_size*160*120; 00132 else if (RES == RAW_320x240) 00133 picture_size = picture_size*320*240; 00134 else if (RES == RAW_640x480) 00135 picture_size = picture_size*640*480; 00136 else if (RES == RAW_128x128) 00137 picture_size = picture_size*128*128; 00138 else if (RES == RAW_128x96) 00139 picture_size = picture_size*128*96; 00140 00141 // Send out the initial command 00142 for (int i=0; i<6; i++) { 00143 _uCam.putc(buf[i]); 00144 } 00145 00146 // Check for ACK 00147 if (Get_Response(_ACK,0x01)) { 00148 // An ACk was received - return true 00149 return(1); 00150 } else { 00151 // Something went wrong - return false 00152 return(0); 00153 } 00154 } 00155 00156 int uCam::Get_Picture(unsigned char *data) { 00157 00158 // Send out the get picture command 00159 for (int i=0; i<6; i++) { 00160 _uCam.putc(GET_PICTURE[i]); 00161 } 00162 00163 if (!Get_Response(_ACK,0x04)) 00164 // Something went wrong 00165 return(0); 00166 00167 // Get response from uCam 00168 for (int i=0; i<picture_size; i++) { 00169 if (_uCam.readable()) 00170 data[i] = _uCam.getc(); 00171 else { 00172 i--; 00173 } 00174 } 00175 00176 // We need a small delay (1ms) from receiving the SYNC response and sending an ACK in return 00177 wait(0.001); 00178 for (int i=0; i<6; i++) { 00179 _uCam.putc(ACK[i]); 00180 } 00181 // Everything is now complete so return true 00182 return(1); 00183 } 00184 00185 int uCam::Save_Picture_To_Memory(FeRAM &flash, int address) { 00186 // Variables 00187 unsigned char buf[6]; // Buffer to save data from uCam before its written to flash 00188 int length; // The length of the incoing data (sent in data packet from uCam) 00189 char binned = 0; // Escape variable to break out of function if some data isn't sent from uCam 00190 Timer bin; // Timer to see if uCam has hung 00191 00192 Timer t; 00193 t.start(); 00194 00195 // Send out the get picture command 00196 for (int i=0; i<6; i++) { 00197 _uCam.putc(GET_PICTURE[i]); 00198 } 00199 00200 if (!Get_Response(_ACK,0x04)) 00201 // Something went wrong 00202 return(0); 00203 #ifdef DEBUG 00204 printf("\n Getting picture"); 00205 #endif 00206 // Get the first 6 bytes 00207 // Format 0xAA 0x0A (Data command), Data type, 3 bytes to show length 00208 for (int i=0; i<6; i++) { 00209 while (!_uCam.readable()) { 00210 wait_us(1); 00211 } 00212 buf[i] = _uCam.getc(); // Get a byte of data 00213 } 00214 length = (buf[5] << 16) + (buf[4] << 8) + buf[3]; 00215 00216 // Get response from uCam and save to flash 00217 bin.start(); 00218 for (int i=0; i<length; i++) { 00219 #ifdef DEBUG 00220 // See where we are... 00221 if (i>length/4) 00222 led1 = 1; 00223 if (i>length/2) 00224 led2 = 1; 00225 if (i>length*3/4) 00226 led3 = 1; 00227 #endif 00228 // reset the timer 00229 bin.reset(); 00230 00231 while (!_uCam.readable()) { 00232 #ifdef DEBUG 00233 led4 = 1; // Turn LED on to show we're waiting 00234 #endif 00235 // Check to see if we have been waiting for more than 10 ms 00236 if (bin.read() > 0.01) { 00237 printf("\n binned at %d",i); 00238 binned = 1; 00239 break; 00240 } 00241 } 00242 #ifdef DEBUG 00243 led4 = 0; // Turn LED off again 00244 #endif 00245 00246 // If this if statement runs than it means the uCam module has hung 00247 if (binned) { 00248 for (; i<length; i++) { 00249 flash.write_byte(i + address, 0x00); // Fill the remaining bytes with 0x00 00250 } 00251 break; // This breaks out of the loop and writes an ACk back to uCam 00252 } 00253 00254 // uCam has a byte of data ready to read - so go get it! 00255 flash.write_byte(i + address, _uCam.getc()); 00256 00257 } 00258 // All data has been received so send an ACK back to the uCam module 00259 _uCam.putc(0xAA); 00260 _uCam.putc(0x0E); 00261 _uCam.putc(0x0A); 00262 _uCam.putc(0x00); 00263 _uCam.putc(0x01); 00264 _uCam.putc(0x00); 00265 00266 #ifdef DEBUG 00267 t.stop(); 00268 //printf("\n Finished in %.3f Secs",t.read()); 00269 00270 // Turn all the LEDs off 00271 led1 = led2 = led3 = led4 = 0; 00272 #endif 00273 00274 // Everything is now complete so return true 00275 return(1); 00276 } 00277 00278 int uCam::Save_Zoom_Picture_To_Memory(FeRAM &flash, int address){ 00279 // Variables 00280 unsigned char buf[6]; // Buffer to save data from uCam before its written to flash 00281 unsigned char dummy; // Byte to read in unwanted info 00282 int length; // The length of the incoing data (sent in data packet from uCam) 00283 int pos = 0; 00284 char binned = 0; // Escape variable to break out of function if some data isn't sent from uCam 00285 Timer bin; // Timer to see if uCam has hung 00286 00287 Timer t; 00288 t.start(); 00289 00290 // Send out the get picture command 00291 #ifdef DEBUG 00292 printf("\n\n\n\n\n\n\n\n\n\n"); 00293 #endif 00294 for (int i=0; i<6; i++) { 00295 _uCam.putc(GET_PICTURE[i]); 00296 #ifdef DEBUG 00297 printf("[%X],",GET_PICTURE[i]); 00298 #endif 00299 } 00300 00301 if (!Get_Response(_ACK,0x04)) 00302 // Something went wrong 00303 return(0); 00304 #ifdef DEBUG 00305 printf("\n Getting picture \n"); 00306 #endif 00307 // Get the first 6 bytes 00308 // Format 0xAA 0x0A (Data command), Data type, 3 bytes to show length 00309 for (int i=0; i<6; i++) { 00310 while (!_uCam.readable()) { 00311 wait_us(1); 00312 } 00313 buf[i] = _uCam.getc(); // Get a byte of data 00314 printf("[%2X],",buf[i]); 00315 } 00316 length = (buf[5] << 16) + (buf[4] << 8) + buf[3]; 00317 #ifdef DEBUG 00318 printf("\n Length is: %d \n[%d] [%d] [%d]",length, buf[5], buf[4], buf[3]); 00319 #endif 00320 00321 // Get response from uCam and save to flash 00322 bin.start(); 00323 for (int i=0; i<length; i++) { 00324 #ifdef DEBUG 00325 // See where we are... 00326 if (i>length/4) 00327 led1 = 1; 00328 if (i>length/2) 00329 led2 = 1; 00330 if (i>length*3/4) 00331 led3 = 1; 00332 #endif 00333 // reset the timer 00334 bin.reset(); 00335 00336 while (!_uCam.readable()) { 00337 #ifdef DEBUG 00338 led4 = 1; // Turn LED on to show we're waiting 00339 #endif 00340 // Check to see if we have been waiting for more than 10 ms 00341 if (bin.read() > 0.01) { 00342 printf("\n binned at %d",i); 00343 binned = 1; 00344 break; 00345 } 00346 } 00347 #ifdef DEBUG 00348 led4 = 0; // Turn LED off again 00349 #endif 00350 00351 // If this if statement runs than it means the uCam module has hung 00352 if (binned) { 00353 for (; i<length; i++) { 00354 flash.write_byte(i + address, 0x00); // Fill the remaining bytes with 0x00 00355 } 00356 break; // This breaks out of the loop and writes an ACk back to uCam 00357 } 00358 00359 // uCam has a byte of data ready to read - so go get it! 00360 // Need to check here if I actually want it! 00361 if (i < 320 * 60 * 2 || i > 320 * 180 * 2) // Pixel is too high or low 00362 dummy = _uCam.getc(); 00363 else if (i % 640 < 160) // Pixel is too left 00364 dummy = _uCam.getc(); 00365 else if (i % 640 < 160 + 320){ // Pixel is in the centre - go get it! 00366 flash.write_byte(pos + address, _uCam.getc()); 00367 pos++; 00368 } else // Pixel is too right 00369 dummy = _uCam.getc(); 00370 00371 00372 } 00373 // All data has been received so send an ACK back to the uCam module 00374 _uCam.putc(0xAA); 00375 _uCam.putc(0x0E); 00376 _uCam.putc(0x0A); 00377 _uCam.putc(0x00); 00378 _uCam.putc(0x01); 00379 _uCam.putc(0x00); 00380 00381 #ifdef DEBUG 00382 t.stop(); 00383 //printf("\n Finished in %.3f Secs",t.read()); 00384 00385 // Turn all the LEDs off 00386 led1 = led2 = led3 = led4 = 0; 00387 #endif 00388 00389 // Everything is now complete so return true 00390 return(1); 00391 }
Generated on Fri Jul 15 2022 20:20:56 by 1.7.2