This is an digital video camera program using NKK\'s oLED swtich and 4D Systems\' uCam serial camera. It takes image from the uCam and displays on the IS-C15 switch. Some image processing demos are included. This program uses FatFileSytem, SDFileSystem, and TextLCD library. See http://www.youtube.com/watch?v=fqHTaCRHyQs for how it works. CQ出版社の「mbed/ARM活用事例」第10章シリアル接続カメラと有機ELディスプレイ内蔵スイッチで作るmbedディジタル・カメラの作例です。動作の様子は http://www.youtube.com/watch?v=fqHTaCRHyQs で見れます。

Dependencies:   TextLCD mbed SDFileSystem

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers ucam.cpp Source File

ucam.cpp

00001 /* 4D Systems uCam serial RAW/JPEG camera library
00002  * Copyright (c) 2011, Noriaki Mitsunaga
00003  *
00004  * Permission is hereby granted, free of charge, to any person obtaining a copy
00005  * of this software and associated documentation files (the "Software"), to deal
00006  * in the Software without restriction, including without limitation the rights
00007  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
00008  * copies of the Software, and to permit persons to whom the Software is
00009  * furnished to do so, subject to the following conditions:
00010  *
00011  * The above copyright notice and this permission notice shall be included in
00012  * all copies or substantial portions of the Software.
00013  *
00014  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00015  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00016  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
00017  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00018  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00019  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
00020  * THE SOFTWARE.
00021  */
00022 #include "mbed.h"
00023 #include "ucam.h"
00024 
00025 // uCam-TTL commands:
00026 const unsigned char ACK[] = {0xaa, 0x0e, 0x0d, 0, 0, 0};
00027 const unsigned char ACK1[] = {0xaa, 0x0e, 0x0d, 0, 1, 0};
00028 const unsigned char ACK_F0F0_[] = {0xaa, 0x0e, 0, 0, 0xf0, 0xf0};
00029 const unsigned char GETPICTURE_SNAPSHOT[] = {0xaa, 0x04, 0x01, 0, 0, 0};
00030 // const unsigned char GETPICTURE_RAWPREVIEW[] = {0xaa, 0x04, 0x02, 0, 0, 0};
00031 const unsigned char RESET[] = {0xaa, 0x08, 0x01, 0x0, 0x0, 0xff};
00032 const unsigned char SNAPSHOT_JPEG[] = {0xaa, 0x05, 0x00, 1, 0, 0};
00033 const unsigned char SNAPSHOT_RAW[] = {0xaa, 0x05, 0x01, 1, 0, 0};
00034 const unsigned char SYNC[] = {0xaa, 0x0d, 0, 0, 0, 0};
00035 
00036 // Send special ACK
00037 void uCam::ACK_F0F0() {
00038     write(ACK_F0F0_, sizeof(ACK_F0F0_));
00039 }
00040 
00041 // Check if buf is valid ACK.
00042 int uCam::checkACK(const unsigned char *buf) {
00043     if (buf[0] == ACK[0] && buf[1] == ACK[1] && buf[2] == ACK[2]
00044             && buf[4] == 0 && buf[5] == 0)
00045         return 1;
00046 
00047     return 0;
00048 }
00049 
00050 // Compare buf to SYNC
00051 int uCam::checkSYNC(const unsigned char *buf) {
00052     if (memcmp(buf, SYNC, sizeof(SYNC)) == 0)
00053         return 1;
00054 
00055     return 0;
00056 }
00057 
00058 // Send a command to uCam via the serial
00059 int uCam::Command(const unsigned char *cmd) {
00060     // Send the command
00061     write(cmd, 6);
00062 
00063     // Wait for response
00064     unsigned char buf[6];
00065     read(buf, 6);
00066 
00067     // Check ACK
00068     if (buf[0] == 0xaa && buf[1] == 0x0e
00069             && buf[2] == cmd[1]
00070             /* ignore fourth byte */
00071             && buf[4] == 0 && buf[5] == 0)
00072         return 1;
00073 
00074     return 0;
00075 }
00076 
00077 // Initialize communcation to uCam
00078 int uCam::Init() {
00079     int i;
00080     unsigned char buf[12];
00081 
00082     for (i=0; i<60; i ++) {
00083         // Send SYNC and check the answer
00084         write(SYNC, sizeof(SYNC));
00085         if (readT(buf, sizeof(buf)) == 12 && checkACK(buf)) {
00086             break;
00087         }
00088     }
00089     if (i == 60)      // Too many retries
00090         return 0;
00091 
00092     // Check SYNC
00093     if (!checkSYNC(buf+6)) {
00094         return 0;
00095     }
00096     write(ACK, sizeof(ACK));
00097     return 1;
00098 }
00099 
00100 // Set light frequencey (50Hz or 60Hz) to reduce flicker.
00101 int uCam::LightFreq(int f) {
00102     unsigned char LIGHT[] = {0xaa, 0x13, 0, 0, 0, 0};
00103 
00104     if (f == 50)
00105         LIGHT[2] = 0x0;
00106     else if (f == 60)
00107         LIGHT[2] = 0x1;
00108     else
00109         return 0;
00110 
00111     return Command(LIGHT);
00112 }
00113 
00114 // Recive data from serial. It blocks until it recieves len bytes.
00115 // buf: recieving buffer
00116 // len: length to recieve
00117 void uCam::read(unsigned char *p, int len) {
00118     for (; len>0; len--, p++) {
00119         *p = s->getc();
00120     }
00121 }
00122 
00123 // Recive data from serial with timeout
00124 // buf: recieving buffer
00125 // len: length of the buffer
00126 int uCam::readT(unsigned char *buf, int len) {
00127     int c = 0;
00128     unsigned char *q = buf;
00129 
00130     for (int j=0; j<2000; j ++) {
00131         if (s->readable()) {
00132             *q = s->getc();
00133             if (c < len) {
00134                 q ++;
00135                 c ++;
00136             }
00137         }
00138         wait_us(50);
00139     }
00140 
00141     return c;
00142 }
00143 
00144 // Reset uCam
00145 void uCam::Reset() {
00146     Command(RESET);
00147 }
00148 
00149 // Recieve a JPEG image packet. You need to call SnapshotJPEGi() before.
00150 // no: packet number (starts from 0)
00151 // buf: recieving buffer
00152 // pksz: packet size to recieve
00153 int uCam::SnapshotJPEGd(int no, unsigned char *buf, int pksz) {
00154     unsigned char ACK_[] = {0xaa, 0x0e, 0x00, 0, 0, 0};
00155 
00156     ACK_[4] = no & 0xff;
00157     ACK_[5] = (no >> 8) & 0xff;
00158 
00159     write(ACK_, sizeof(ACK_));
00160     read(buf, pksz);
00161 
00162     return 1;
00163 }
00164 
00165 // Prepare to recieve a JPEG image.
00166 // Res: resolution of the image (did not work well for 640x480 with uCam-TTL(ov528 version))
00167 // pksz: packet size to recieve
00168 int uCam::SnapshotJPEGi(int Res, int pksz) {
00169     unsigned char INITIAL[] = {0xaa, 0x01, 0x00, 0x07, 0x01, 0x00};
00170     unsigned char SET_PACKAGESIZE[] = {0xaa, 0x06, 0x08, 0x00, 0x00, 0x00};
00171     unsigned char buf[6];
00172 
00173     INITIAL[5] = Res;
00174     SET_PACKAGESIZE[3] = pksz & 0xff;
00175     SET_PACKAGESIZE[4] = (pksz >> 8) & 0xff;
00176 
00177     if (!Command(INITIAL))
00178         return 0;
00179     if (!Command(SET_PACKAGESIZE))
00180         return 0;
00181     if (!Command(SNAPSHOT_JPEG))
00182         return 0;
00183     if (!Command(GETPICTURE_SNAPSHOT))
00184         return 0;
00185 
00186     read(buf, 6);
00187     if (!(buf[0] == 0xaa && buf[1] == 0x0a && buf[2] == 0x01))
00188         return 0;
00189 
00190     return buf[5]<<16 | buf[4]<<8 | buf[3]; // return file size
00191 }
00192 
00193 // Take a raw image. 
00194 //
00195 // Color: color mode (supporte form 8bit gray, RGB232, or RGB565 only)
00196 // Res: image resolution
00197 // buf: buffer to save the image
00198 int uCam::SnapshotRaw(int Color, int Res, unsigned char *buf) {
00199     unsigned char INITIAL[] = {0xaa, 0x01, 0x00, 0x00, 0x00, 0x07};
00200 
00201     INITIAL[3] = Color;
00202     INITIAL[4] = Res;
00203 
00204     if (!Command(INITIAL))
00205         return 0;
00206     if (!Command(SNAPSHOT_RAW))
00207         return 0;
00208     if (!Command(GETPICTURE_SNAPSHOT))
00209         return 0;
00210 
00211     read(buf, 6);
00212     if (!(buf[0] == 0xaa && buf[1] == 0x0a && buf[2] == 0x01))
00213         return 0;
00214 
00215     // lcd.printf("%d\n", buf[3] + buf[4]<<8 + buf[5]<<16);
00216     read(buf, buf[5]<<16 | buf[4]<<8 | buf[3] /* 80*60*2*/ );
00217     write(ACK1, sizeof(ACK1));
00218 
00219     return 1;
00220 }
00221 
00222 // Take a raw image. This function crops
00223 // the image while it is recieving data from uCam
00224 //
00225 // Color: color mode (supporte form 8bit gray, RGB232, or RGB565 only)
00226 // Res: image resolution
00227 // x0, y0: top left corner of the cropping area
00228 // w, h: width and height of cropping area
00229 // buf: buffer to save the image
00230 int uCam::SnapshotRawCrop(int Color, int Res,
00231                           int x0, int y0, int w, int h,
00232                           unsigned char *buf) {
00233     unsigned char INITIAL[] = {0xaa, 0x01, 0x00, 0x00, 0x00, 0x07};
00234     int W = ucam_raw_resolution_w[(Res-1)/2];
00235     int H = ucam_raw_resolution_h[(Res-1)/2];
00236 
00237     if (Color == UCAM_COLOR_TYPE_RGB565) {
00238         W *= 2;
00239         x0 *= 2;
00240         w *= 2;
00241     }
00242 
00243     INITIAL[3] = Color;
00244     INITIAL[4] = Res;
00245 
00246     if (!Command(INITIAL))
00247         return 0;
00248     if (!Command(SNAPSHOT_RAW))
00249         return 0;
00250     if (!Command(GETPICTURE_SNAPSHOT))
00251         return 0;
00252 
00253     read(buf, 6);
00254     if (!(buf[0] == 0xaa && buf[1] == 0x0a && buf[2] == 0x01))
00255         return 0;
00256 
00257     for (int i=y0*W; i>0; i--) /* Skip */
00258         s->getc();
00259 
00260     for (int i=h; i>0; i--) {
00261         for (int j=x0; j>0; j--) /* Skip */
00262             s->getc();
00263         read(buf, w);
00264         buf += w;
00265         for (int j=W-w-x0; j>0; j--) /* Skip */
00266             s->getc();
00267     }
00268     for (int i=(H-y0-h)*W; i>0; i--) /* Skip */
00269         s->getc();
00270     write(ACK1, sizeof(ACK1));
00271 
00272     return 1;
00273 }
00274 
00275 // Write <len> characters from p to the serial
00276 void uCam::write(const unsigned char *p, int len) {
00277     for (; len>0; len--, p++) {
00278         s->putc(*p);
00279     }
00280 }