A Simple library to capture pictures from the uCam by 4D Systems

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers uCam.cpp Source File

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 }