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

Committer:
non
Date:
Thu Oct 13 02:41:04 2011 +0000
Revision:
2:0621feb3adf2
Parent:
0:07d02a20d1cc

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
non 0:07d02a20d1cc 1 /* 4D Systems uCam serial RAW/JPEG camera library
non 0:07d02a20d1cc 2 * Copyright (c) 2011, Noriaki Mitsunaga
non 0:07d02a20d1cc 3 *
non 0:07d02a20d1cc 4 * Permission is hereby granted, free of charge, to any person obtaining a copy
non 0:07d02a20d1cc 5 * of this software and associated documentation files (the "Software"), to deal
non 0:07d02a20d1cc 6 * in the Software without restriction, including without limitation the rights
non 0:07d02a20d1cc 7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
non 0:07d02a20d1cc 8 * copies of the Software, and to permit persons to whom the Software is
non 0:07d02a20d1cc 9 * furnished to do so, subject to the following conditions:
non 0:07d02a20d1cc 10 *
non 0:07d02a20d1cc 11 * The above copyright notice and this permission notice shall be included in
non 0:07d02a20d1cc 12 * all copies or substantial portions of the Software.
non 0:07d02a20d1cc 13 *
non 0:07d02a20d1cc 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
non 0:07d02a20d1cc 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
non 0:07d02a20d1cc 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
non 0:07d02a20d1cc 17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
non 0:07d02a20d1cc 18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
non 0:07d02a20d1cc 19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
non 0:07d02a20d1cc 20 * THE SOFTWARE.
non 0:07d02a20d1cc 21 */
non 0:07d02a20d1cc 22 #include "mbed.h"
non 0:07d02a20d1cc 23 #include "ucam.h"
non 0:07d02a20d1cc 24
non 0:07d02a20d1cc 25 // uCam-TTL commands:
non 0:07d02a20d1cc 26 const unsigned char ACK[] = {0xaa, 0x0e, 0x0d, 0, 0, 0};
non 0:07d02a20d1cc 27 const unsigned char ACK1[] = {0xaa, 0x0e, 0x0d, 0, 1, 0};
non 0:07d02a20d1cc 28 const unsigned char ACK_F0F0_[] = {0xaa, 0x0e, 0, 0, 0xf0, 0xf0};
non 0:07d02a20d1cc 29 const unsigned char GETPICTURE_SNAPSHOT[] = {0xaa, 0x04, 0x01, 0, 0, 0};
non 0:07d02a20d1cc 30 // const unsigned char GETPICTURE_RAWPREVIEW[] = {0xaa, 0x04, 0x02, 0, 0, 0};
non 0:07d02a20d1cc 31 const unsigned char RESET[] = {0xaa, 0x08, 0x01, 0x0, 0x0, 0xff};
non 0:07d02a20d1cc 32 const unsigned char SNAPSHOT_JPEG[] = {0xaa, 0x05, 0x00, 1, 0, 0};
non 0:07d02a20d1cc 33 const unsigned char SNAPSHOT_RAW[] = {0xaa, 0x05, 0x01, 1, 0, 0};
non 0:07d02a20d1cc 34 const unsigned char SYNC[] = {0xaa, 0x0d, 0, 0, 0, 0};
non 0:07d02a20d1cc 35
non 0:07d02a20d1cc 36 // Send special ACK
non 0:07d02a20d1cc 37 void uCam::ACK_F0F0() {
non 0:07d02a20d1cc 38 write(ACK_F0F0_, sizeof(ACK_F0F0_));
non 0:07d02a20d1cc 39 }
non 0:07d02a20d1cc 40
non 0:07d02a20d1cc 41 // Check if buf is valid ACK.
non 0:07d02a20d1cc 42 int uCam::checkACK(const unsigned char *buf) {
non 0:07d02a20d1cc 43 if (buf[0] == ACK[0] && buf[1] == ACK[1] && buf[2] == ACK[2]
non 0:07d02a20d1cc 44 && buf[4] == 0 && buf[5] == 0)
non 0:07d02a20d1cc 45 return 1;
non 0:07d02a20d1cc 46
non 0:07d02a20d1cc 47 return 0;
non 0:07d02a20d1cc 48 }
non 0:07d02a20d1cc 49
non 0:07d02a20d1cc 50 // Compare buf to SYNC
non 0:07d02a20d1cc 51 int uCam::checkSYNC(const unsigned char *buf) {
non 0:07d02a20d1cc 52 if (memcmp(buf, SYNC, sizeof(SYNC)) == 0)
non 0:07d02a20d1cc 53 return 1;
non 0:07d02a20d1cc 54
non 0:07d02a20d1cc 55 return 0;
non 0:07d02a20d1cc 56 }
non 0:07d02a20d1cc 57
non 0:07d02a20d1cc 58 // Send a command to uCam via the serial
non 0:07d02a20d1cc 59 int uCam::Command(const unsigned char *cmd) {
non 0:07d02a20d1cc 60 // Send the command
non 0:07d02a20d1cc 61 write(cmd, 6);
non 0:07d02a20d1cc 62
non 0:07d02a20d1cc 63 // Wait for response
non 0:07d02a20d1cc 64 unsigned char buf[6];
non 0:07d02a20d1cc 65 read(buf, 6);
non 0:07d02a20d1cc 66
non 0:07d02a20d1cc 67 // Check ACK
non 0:07d02a20d1cc 68 if (buf[0] == 0xaa && buf[1] == 0x0e
non 0:07d02a20d1cc 69 && buf[2] == cmd[1]
non 0:07d02a20d1cc 70 /* ignore fourth byte */
non 0:07d02a20d1cc 71 && buf[4] == 0 && buf[5] == 0)
non 0:07d02a20d1cc 72 return 1;
non 0:07d02a20d1cc 73
non 0:07d02a20d1cc 74 return 0;
non 0:07d02a20d1cc 75 }
non 0:07d02a20d1cc 76
non 0:07d02a20d1cc 77 // Initialize communcation to uCam
non 0:07d02a20d1cc 78 int uCam::Init() {
non 0:07d02a20d1cc 79 int i;
non 0:07d02a20d1cc 80 unsigned char buf[12];
non 0:07d02a20d1cc 81
non 0:07d02a20d1cc 82 for (i=0; i<60; i ++) {
non 0:07d02a20d1cc 83 // Send SYNC and check the answer
non 0:07d02a20d1cc 84 write(SYNC, sizeof(SYNC));
non 0:07d02a20d1cc 85 if (readT(buf, sizeof(buf)) == 12 && checkACK(buf)) {
non 0:07d02a20d1cc 86 break;
non 0:07d02a20d1cc 87 }
non 0:07d02a20d1cc 88 }
non 0:07d02a20d1cc 89 if (i == 60) // Too many retries
non 0:07d02a20d1cc 90 return 0;
non 0:07d02a20d1cc 91
non 0:07d02a20d1cc 92 // Check SYNC
non 0:07d02a20d1cc 93 if (!checkSYNC(buf+6)) {
non 0:07d02a20d1cc 94 return 0;
non 0:07d02a20d1cc 95 }
non 0:07d02a20d1cc 96 write(ACK, sizeof(ACK));
non 0:07d02a20d1cc 97 return 1;
non 0:07d02a20d1cc 98 }
non 0:07d02a20d1cc 99
non 0:07d02a20d1cc 100 // Set light frequencey (50Hz or 60Hz) to reduce flicker.
non 0:07d02a20d1cc 101 int uCam::LightFreq(int f) {
non 0:07d02a20d1cc 102 unsigned char LIGHT[] = {0xaa, 0x13, 0, 0, 0, 0};
non 0:07d02a20d1cc 103
non 0:07d02a20d1cc 104 if (f == 50)
non 0:07d02a20d1cc 105 LIGHT[2] = 0x0;
non 0:07d02a20d1cc 106 else if (f == 60)
non 0:07d02a20d1cc 107 LIGHT[2] = 0x1;
non 0:07d02a20d1cc 108 else
non 0:07d02a20d1cc 109 return 0;
non 0:07d02a20d1cc 110
non 0:07d02a20d1cc 111 return Command(LIGHT);
non 0:07d02a20d1cc 112 }
non 0:07d02a20d1cc 113
non 0:07d02a20d1cc 114 // Recive data from serial. It blocks until it recieves len bytes.
non 0:07d02a20d1cc 115 // buf: recieving buffer
non 0:07d02a20d1cc 116 // len: length to recieve
non 0:07d02a20d1cc 117 void uCam::read(unsigned char *p, int len) {
non 0:07d02a20d1cc 118 for (; len>0; len--, p++) {
non 0:07d02a20d1cc 119 *p = s->getc();
non 0:07d02a20d1cc 120 }
non 0:07d02a20d1cc 121 }
non 0:07d02a20d1cc 122
non 0:07d02a20d1cc 123 // Recive data from serial with timeout
non 0:07d02a20d1cc 124 // buf: recieving buffer
non 0:07d02a20d1cc 125 // len: length of the buffer
non 0:07d02a20d1cc 126 int uCam::readT(unsigned char *buf, int len) {
non 0:07d02a20d1cc 127 int c = 0;
non 0:07d02a20d1cc 128 unsigned char *q = buf;
non 0:07d02a20d1cc 129
non 0:07d02a20d1cc 130 for (int j=0; j<2000; j ++) {
non 0:07d02a20d1cc 131 if (s->readable()) {
non 0:07d02a20d1cc 132 *q = s->getc();
non 0:07d02a20d1cc 133 if (c < len) {
non 0:07d02a20d1cc 134 q ++;
non 0:07d02a20d1cc 135 c ++;
non 0:07d02a20d1cc 136 }
non 0:07d02a20d1cc 137 }
non 0:07d02a20d1cc 138 wait_us(50);
non 0:07d02a20d1cc 139 }
non 0:07d02a20d1cc 140
non 0:07d02a20d1cc 141 return c;
non 0:07d02a20d1cc 142 }
non 0:07d02a20d1cc 143
non 0:07d02a20d1cc 144 // Reset uCam
non 0:07d02a20d1cc 145 void uCam::Reset() {
non 0:07d02a20d1cc 146 Command(RESET);
non 0:07d02a20d1cc 147 }
non 0:07d02a20d1cc 148
non 0:07d02a20d1cc 149 // Recieve a JPEG image packet. You need to call SnapshotJPEGi() before.
non 0:07d02a20d1cc 150 // no: packet number (starts from 0)
non 0:07d02a20d1cc 151 // buf: recieving buffer
non 0:07d02a20d1cc 152 // pksz: packet size to recieve
non 0:07d02a20d1cc 153 int uCam::SnapshotJPEGd(int no, unsigned char *buf, int pksz) {
non 0:07d02a20d1cc 154 unsigned char ACK_[] = {0xaa, 0x0e, 0x00, 0, 0, 0};
non 0:07d02a20d1cc 155
non 0:07d02a20d1cc 156 ACK_[4] = no & 0xff;
non 0:07d02a20d1cc 157 ACK_[5] = (no >> 8) & 0xff;
non 0:07d02a20d1cc 158
non 0:07d02a20d1cc 159 write(ACK_, sizeof(ACK_));
non 0:07d02a20d1cc 160 read(buf, pksz);
non 0:07d02a20d1cc 161
non 0:07d02a20d1cc 162 return 1;
non 0:07d02a20d1cc 163 }
non 0:07d02a20d1cc 164
non 0:07d02a20d1cc 165 // Prepare to recieve a JPEG image.
non 0:07d02a20d1cc 166 // Res: resolution of the image (did not work well for 640x480 with uCam-TTL(ov528 version))
non 0:07d02a20d1cc 167 // pksz: packet size to recieve
non 0:07d02a20d1cc 168 int uCam::SnapshotJPEGi(int Res, int pksz) {
non 0:07d02a20d1cc 169 unsigned char INITIAL[] = {0xaa, 0x01, 0x00, 0x07, 0x01, 0x00};
non 0:07d02a20d1cc 170 unsigned char SET_PACKAGESIZE[] = {0xaa, 0x06, 0x08, 0x00, 0x00, 0x00};
non 0:07d02a20d1cc 171 unsigned char buf[6];
non 0:07d02a20d1cc 172
non 0:07d02a20d1cc 173 INITIAL[5] = Res;
non 0:07d02a20d1cc 174 SET_PACKAGESIZE[3] = pksz & 0xff;
non 0:07d02a20d1cc 175 SET_PACKAGESIZE[4] = (pksz >> 8) & 0xff;
non 0:07d02a20d1cc 176
non 0:07d02a20d1cc 177 if (!Command(INITIAL))
non 0:07d02a20d1cc 178 return 0;
non 0:07d02a20d1cc 179 if (!Command(SET_PACKAGESIZE))
non 0:07d02a20d1cc 180 return 0;
non 0:07d02a20d1cc 181 if (!Command(SNAPSHOT_JPEG))
non 0:07d02a20d1cc 182 return 0;
non 0:07d02a20d1cc 183 if (!Command(GETPICTURE_SNAPSHOT))
non 0:07d02a20d1cc 184 return 0;
non 0:07d02a20d1cc 185
non 0:07d02a20d1cc 186 read(buf, 6);
non 0:07d02a20d1cc 187 if (!(buf[0] == 0xaa && buf[1] == 0x0a && buf[2] == 0x01))
non 0:07d02a20d1cc 188 return 0;
non 0:07d02a20d1cc 189
non 0:07d02a20d1cc 190 return buf[5]<<16 | buf[4]<<8 | buf[3]; // return file size
non 0:07d02a20d1cc 191 }
non 0:07d02a20d1cc 192
non 0:07d02a20d1cc 193 // Take a raw image.
non 0:07d02a20d1cc 194 //
non 0:07d02a20d1cc 195 // Color: color mode (supporte form 8bit gray, RGB232, or RGB565 only)
non 0:07d02a20d1cc 196 // Res: image resolution
non 0:07d02a20d1cc 197 // buf: buffer to save the image
non 0:07d02a20d1cc 198 int uCam::SnapshotRaw(int Color, int Res, unsigned char *buf) {
non 0:07d02a20d1cc 199 unsigned char INITIAL[] = {0xaa, 0x01, 0x00, 0x00, 0x00, 0x07};
non 0:07d02a20d1cc 200
non 0:07d02a20d1cc 201 INITIAL[3] = Color;
non 0:07d02a20d1cc 202 INITIAL[4] = Res;
non 0:07d02a20d1cc 203
non 0:07d02a20d1cc 204 if (!Command(INITIAL))
non 0:07d02a20d1cc 205 return 0;
non 0:07d02a20d1cc 206 if (!Command(SNAPSHOT_RAW))
non 0:07d02a20d1cc 207 return 0;
non 0:07d02a20d1cc 208 if (!Command(GETPICTURE_SNAPSHOT))
non 0:07d02a20d1cc 209 return 0;
non 0:07d02a20d1cc 210
non 0:07d02a20d1cc 211 read(buf, 6);
non 0:07d02a20d1cc 212 if (!(buf[0] == 0xaa && buf[1] == 0x0a && buf[2] == 0x01))
non 0:07d02a20d1cc 213 return 0;
non 0:07d02a20d1cc 214
non 0:07d02a20d1cc 215 // lcd.printf("%d\n", buf[3] + buf[4]<<8 + buf[5]<<16);
non 0:07d02a20d1cc 216 read(buf, buf[5]<<16 | buf[4]<<8 | buf[3] /* 80*60*2*/ );
non 0:07d02a20d1cc 217 write(ACK1, sizeof(ACK1));
non 0:07d02a20d1cc 218
non 0:07d02a20d1cc 219 return 1;
non 0:07d02a20d1cc 220 }
non 0:07d02a20d1cc 221
non 0:07d02a20d1cc 222 // Take a raw image. This function crops
non 0:07d02a20d1cc 223 // the image while it is recieving data from uCam
non 0:07d02a20d1cc 224 //
non 0:07d02a20d1cc 225 // Color: color mode (supporte form 8bit gray, RGB232, or RGB565 only)
non 0:07d02a20d1cc 226 // Res: image resolution
non 0:07d02a20d1cc 227 // x0, y0: top left corner of the cropping area
non 0:07d02a20d1cc 228 // w, h: width and height of cropping area
non 0:07d02a20d1cc 229 // buf: buffer to save the image
non 0:07d02a20d1cc 230 int uCam::SnapshotRawCrop(int Color, int Res,
non 0:07d02a20d1cc 231 int x0, int y0, int w, int h,
non 0:07d02a20d1cc 232 unsigned char *buf) {
non 0:07d02a20d1cc 233 unsigned char INITIAL[] = {0xaa, 0x01, 0x00, 0x00, 0x00, 0x07};
non 0:07d02a20d1cc 234 int W = ucam_raw_resolution_w[(Res-1)/2];
non 0:07d02a20d1cc 235 int H = ucam_raw_resolution_h[(Res-1)/2];
non 0:07d02a20d1cc 236
non 0:07d02a20d1cc 237 if (Color == UCAM_COLOR_TYPE_RGB565) {
non 0:07d02a20d1cc 238 W *= 2;
non 0:07d02a20d1cc 239 x0 *= 2;
non 0:07d02a20d1cc 240 w *= 2;
non 0:07d02a20d1cc 241 }
non 0:07d02a20d1cc 242
non 0:07d02a20d1cc 243 INITIAL[3] = Color;
non 0:07d02a20d1cc 244 INITIAL[4] = Res;
non 0:07d02a20d1cc 245
non 0:07d02a20d1cc 246 if (!Command(INITIAL))
non 0:07d02a20d1cc 247 return 0;
non 0:07d02a20d1cc 248 if (!Command(SNAPSHOT_RAW))
non 0:07d02a20d1cc 249 return 0;
non 0:07d02a20d1cc 250 if (!Command(GETPICTURE_SNAPSHOT))
non 0:07d02a20d1cc 251 return 0;
non 0:07d02a20d1cc 252
non 0:07d02a20d1cc 253 read(buf, 6);
non 0:07d02a20d1cc 254 if (!(buf[0] == 0xaa && buf[1] == 0x0a && buf[2] == 0x01))
non 0:07d02a20d1cc 255 return 0;
non 0:07d02a20d1cc 256
non 0:07d02a20d1cc 257 for (int i=y0*W; i>0; i--) /* Skip */
non 0:07d02a20d1cc 258 s->getc();
non 0:07d02a20d1cc 259
non 0:07d02a20d1cc 260 for (int i=h; i>0; i--) {
non 0:07d02a20d1cc 261 for (int j=x0; j>0; j--) /* Skip */
non 0:07d02a20d1cc 262 s->getc();
non 0:07d02a20d1cc 263 read(buf, w);
non 0:07d02a20d1cc 264 buf += w;
non 0:07d02a20d1cc 265 for (int j=W-w-x0; j>0; j--) /* Skip */
non 0:07d02a20d1cc 266 s->getc();
non 0:07d02a20d1cc 267 }
non 0:07d02a20d1cc 268 for (int i=(H-y0-h)*W; i>0; i--) /* Skip */
non 0:07d02a20d1cc 269 s->getc();
non 0:07d02a20d1cc 270 write(ACK1, sizeof(ACK1));
non 0:07d02a20d1cc 271
non 0:07d02a20d1cc 272 return 1;
non 0:07d02a20d1cc 273 }
non 0:07d02a20d1cc 274
non 0:07d02a20d1cc 275 // Write <len> characters from p to the serial
non 0:07d02a20d1cc 276 void uCam::write(const unsigned char *p, int len) {
non 0:07d02a20d1cc 277 for (; len>0; len--, p++) {
non 0:07d02a20d1cc 278 s->putc(*p);
non 0:07d02a20d1cc 279 }
non 0:07d02a20d1cc 280 }