A Simple library to capture pictures from the uCam by 4D Systems
uCam.cpp
- Committer:
- ms523
- Date:
- 2012-05-29
- Revision:
- 0:68395cd065e4
File content as of revision 0:68395cd065e4:
#include "uCam.h" #include "mbed.h" #define DEBUG // Set up some memory to hold the commands const unsigned char SYNC[] = {0xAA, 0x0D, 0x00, 0x00, 0x00, 0x00}; const unsigned char ACK[] = {0xAA, 0x0E, 0x0D, 0x00, 0x00, 0x00}; const unsigned char BAUD_115200[] = {0xAA, 0x07, 0x01, 0x0F, 0x00, 0x00}; const unsigned char BAUD_737280[] = {0xAA, 0x07, 0x00, 0x04, 0x00, 0x00}; const unsigned char BAUD_921600[] = {0xAA, 0x07, 0x01, 0x01, 0x00, 0x00}; const unsigned char BAUD_1228800[] = {0xAA, 0x07, 0x02, 0x00, 0x00, 0x00}; const unsigned char GET_PICTURE[] = {0xAA, 0x04, 0x02, 0x00, 0x00, 0x00}; // take snapshot picture int picture_size; // To track the current picture size DigitalOut led1(LED1),led2(LED2),led3(LED3),led4(LED4); uCam::uCam(PinName tx, PinName rx, int buffer) : _uCam(tx,rx,buffer) { // Set the initial baud rate _uCam.baud(115200); } // Waits for an response from the uCam module and checks that a valid ACK was received int uCam::Get_Response(unsigned char type, unsigned char command) { // First wait for the uCam module to send the reply or timeout // This waits for the module to become readable or timesout after 50 ms char times = 0; // Variable to check for timeouts do { wait(0.001); // Wait 1 ms times++; // Inc variable if (_uCam.readable()) break; } while (times < 100 ); // Check if it timed out if (times > 99) { printf("\n\r Response Timeout"); return(0); } // Get the reply from the uCam module (will be 6 bytes unsigned char reply[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; for (int i=0; i<6; i++) { reply[i] = _uCam.getc(); } // Check reply was valid, A valid ACK should be 0xAA, 0x0E, Command ID, X, 0x00, 0x00 if (reply[0] == 0xAA && reply[1] == type && reply[2] == command && reply[4] == 0x00 && reply[5] == 0x00) // It was an ACK so return true return(1); else { // Reply was invalid so print the reply and return false return(0); } } int uCam::Sync() { // This will give 60 attempts to sync with the uCam module for (int i=0; i<=10; i ++) { // Send out the sync command for (int i=0; i<6; i++) { _uCam.putc(SYNC[i]); } // Check if the response was an ACK if (Get_Response(_ACK,SYNC[1])) { // It was an ACK so now get the next response - it should be a sync if (Get_Response(_SYNC,0x00)) { // We need a small delay (1ms) from receiving the SYNC response and sending an ACK in return wait(0.001); for (int i=0; i<6; i++) { _uCam.putc(ACK[i]); } // Everything is now complete so return true return(1); } } // Wait a while and try again wait(0.01); printf("\n\r Sync failed - trying again"); } // Something went wrong so return false return(0); } int uCam::SetBaud(int baud) { // Send out the set baud command for (int i=0; i<6; i++) { // Select the correct data for the desired baud if (baud == 115200) _uCam.putc(BAUD_115200[i]); else if (baud == 737280) _uCam.putc(BAUD_737280[i]); else if (baud == 921600) _uCam.putc(BAUD_921600[i]); else if (baud == 1228800) _uCam.putc(BAUD_1228800[i]); } // Check if the response was an ACK if (Get_Response(_ACK,0x07)) { // An ACk was received so we can now set the mbed to the new baud rate _uCam.baud(baud); // New baud rate confirmed - return true return(1); } else // Something went wrong - return false return(0); } int uCam::Initial(unsigned char COLOUR, unsigned char RES) { // Set up a buffer to hold the uCam response unsigned char buf[6] = {0xAA, 0x01, 0x00, COLOUR, 0x00, 0x00}; //Amend the initial command for the type of image if (buf[3]==0x07) { buf[5] = RES; // The image is a JPEG so set byte 5 } else { buf[4] = RES; // The image is RAW so set byte 4 } // Get the number of bytes to be transferred // Start by finding out how many bytes per pixel if (COLOUR == GREY_8BIT || COLOUR == COLOUR_8BIT) { picture_size = 1; } else if (COLOUR == COLOUR_16BIT) { picture_size = 2; } // Then multiply this by the number of pixels if (RES == RAW_80x60) picture_size = picture_size*80*60; else if (RES == RAW_160x120) picture_size = picture_size*160*120; else if (RES == RAW_320x240) picture_size = picture_size*320*240; else if (RES == RAW_640x480) picture_size = picture_size*640*480; else if (RES == RAW_128x128) picture_size = picture_size*128*128; else if (RES == RAW_128x96) picture_size = picture_size*128*96; // Send out the initial command for (int i=0; i<6; i++) { _uCam.putc(buf[i]); } // Check for ACK if (Get_Response(_ACK,0x01)) { // An ACk was received - return true return(1); } else { // Something went wrong - return false return(0); } } int uCam::Get_Picture(unsigned char *data) { // Send out the get picture command for (int i=0; i<6; i++) { _uCam.putc(GET_PICTURE[i]); } if (!Get_Response(_ACK,0x04)) // Something went wrong return(0); // Get response from uCam for (int i=0; i<picture_size; i++) { if (_uCam.readable()) data[i] = _uCam.getc(); else { i--; } } // We need a small delay (1ms) from receiving the SYNC response and sending an ACK in return wait(0.001); for (int i=0; i<6; i++) { _uCam.putc(ACK[i]); } // Everything is now complete so return true return(1); } int uCam::Save_Picture_To_Memory(FeRAM &flash, int address) { // Variables unsigned char buf[6]; // Buffer to save data from uCam before its written to flash int length; // The length of the incoing data (sent in data packet from uCam) char binned = 0; // Escape variable to break out of function if some data isn't sent from uCam Timer bin; // Timer to see if uCam has hung Timer t; t.start(); // Send out the get picture command for (int i=0; i<6; i++) { _uCam.putc(GET_PICTURE[i]); } if (!Get_Response(_ACK,0x04)) // Something went wrong return(0); #ifdef DEBUG printf("\n Getting picture"); #endif // Get the first 6 bytes // Format 0xAA 0x0A (Data command), Data type, 3 bytes to show length for (int i=0; i<6; i++) { while (!_uCam.readable()) { wait_us(1); } buf[i] = _uCam.getc(); // Get a byte of data } length = (buf[5] << 16) + (buf[4] << 8) + buf[3]; // Get response from uCam and save to flash bin.start(); for (int i=0; i<length; i++) { #ifdef DEBUG // See where we are... if (i>length/4) led1 = 1; if (i>length/2) led2 = 1; if (i>length*3/4) led3 = 1; #endif // reset the timer bin.reset(); while (!_uCam.readable()) { #ifdef DEBUG led4 = 1; // Turn LED on to show we're waiting #endif // Check to see if we have been waiting for more than 10 ms if (bin.read() > 0.01) { printf("\n binned at %d",i); binned = 1; break; } } #ifdef DEBUG led4 = 0; // Turn LED off again #endif // If this if statement runs than it means the uCam module has hung if (binned) { for (; i<length; i++) { flash.write_byte(i + address, 0x00); // Fill the remaining bytes with 0x00 } break; // This breaks out of the loop and writes an ACk back to uCam } // uCam has a byte of data ready to read - so go get it! flash.write_byte(i + address, _uCam.getc()); } // All data has been received so send an ACK back to the uCam module _uCam.putc(0xAA); _uCam.putc(0x0E); _uCam.putc(0x0A); _uCam.putc(0x00); _uCam.putc(0x01); _uCam.putc(0x00); #ifdef DEBUG t.stop(); //printf("\n Finished in %.3f Secs",t.read()); // Turn all the LEDs off led1 = led2 = led3 = led4 = 0; #endif // Everything is now complete so return true return(1); } int uCam::Save_Zoom_Picture_To_Memory(FeRAM &flash, int address){ // Variables unsigned char buf[6]; // Buffer to save data from uCam before its written to flash unsigned char dummy; // Byte to read in unwanted info int length; // The length of the incoing data (sent in data packet from uCam) int pos = 0; char binned = 0; // Escape variable to break out of function if some data isn't sent from uCam Timer bin; // Timer to see if uCam has hung Timer t; t.start(); // Send out the get picture command #ifdef DEBUG printf("\n\n\n\n\n\n\n\n\n\n"); #endif for (int i=0; i<6; i++) { _uCam.putc(GET_PICTURE[i]); #ifdef DEBUG printf("[%X],",GET_PICTURE[i]); #endif } if (!Get_Response(_ACK,0x04)) // Something went wrong return(0); #ifdef DEBUG printf("\n Getting picture \n"); #endif // Get the first 6 bytes // Format 0xAA 0x0A (Data command), Data type, 3 bytes to show length for (int i=0; i<6; i++) { while (!_uCam.readable()) { wait_us(1); } buf[i] = _uCam.getc(); // Get a byte of data printf("[%2X],",buf[i]); } length = (buf[5] << 16) + (buf[4] << 8) + buf[3]; #ifdef DEBUG printf("\n Length is: %d \n[%d] [%d] [%d]",length, buf[5], buf[4], buf[3]); #endif // Get response from uCam and save to flash bin.start(); for (int i=0; i<length; i++) { #ifdef DEBUG // See where we are... if (i>length/4) led1 = 1; if (i>length/2) led2 = 1; if (i>length*3/4) led3 = 1; #endif // reset the timer bin.reset(); while (!_uCam.readable()) { #ifdef DEBUG led4 = 1; // Turn LED on to show we're waiting #endif // Check to see if we have been waiting for more than 10 ms if (bin.read() > 0.01) { printf("\n binned at %d",i); binned = 1; break; } } #ifdef DEBUG led4 = 0; // Turn LED off again #endif // If this if statement runs than it means the uCam module has hung if (binned) { for (; i<length; i++) { flash.write_byte(i + address, 0x00); // Fill the remaining bytes with 0x00 } break; // This breaks out of the loop and writes an ACk back to uCam } // uCam has a byte of data ready to read - so go get it! // Need to check here if I actually want it! if (i < 320 * 60 * 2 || i > 320 * 180 * 2) // Pixel is too high or low dummy = _uCam.getc(); else if (i % 640 < 160) // Pixel is too left dummy = _uCam.getc(); else if (i % 640 < 160 + 320){ // Pixel is in the centre - go get it! flash.write_byte(pos + address, _uCam.getc()); pos++; } else // Pixel is too right dummy = _uCam.getc(); } // All data has been received so send an ACK back to the uCam module _uCam.putc(0xAA); _uCam.putc(0x0E); _uCam.putc(0x0A); _uCam.putc(0x00); _uCam.putc(0x01); _uCam.putc(0x00); #ifdef DEBUG t.stop(); //printf("\n Finished in %.3f Secs",t.read()); // Turn all the LEDs off led1 = led2 = led3 = led4 = 0; #endif // Everything is now complete so return true return(1); }