mbed serial interface for the OV528 camera (uCAM TTL 120 from 4D systems).
Dependents: mbed_uCAM_TTL120_20141118
Library for interfacing the mbed to the OV528 jpeg engine camera from Omnivision. I tested this program using the uCAM TTL 120 from 4D systems, now obsolete.
Above is a saved jpeg image from the camera at 480x640 resolution
Camera and TFT screen setup
Closeup of the TFT screen displaying a 60x80 pixel 16 bit color bitmap image. The RGB (565) pixel colors were reversed when read from the camera relative to the TFT screen so a bit mask and shift had to be applied when displaying the pixel color.
bit mask and shift
int k=12; for(int i=0;i<60;i++){ for(int j=0;j<80;j++){ //returned 16-bit color is 565(RGB) pixel_col = (imageData[k] << 8); k++; pixel_col += imageData[k]; k++; // fputc(((picture[k] >> 8) & 0xff), fp); //write pixel high byte to file // fputc(picture[k] & 0xff, fp); //write low byte //swap R and B bits in returned pixel for TFT display int TFT_pix_col = 0; TFT_pix_col += (pixel_col & 0x001f) << 11; TFT_pix_col += (pixel_col & 0xf800) >> 11; TFT_pix_col += (pixel_col & 0x07e0); TFT.pixel(j, i, TFT_pix_col); //Do something with the pixel } }
Diff: uCAM_TTL120.cpp
- Revision:
- 2:f80257456c6e
- Parent:
- 0:fcc0eaeeb35c
- Child:
- 3:85db6ea8c0a4
--- a/uCAM_TTL120.cpp Tue Nov 18 17:55:06 2014 +0000 +++ b/uCAM_TTL120.cpp Tue Nov 18 20:26:06 2014 +0000 @@ -12,25 +12,6 @@ timerCam->start(); } -/* -int uCAM_TTL120::uCAM_read(char *str, int numchars, float timeout){ - int i = 0; - - float t_stop = timerCam->read()+timeout; - - while(i < numchars){ - if(_cam.readable()){ - str[i] = _cam.getc(); - i++; - } - if(timerCam->read() > t_stop) - return i; - } - - return i; -} -*/ - int uCAM_TTL120::uCAM_read(char *str, int numchars, float timeout){ int i = 0; float t_start = timerCam->read(); @@ -61,24 +42,24 @@ _cam.putc(p4); } -int uCAM_TTL120::uCAM_GetACK(void) +int uCAM_TTL120::uCAM_GetACK(int command) { char ser_read[7]; - int i; + int i; - for(i=0;i<7;i++) //clear the string + for(i=0;i<7;i++) //clear the string ser_read[i] = 0; - wait(.2); + wait(.1); - //read serial buffer and wait for ACK (0xAA0E0DXX0000) - uCAM_read(ser_read, 6, .1); - if((ser_read[0] == 0xAA) && - (ser_read[1] == 0x0E)) - { + //read serial buffer and wait for ACK (0xAA0E0DXX0000) + uCAM_read(ser_read, 6, .1); + if((ser_read[0] == 0xAA) && + (ser_read[1] == 0x0E)){ + if((command & 0xff) == ser_read[2]) return 1; - } - else + } + else return 0; } @@ -109,7 +90,8 @@ (ser_read[4] == 0x00)) { //after receiving ACK, wait for SYNC (0xAA0D00000000) - uCAM_read(ser_read, 6, 100); + uCAM_read(ser_read, 6, .100); + if((ser_read[0] == 0xAA) && (ser_read[1] == 0x0D) && (ser_read[2] == 0x00) && @@ -121,7 +103,7 @@ uCAM_Command_Send(uCAM_ACK,0x0D,0x00,0x00,0x00); printf("\r\n uCAM 120 Initialized\r\nDelaying 2 seconds for AGC and AEC \r\n circuits to stabilise before image capture."); - wait(.5); //2 second delay before capturing first image +/* wait(.5); //2 second delay before capturing first image printf("."); wait(.5); printf("."); @@ -129,7 +111,7 @@ printf("."); wait(.5); printf(".\r\nFinished\r\n"); - +*/ return 1; //Camera connection successful } } @@ -218,14 +200,14 @@ } int uCAM_TTL120::uCAM_send_SNAPSHOT(void) { - uCAM_Command_Send(uCAM_SNAPSHOT,0x01,0x00,0x00,0x00); // p1=0x01-Uncompressed Image - // p2 and p3 = 0, current frame - wait(.05); + uCAM_Command_Send(uCAM_SNAPSHOT,0x01,0x00,0x00,0x00); // p1=0x01-Uncompressed Image + // p2 and p3 = 0, current frame + wait(.05); - if(uCAM_GetACK()) + if(uCAM_GetACK(uCAM_SNAPSHOT)) return 1; - else - return 0; + else + return 0; } int uCAM_TTL120::uCAM_send_GET_PICTURE_80x60_16COL_RAW(void) @@ -514,10 +496,19 @@ void uCAM_TTL120::uCAM_set_baud(void) { - /*uCAM_Command_Send(uCAM_SET_BAUD_RATE,0x03,0x00,0x00,0x00); // set baud to - serCopen(921600);*/ - uCAM_Command_Send(uCAM_SET_BAUD_RATE,0x02,0x00,0x00,0x00); // set baud to - _cam.baud(1228800); + uCAM_Command_Send(uCAM_SET_BAUD_RATE,0x03,0x00,0x00,0x00); // set baud to + wait(.05); + + if(uCAM_GetACK(uCAM_SET_BAUD_RATE)){ + printf("Baud rate sucessfully changed"); + } + else{ + printf("Baud rate NOT sucessfully changed"); + } + + _cam.baud(921600); +// uCAM_Command_Send(uCAM_SET_BAUD_RATE,0x02,0x00,0x00,0x00); // set baud to +// _cam.baud(1228800); } void uCAM_TTL120::uCAM_TakePic_RAW_16COLOR_80x60(void) @@ -561,3 +552,121 @@ char c = _cam.getc(); } } + +int uCAM_TTL120::uCAM_get_jpeg(FILE *fileName){ + + char ser_read[7]; + unsigned long pic_bytes; + + uCAM_FlushBuffer(); + uCAM_Command_Send(uCAM_INITIAL,0x00,0x07,0x07,0x07); // JPEG,640 x 480,JPEG + //cam.uCAM_Command_Send(uCAM_INITIAL,0x00,0x07,0x07,0x03); // JPEG,160 x 120,JPEG + wait(.05); + + if(uCAM_GetACK(uCAM_INITIAL)){ //INITIAL ACK + printf("ACK received on uCAM_INITIAL\r\n"); + } + else{ + printf("Did not receive ACK on uCAM_INITIAL\r\n"); + } + + uCAM_FlushBuffer(); + uCAM_Command_Send(uCAM_SET_PACKAGE_SIZE,0x08,0x00,0x02,0x00); //512 bytes + + wait(.05); + + if(uCAM_GetACK(uCAM_SET_PACKAGE_SIZE)){ //SET PACKAGE SIZE ACK + printf("ACK received on uCAM_SET_PACKAGE_SIZE\r\n"); + } + else{ + printf("Did not receive ACK on SET PACKAGE SIZE\r\n"); + } + + uCAM_FlushBuffer(); + uCAM_Command_Send(uCAM_SNAPSHOT,0x00,0x00,0x00,0x00); //JPEG + + if(uCAM_GetACK(uCAM_SNAPSHOT)){ //uCAM_SNAPSHOT ACK + printf("ACK received on uCAM_SNAPSHOT\r\n"); + } + else{ + printf("Did not receive ACK on uCAM_SNAPSHOT\r\n"); + } + + pic_bytes = 0; + + uCAM_FlushBuffer(); + uCAM_Command_Send(uCAM_GET_PICTURE,0x01,0x00,0x00,0x00); // p1=0x01-Snapshot picture + wait(.1); + + if(uCAM_GetACK(uCAM_GET_PICTURE)) //returned get pic + { + //read serial buffer and wait for ACK (0xAA0E0DXX0000) + uCAM_read(ser_read, 6, 1); + + if((ser_read[0] == 0xAA) && //first 2 bytes indicate it was a DATA packet + (ser_read[1] == 0x0A) && + (ser_read[2] == 0x01)) //DATA from snapshot ACK + { + pic_bytes = (unsigned long)ser_read[3]; + pic_bytes += (unsigned long)ser_read[4] << 8; + pic_bytes += (unsigned long)ser_read[5] << 16; + + int packID=0; + char packID_l, packID_h; + + // pc.printf("\r\n"); + int numPackages = pic_bytes / (512 - 6); + + while(numPackages>=0){ + packID_h = (packID >> 8) & 0xff; + packID_l = packID & 0xff; + + uCAM_FlushBuffer(); + uCAM_Command_Send(uCAM_ACK, 0x00, 0x00, packID_l, packID_h); + + char ID_ret[2]; + uCAM_read(ID_ret, 2, .2); + + char dataSize[2]; + uCAM_read(dataSize, 2, .2); + + char imageData[506]; //512 - 6 + int imageDataSize = ((dataSize[1] & 0xff) << 8) + (dataSize[0] & 0xff); + + //uCAM_read(imageData, imageDataSize, .2); + for(int i=0;i<imageDataSize;i++) + imageData[i] = _cam.getc(); + + char verifyCode[2]; + uCAM_read(verifyCode, 2, .2); + + int vCodeCheck=0; + vCodeCheck += ID_ret[0]; + vCodeCheck += ID_ret[1]; + vCodeCheck += dataSize[0]; + vCodeCheck += dataSize[1]; + + for(int i=0;i<imageDataSize;i++) + vCodeCheck += imageData[i]; + + if((verifyCode[0] & 0xff) == (vCodeCheck & 0xff)){ + //pc.printf("\r\nPack ID = %d\r\n", packID);//debugging + for(int j=0;j<imageDataSize;j++){ + fputc(imageData[j], fileName); + //pc.printf("%2X ", imageData[j]); + } + + packID++; + numPackages--; + } + else{ + printf("\r\nBad Data in transfer. ReTransfer\r\n"); + return -2; + } + } + uCAM_Command_Send(uCAM_ACK, 0x00, 0x00, 0xf0, 0xf0); + return 0; //return 0 on success + } + }//data packet + return -1; +} //function