mbed serial interface for the OV528 camera (uCAM TTL 120 from 4D systems).

Dependencies:   MODSERIAL

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.

/media/uploads/jebradshaw/pic0003.jpg

Above is a saved jpeg image from the camera at 480x640 resolution

/media/uploads/jebradshaw/fullsizerender.jpg

Camera and TFT screen setup

/media/uploads/jebradshaw/tft_closeup_60x80.jpg

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
                }
             }
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