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

Revision:
0:07d02a20d1cc
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ucam.cpp	Thu Oct 06 00:54:08 2011 +0000
@@ -0,0 +1,280 @@
+/* 4D Systems uCam serial RAW/JPEG camera library
+ * Copyright (c) 2011, Noriaki Mitsunaga
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include "mbed.h"
+#include "ucam.h"
+
+// uCam-TTL commands:
+const unsigned char ACK[] = {0xaa, 0x0e, 0x0d, 0, 0, 0};
+const unsigned char ACK1[] = {0xaa, 0x0e, 0x0d, 0, 1, 0};
+const unsigned char ACK_F0F0_[] = {0xaa, 0x0e, 0, 0, 0xf0, 0xf0};
+const unsigned char GETPICTURE_SNAPSHOT[] = {0xaa, 0x04, 0x01, 0, 0, 0};
+// const unsigned char GETPICTURE_RAWPREVIEW[] = {0xaa, 0x04, 0x02, 0, 0, 0};
+const unsigned char RESET[] = {0xaa, 0x08, 0x01, 0x0, 0x0, 0xff};
+const unsigned char SNAPSHOT_JPEG[] = {0xaa, 0x05, 0x00, 1, 0, 0};
+const unsigned char SNAPSHOT_RAW[] = {0xaa, 0x05, 0x01, 1, 0, 0};
+const unsigned char SYNC[] = {0xaa, 0x0d, 0, 0, 0, 0};
+
+// Send special ACK
+void uCam::ACK_F0F0() {
+    write(ACK_F0F0_, sizeof(ACK_F0F0_));
+}
+
+// Check if buf is valid ACK.
+int uCam::checkACK(const unsigned char *buf) {
+    if (buf[0] == ACK[0] && buf[1] == ACK[1] && buf[2] == ACK[2]
+            && buf[4] == 0 && buf[5] == 0)
+        return 1;
+
+    return 0;
+}
+
+// Compare buf to SYNC
+int uCam::checkSYNC(const unsigned char *buf) {
+    if (memcmp(buf, SYNC, sizeof(SYNC)) == 0)
+        return 1;
+
+    return 0;
+}
+
+// Send a command to uCam via the serial
+int uCam::Command(const unsigned char *cmd) {
+    // Send the command
+    write(cmd, 6);
+
+    // Wait for response
+    unsigned char buf[6];
+    read(buf, 6);
+
+    // Check ACK
+    if (buf[0] == 0xaa && buf[1] == 0x0e
+            && buf[2] == cmd[1]
+            /* ignore fourth byte */
+            && buf[4] == 0 && buf[5] == 0)
+        return 1;
+
+    return 0;
+}
+
+// Initialize communcation to uCam
+int uCam::Init() {
+    int i;
+    unsigned char buf[12];
+
+    for (i=0; i<60; i ++) {
+        // Send SYNC and check the answer
+        write(SYNC, sizeof(SYNC));
+        if (readT(buf, sizeof(buf)) == 12 && checkACK(buf)) {
+            break;
+        }
+    }
+    if (i == 60)      // Too many retries
+        return 0;
+
+    // Check SYNC
+    if (!checkSYNC(buf+6)) {
+        return 0;
+    }
+    write(ACK, sizeof(ACK));
+    return 1;
+}
+
+// Set light frequencey (50Hz or 60Hz) to reduce flicker.
+int uCam::LightFreq(int f) {
+    unsigned char LIGHT[] = {0xaa, 0x13, 0, 0, 0, 0};
+
+    if (f == 50)
+        LIGHT[2] = 0x0;
+    else if (f == 60)
+        LIGHT[2] = 0x1;
+    else
+        return 0;
+
+    return Command(LIGHT);
+}
+
+// Recive data from serial. It blocks until it recieves len bytes.
+// buf: recieving buffer
+// len: length to recieve
+void uCam::read(unsigned char *p, int len) {
+    for (; len>0; len--, p++) {
+        *p = s->getc();
+    }
+}
+
+// Recive data from serial with timeout
+// buf: recieving buffer
+// len: length of the buffer
+int uCam::readT(unsigned char *buf, int len) {
+    int c = 0;
+    unsigned char *q = buf;
+
+    for (int j=0; j<2000; j ++) {
+        if (s->readable()) {
+            *q = s->getc();
+            if (c < len) {
+                q ++;
+                c ++;
+            }
+        }
+        wait_us(50);
+    }
+
+    return c;
+}
+
+// Reset uCam
+void uCam::Reset() {
+    Command(RESET);
+}
+
+// Recieve a JPEG image packet. You need to call SnapshotJPEGi() before.
+// no: packet number (starts from 0)
+// buf: recieving buffer
+// pksz: packet size to recieve
+int uCam::SnapshotJPEGd(int no, unsigned char *buf, int pksz) {
+    unsigned char ACK_[] = {0xaa, 0x0e, 0x00, 0, 0, 0};
+
+    ACK_[4] = no & 0xff;
+    ACK_[5] = (no >> 8) & 0xff;
+
+    write(ACK_, sizeof(ACK_));
+    read(buf, pksz);
+
+    return 1;
+}
+
+// Prepare to recieve a JPEG image.
+// Res: resolution of the image (did not work well for 640x480 with uCam-TTL(ov528 version))
+// pksz: packet size to recieve
+int uCam::SnapshotJPEGi(int Res, int pksz) {
+    unsigned char INITIAL[] = {0xaa, 0x01, 0x00, 0x07, 0x01, 0x00};
+    unsigned char SET_PACKAGESIZE[] = {0xaa, 0x06, 0x08, 0x00, 0x00, 0x00};
+    unsigned char buf[6];
+
+    INITIAL[5] = Res;
+    SET_PACKAGESIZE[3] = pksz & 0xff;
+    SET_PACKAGESIZE[4] = (pksz >> 8) & 0xff;
+
+    if (!Command(INITIAL))
+        return 0;
+    if (!Command(SET_PACKAGESIZE))
+        return 0;
+    if (!Command(SNAPSHOT_JPEG))
+        return 0;
+    if (!Command(GETPICTURE_SNAPSHOT))
+        return 0;
+
+    read(buf, 6);
+    if (!(buf[0] == 0xaa && buf[1] == 0x0a && buf[2] == 0x01))
+        return 0;
+
+    return buf[5]<<16 | buf[4]<<8 | buf[3]; // return file size
+}
+
+// Take a raw image. 
+//
+// Color: color mode (supporte form 8bit gray, RGB232, or RGB565 only)
+// Res: image resolution
+// buf: buffer to save the image
+int uCam::SnapshotRaw(int Color, int Res, unsigned char *buf) {
+    unsigned char INITIAL[] = {0xaa, 0x01, 0x00, 0x00, 0x00, 0x07};
+
+    INITIAL[3] = Color;
+    INITIAL[4] = Res;
+
+    if (!Command(INITIAL))
+        return 0;
+    if (!Command(SNAPSHOT_RAW))
+        return 0;
+    if (!Command(GETPICTURE_SNAPSHOT))
+        return 0;
+
+    read(buf, 6);
+    if (!(buf[0] == 0xaa && buf[1] == 0x0a && buf[2] == 0x01))
+        return 0;
+
+    // lcd.printf("%d\n", buf[3] + buf[4]<<8 + buf[5]<<16);
+    read(buf, buf[5]<<16 | buf[4]<<8 | buf[3] /* 80*60*2*/ );
+    write(ACK1, sizeof(ACK1));
+
+    return 1;
+}
+
+// Take a raw image. This function crops
+// the image while it is recieving data from uCam
+//
+// Color: color mode (supporte form 8bit gray, RGB232, or RGB565 only)
+// Res: image resolution
+// x0, y0: top left corner of the cropping area
+// w, h: width and height of cropping area
+// buf: buffer to save the image
+int uCam::SnapshotRawCrop(int Color, int Res,
+                          int x0, int y0, int w, int h,
+                          unsigned char *buf) {
+    unsigned char INITIAL[] = {0xaa, 0x01, 0x00, 0x00, 0x00, 0x07};
+    int W = ucam_raw_resolution_w[(Res-1)/2];
+    int H = ucam_raw_resolution_h[(Res-1)/2];
+
+    if (Color == UCAM_COLOR_TYPE_RGB565) {
+        W *= 2;
+        x0 *= 2;
+        w *= 2;
+    }
+
+    INITIAL[3] = Color;
+    INITIAL[4] = Res;
+
+    if (!Command(INITIAL))
+        return 0;
+    if (!Command(SNAPSHOT_RAW))
+        return 0;
+    if (!Command(GETPICTURE_SNAPSHOT))
+        return 0;
+
+    read(buf, 6);
+    if (!(buf[0] == 0xaa && buf[1] == 0x0a && buf[2] == 0x01))
+        return 0;
+
+    for (int i=y0*W; i>0; i--) /* Skip */
+        s->getc();
+
+    for (int i=h; i>0; i--) {
+        for (int j=x0; j>0; j--) /* Skip */
+            s->getc();
+        read(buf, w);
+        buf += w;
+        for (int j=W-w-x0; j>0; j--) /* Skip */
+            s->getc();
+    }
+    for (int i=(H-y0-h)*W; i>0; i--) /* Skip */
+        s->getc();
+    write(ACK1, sizeof(ACK1));
+
+    return 1;
+}
+
+// Write <len> characters from p to the serial
+void uCam::write(const unsigned char *p, int len) {
+    for (; len>0; len--, p++) {
+        s->putc(*p);
+    }
+}