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 } }
uCAM_TTL120.cpp
- Committer:
- jebradshaw
- Date:
- 2014-11-17
- Revision:
- 0:fcc0eaeeb35c
- Child:
- 2:f80257456c6e
File content as of revision 0:fcc0eaeeb35c:
// Library for uCAM-TTL120 from Saelig #include "uCAM_TTL120.h" #define __DEBUG //----------------- uCAM Functions ------------------------------ uCAM_TTL120::uCAM_TTL120(PinName tx, PinName rx) : _cam(tx, rx) { _cam.baud(115200); //Initial baud rate timerCam = new Timer(); 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(); while((timerCam->read() < (t_start + timeout)) && (i < numchars)){ if(_cam.readable()){ str[i] = _cam.getc(); i++; } } if(timerCam->read() >= (t_start + timeout)){ return -1; } if(i >= numchars){ return -2; } return i; } void uCAM_TTL120::uCAM_Command_Send(int command,char p1,char p2,char p3,char p4) { _cam.putc((char)(command >> 8) & 0xff); _cam.putc((char)(command & 0xff)); _cam.putc(p1); _cam.putc(p2); _cam.putc(p3); _cam.putc(p4); } int uCAM_TTL120::uCAM_GetACK(void) { char ser_read[7]; int i; for(i=0;i<7;i++) //clear the string ser_read[i] = 0; wait(.2); //read serial buffer and wait for ACK (0xAA0E0DXX0000) uCAM_read(ser_read, 6, .1); if((ser_read[0] == 0xAA) && (ser_read[1] == 0x0E)) { return 1; } else return 0; } int uCAM_TTL120::uCAM_Connect(void) { char ser_read[20]; int i, retries; for(i=0;i<20;i++) //clear the string ser_read[i] = 0; retries=0; while(retries < 60) { uCAM_FlushBuffer(); //Transmit SYNC command uCAM_Command_Send(uCAM_SYNC,0x00,0x00,0x00,0x00); wait(.2); //read serial buffer and wait for ACK (0xAA0E0DXX0000) uCAM_read(ser_read, 6, .01); if((ser_read[0] == 0xAA) && (ser_read[1] == 0x0E) && (ser_read[2] == 0x0D) && //skip ser_read[3] (ser_read[4] == 0x00)) { //after receiving ACK, wait for SYNC (0xAA0D00000000) uCAM_read(ser_read, 6, 100); if((ser_read[0] == 0xAA) && (ser_read[1] == 0x0D) && (ser_read[2] == 0x00) && (ser_read[3] == 0x00) && (ser_read[4] == 0x00) && (ser_read[5] == 0x00)) { //Transmit ACK command 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 printf("."); wait(.5); printf("."); wait(.5); printf("."); wait(.5); printf(".\r\nFinished\r\n"); return 1; //Camera connection successful } } retries++; } if(retries == 60) return 0; return -1; } int uCAM_TTL120::uCAM_send_INITIAL_80x60_16RAW(void) { char ser_read[7]; int i; uCAM_Command_Send(uCAM_INITIAL,0x00,0x06,0x01,0x00); // p2=0x06-16 bit color(RAW,565(RGB)) // p3=0x01-80 x 60 bit resolution // p4=0x01-JPEG res 80 x 64 wait(.02); for(i=0;i<7;i++) //clear the string ser_read[i] = 0; //read serial C buffer and wait for ACK (0xAA0E0DXX0000) uCAM_read(ser_read, 6, 100); if((ser_read[0] == 0xAA) && (ser_read[1] == 0x0E) && (ser_read[2] == 0x01)){ return 1; } else return 0; } int uCAM_TTL120::uCAM_send_INITIAL_80x60_2RAW(void) { char ser_read[7]; int i; uCAM_Command_Send(uCAM_INITIAL,0x00,0x01,0x01,0x00); // p2=0x01-2 bit GRAY (RAW) // p3=0x01-80 x 60 bit resolution // p4=0x01-JPEG res 80 x 64 wait(.02); for(i=0;i<7;i++) //clear the string ser_read[i] = 0; //read serial C buffer and wait for ACK (0xAA0E0DXX0000) uCAM_read(ser_read, 6, .1); if((ser_read[0] == 0xAA) && (ser_read[1] == 0x0E) && (ser_read[2] == 0x01)) { wait(.050); return 1; } else return 0; } int uCAM_TTL120::uCAM_send_INITIAL_128x128_4RAW(void) { char ser_read[7]; int i; uCAM_Command_Send(uCAM_INITIAL,0x00,0x02,0x09,0x00); // p2=0x02-4 bit GRAY (RAW) // p3=0x09- 128x128 bit resolution // p4=0x01-JPEG res 80 x 64 wait(.02); for(i=0;i<7;i++) //clear the string ser_read[i] = 0; //read serial buffer and wait for ACK (0xAA0E0DXX0000) uCAM_read(ser_read, 6, 100); if((ser_read[0] == 0xAA) && (ser_read[1] == 0x0E) && (ser_read[2] == 0x01)) { wait(.05); return 1; } else return 0; } 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); if(uCAM_GetACK()) return 1; else return 0; } int uCAM_TTL120::uCAM_send_GET_PICTURE_80x60_16COL_RAW(void) { char ser_read[7]; char c; unsigned long pic_bytes; unsigned int i, j, k; unsigned int serbytes_read; unsigned int pixel_col; pic_bytes = 0; c=0; serbytes_read = 0; for(i=0;i<100;i++) picture[i] = 0; while(_cam.readable()){ //flush the buffer char c = _cam.getc(); } uCAM_Command_Send(uCAM_GET_PICTURE,0x01,0x00,0x00,0x00); // p1=0x01-Snapshot picture wait(.3); //read serial C buffer and wait for ACK (0xAA0E0DXX0000) c=uCAM_read(ser_read, 6, 1); wait(.3); if(c==6) //received 6 bytes back { if((ser_read[0] == 0xAA) && //first 2 bytes indicate it was a DATA packet (ser_read[1] == 0x0E) && (ser_read[2] == 0x04)) //returned get pic { //read serial C buffer and wait for ACK (0xAA0E0DXX0000) c=uCAM_read(ser_read, 6, 1); if(c==6) //received 6 bytes back { if((ser_read[0] == 0xAA) && //first 2 bytes indicate it was a DATA packet (ser_read[1] == 0x0A)) { pic_bytes = (unsigned long)ser_read[3]; pic_bytes += (unsigned long)ser_read[4] << 8; pic_bytes += (unsigned long)ser_read[5] << 16; serbytes_read = uCAM_read(picture, pic_bytes, .200); if(serbytes_read == pic_bytes) { k=0; for(i=0;i<60;i++) { for(j=0;j<80;j++) { pixel_col = picture[k]; k++; // printf("%d ", pixel_col); // uLCD144_Put_Pixel(j, i, pixel_col); //Do something with the pixel } } uCAM_Command_Send(uCAM_ACK, 0x0A, 0x00, 0x01, 0x00); return pic_bytes; } else return -4; } else return -3; } } else return -2; } return -1; } int uCAM_TTL120::uCAM_send_GET_PICTURE_80x60_2GRAY_RAW(void) { char ser_read[7]; char c; unsigned long pic_bytes; unsigned int pixel_col; unsigned int i, j, k; int m; unsigned int serbytes_read; int temp; pic_bytes = 0; c=0; serbytes_read = 0; for(i=0;i<100;i++) picture[i] = 0; while(_cam.readable()){ //flush the buffer char c = _cam.getc(); } uCAM_Command_Send(uCAM_GET_PICTURE,0x01,0x00,0x00,0x00); // p1=0x01-Snapshot picture wait(.3); //read serial C buffer and wait for ACK (0xAA0E0DXX0000) c=uCAM_read(ser_read, 6, 1); wait(.2); if(c==6) //received 6 bytes back { if((ser_read[0] == 0xAA) && //first 2 bytes indicate it was a DATA packet (ser_read[1] == 0x0E) && (ser_read[2] == 0x04)) //returned get pic { //read serial C buffer and wait for ACK (0xAA0E0DXX0000) c=uCAM_read(ser_read, 6, 1); if(c==6) //received 6 bytes back { if((ser_read[0] == 0xAA) && //first 2 bytes indicate it was a DATA packet (ser_read[1] == 0x0A)) { pic_bytes = (unsigned long)ser_read[3]; pic_bytes += (unsigned long)ser_read[4] << 8; pic_bytes += (unsigned long)ser_read[5] << 16; serbytes_read = uCAM_read(picture, pic_bytes, 200); if(serbytes_read == pic_bytes) { k=0; for(i=0;i<60;i++) { for(j=0;j<80;) { temp = picture[k]; for(m=14;m>=0;m-=2) { pixel_col = (temp >> m) & 0x03; switch(pixel_col) { case 0: // uLCD144_Put_Pixel(j, i, 0x0000); //0x0000 break; case 1: // uLCD144_Put_Pixel(j, i, 0x0180); //0x39e7 break; case 2: // uLCD144_Put_Pixel(j, i, 0xc209); //0x7bef break; case 3: // uLCD144_Put_Pixel(j, i, 0xFFFF); //0xFFFF break; default: // uLCD144_Put_Pixel(j, i, 0x0000); break; } j++; } k++; } } uCAM_Command_Send(uCAM_ACK, 0x0A, 0x00, 0x01, 0x00); return pic_bytes; } else return -4; } else return -3; } } else return -2; } return -1; } int uCAM_TTL120::uCAM_send_GET_PICTURE_128x128_4GRAY_RAW(void) { char ser_read[7]; char c; unsigned long pic_bytes; unsigned int pixel_col; unsigned int i, j, k; unsigned int serbytes_read; int temp; pic_bytes = 0; c=0; serbytes_read = 0; for(i=0;i<100;i++) picture[i] = 0; while(_cam.readable()){ //flush the buffer char c = _cam.getc(); } uCAM_Command_Send(uCAM_GET_PICTURE,0x01,0x00,0x00,0x00); // p1=0x01-Snapshot picture wait(.3); //read serial C buffer and wait for ACK (0xAA0E0DXX0000) c=uCAM_read(ser_read, 6, 1); wait(.2); if(c==6) //received 6 bytes back { if((ser_read[0] == 0xAA) && //first 2 bytes indicate it was a DATA packet (ser_read[1] == 0x0E) && (ser_read[2] == 0x04)) //returned get pic { //read serial C buffer and wait for ACK (0xAA0E0DXX0000) c=uCAM_read(ser_read, 6, 1); if(c==6) //received 6 bytes back { if((ser_read[0] == 0xAA) && //first 2 bytes indicate it was a DATA packet (ser_read[1] == 0x0A)) { pic_bytes = (unsigned long)ser_read[3]; pic_bytes += (unsigned long)ser_read[4] << 8; pic_bytes += (unsigned long)ser_read[5] << 16; serbytes_read = uCAM_read(picture, pic_bytes, .2); if(serbytes_read == pic_bytes) { k=0; for(i=0;i<128;i++) { for(j=0;j<128;) { temp = picture[k]; pixel_col = (temp >> 12) & 0x000F; pixel_col |= ((temp >> 12) & 0x000F) << 6; pixel_col |= ((temp >> 12) & 0x000F) << 11; // uLCD144_Put_Pixel(j, i, pixel_col); printf("%c", pixel_col); j++; pixel_col = (temp >> 8) & 0x000F; pixel_col |= ((temp >> 8) & 0x000F) << 6; pixel_col |= ((temp >> 8) & 0x000F) << 11; // uLCD144_Put_Pixel(j, i, pixel_col); printf("%c", pixel_col); j++; pixel_col = (temp >> 4) & 0x000F; pixel_col |= ((temp >> 4) & 0x000F) << 6; pixel_col |= ((temp >> 4) & 0x000F) << 11; // uLCD144_Put_Pixel(j, i, pixel_col); printf("%c", pixel_col); j++; pixel_col = temp & 0x000F; pixel_col |= (temp & 0x000F) << 6; pixel_col |= (temp & 0x000F) << 11; // uLCD144_Put_Pixel(j, i, pixel_col); printf("%c", pixel_col); j++; k++; } } uCAM_Command_Send(uCAM_ACK, 0x0A, 0x00, 0x01, 0x00); return pic_bytes; } else return -4; } else return -3; } } else return -2; } return -1; } 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); } void uCAM_TTL120::uCAM_TakePic_RAW_16COLOR_80x60(void) { uCAM_send_INITIAL_80x60_16RAW(); wait(.1); uCAM_send_SNAPSHOT(); wait(.1); uCAM_send_GET_PICTURE_80x60_16COL_RAW(); } void uCAM_TTL120::uCAM_TakePic_RAW_2GRAY_80x60(void) { uCAM_send_INITIAL_80x60_2RAW(); wait(.1); uCAM_send_SNAPSHOT(); wait(.1); while(uCAM_send_GET_PICTURE_80x60_2GRAY_RAW() < 0){ wait(.1); uCAM_send_SNAPSHOT(); wait(.2); } } void uCAM_TTL120::uCAM_TakePic_RAW_4GRAY_128x128(void) { uCAM_send_INITIAL_128x128_4RAW(); wait(.100); uCAM_send_SNAPSHOT(); wait(.100); while(uCAM_send_GET_PICTURE_128x128_4GRAY_RAW() < 0){ wait(.100); uCAM_send_SNAPSHOT(); wait(.200); } } void uCAM_TTL120::uCAM_FlushBuffer(void){ while(_cam.readable()){ //flush the buffer char c = _cam.getc(); } }