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
main.cpp
00001 /* This software is an digital video camera program using NKK's oLED swtich 00002 * and 4D Systems' uCam serial camera. It takes image from the uCam and 00003 * displays on the IS-C15 switch. Some image processing demos are included. 00004 * 00005 * This program uses FatFileSytem, SDFileSystem, and TextLCD library. 00006 * 00007 * Copyright (c) 2011, Noriaki Mitsunaga 00008 * 00009 * Permission is hereby granted, free of charge, to any person obtaining a copy 00010 * of this software and associated documentation files (the "Software"), to deal 00011 * in the Software without restriction, including without limitation the rights 00012 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 00013 * copies of the Software, and to permit persons to whom the Software is 00014 * furnished to do so, subject to the following conditions: 00015 * 00016 * The above copyright notice and this permission notice shall be included in 00017 * all copies or substantial portions of the Software. 00018 * 00019 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 00020 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00021 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 00022 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 00023 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00024 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 00025 * THE SOFTWARE. 00026 */ 00027 #include "mbed.h" 00028 // #define USE_LCD // Need this if you want to use text LCD 00029 #ifdef USE_LCD 00030 #include "TextLCD.h" 00031 #endif 00032 // #include "SDFileSystem.h" // Need this if you want to save to SD-Card 00033 00034 #include "isc15.h" 00035 #include "ucam.h" 00036 00037 // SDFileSystem sd(p5, p6, p7, p8, "sd"); // Need this if you want to save to SD-Card 00038 LocalFileSystem local("local"); // Need this if you want to save to local flash 00039 SPI spi(p11, p12, p13); // mosi(SDO), miso(SDI), sclk(SCLK) 00040 00041 ISC15 ISC15(p16, p15, p14, p18); // NKK IS-C15 oLED swtich 00042 DigitalOut led1(LED1), led2(LED2); // On board LEDs 00043 DigitalIn sw1(p17); // Shutter switch (IS-C15) 00044 uCam ucam(p9, p10); // uCam-TTL (p9=TX, p10=RX) 00045 00046 Ticker timer; 00047 bool sw1pressed = false; 00048 bool sw1pressing = false; 00049 00050 #ifdef USE_LCD 00051 TextLCD lcd(p24, p26, p27, p28, p29, p30); // rs, e, d0-d3 00052 #define LCDPRINTF(...) lcd.printf(__VA_ARGS__) 00053 #else 00054 #define LCDPRINTF(...) 00055 #endif /* USE_LCD */ 00056 00057 /* Function prototypes */ 00058 void checkSW(); 00059 int SaveJPEG(const char *fname); 00060 00061 /* main fuction */ 00062 int main() { 00063 unsigned char cam[80*60*2]; 00064 unsigned char oled[64*48*2]; 00065 int n = 0; 00066 00067 sw1.mode(PullUp); 00068 led1 = led2 = 1; 00069 // Setup the spi for 8 bit data, high steady state clock, 00070 // second edge capture, with a 4MHz clock rate 00071 spi.format(8, 3); 00072 spi.frequency(4000000); 00073 // Initialize IS Color 15's oLED 00074 ISC15.Init(ISC15_DEVICE_ISC15, &spi); 00075 // Clear oLED display 00076 ISC15.Cls(); 00077 00078 // Initialize uCam-TTL 00079 LCDPRINTF("Init Camera..\n"); 00080 if (!ucam.Init()) { 00081 LCDPRINTF("Init failed.\n"); 00082 goto ERROR; 00083 } 00084 // Set AC frequency (60 for Kansai-area, 50 for Kanto-area) 00085 if (!ucam.LightFreq(60)) 00086 goto ERROR; 00087 // Attach tick timer to checkSW function 00088 timer.attach_us(checkSW, 20000); 00089 00090 LCDPRINTF("Starting.\n"); 00091 led1 = led2 = 0; 00092 00093 for (;;) { 00094 // Flush LED 00095 led1 = 1; 00096 wait(0.1); 00097 led1 = 0; 00098 00099 #if 1 /* D1: Set 1 to test RGB565 mode */ 00100 if (!ucam.SnapshotRaw(UCAM_COLOR_TYPE_RGB565, UCAM_RAW_RESOLUTION_80X60, cam)) 00101 goto ERROR; 00102 00103 for (int y=0; y<48; y++) { 00104 unsigned char *rg = cam + (80-64)/2 + ((60-48)/2+y)*80*2; 00105 unsigned char *gb = rg + 1; 00106 unsigned char *p = oled + y*64*2; 00107 for (int x=0; x<64; x++, rg+=2, gb+=2) { 00108 *p ++ = (*gb <<3) | (*rg & 0x7); 00109 *p ++ = (*gb & 0xe0) | (*rg >> 3); 00110 } 00111 } 00112 ISC15.Disp(ISC15_DSPMODE_64K, oled); 00113 #endif 00114 00115 #if 0 /* D2: Set 1 to test 4bit gray mode */ 00116 if (!ucam.SnapshotRaw(UCAM_COLOR_TYPE_4BITG, UCAM_RAW_RESOLUTION_80X60, cam)) 00117 goto ERROR; 00118 00119 for (int y=0; y<48; y++) { 00120 unsigned char *v = cam + ((80-64)/2 + ((60-48)/2+y)*80)/2; 00121 unsigned char *p = oled + y*64*2; 00122 for (int x=0; x<64; x++, v++) { 00123 int V = (*v & 0xf0) >> 4; 00124 *p ++ = (V << 4) | (V >> 1); 00125 *p ++ = ((V << 2) & 0xe0) | (V << 1); 00126 x ++; 00127 00128 V = *v & 0xf; 00129 *p ++ = (V << 4) | (V >> 1); 00130 *p ++ = ((V << 2) & 0xe0) | (V << 1); 00131 } 00132 } 00133 ISC15.Disp(ISC15_DSPMODE_64K, oled); 00134 #endif 00135 00136 #if 0 /* D3: Set 1 to test 8bit gray mode */ 00137 if (!ucam.SnapshotRaw(UCAM_COLOR_TYPE_8BITG, UCAM_RAW_RESOLUTION_80X60, cam)) 00138 goto ERROR; 00139 00140 for (int y=0; y<48; y++) { 00141 unsigned char *v = cam + (80-64)/2 + ((60-48)/2+y)*80; 00142 unsigned char *p = oled + y*64*2; 00143 for (int x=0; x<64; x++, v++) { 00144 *p ++ = (*v & 0xf8) | (*v >> 5); 00145 *p ++ = ((*v << 3) & 0xe0) | (*v >> 3); 00146 } 00147 } 00148 ISC15.Disp(ISC15_DSPMODE_64K, oled); 00149 #endif 00150 00151 #if 0 /* D4: Set 1 to test RGB332 mode */ 00152 if (!ucam.SnapshotRaw(UCAM_COLOR_TYPE_RGB332, UCAM_RAW_RESOLUTION_80X60, cam)) 00153 goto ERROR; 00154 00155 for (int y=0; y<48; y++) { 00156 unsigned char *v = cam + ((80-64)/2 + ((60-48)/2+y)*80); 00157 unsigned char *p = oled + y*64*2; 00158 for (int x=0; x<64; x++, v++) { 00159 int B = (*v & 0xe0) >> 5; /* 3bits */ 00160 int G = (*v & 0x1c) >> 3; /* 3bits */ 00161 int R = (*v & 0x3); /* 2bits */ 00162 *p ++ = (B << 6) | G; 00163 *p ++ = R << 2; 00164 } 00165 } 00166 ISC15.Disp(ISC15_DSPMODE_64K, oled); 00167 #endif 00168 00169 #if 0 /* D5: Set 1 to test cropping (digital zoom) */ 00170 if (!ucam.SnapshotRawCrop(UCAM_COLOR_TYPE_RGB565, 00171 UCAM_RAW_RESOLUTION_160X120, 48, 36, 64, 48, cam)) 00172 goto ERROR; 00173 00174 unsigned char *rg = cam; 00175 unsigned char *gb = rg + 1; 00176 unsigned char *p = oled; 00177 for (int i=64*48; i>0; i--, rg+=2, gb+=2) { 00178 *p ++ = (*gb <<3) | (*rg & 0x7); 00179 *p ++ = (*gb & 0xe0) | (*rg >> 3); 00180 } 00181 ISC15.Disp(ISC15_DSPMODE_64K, oled); 00182 #endif 00183 00184 #if 0 /* D6: Set 1 to test 8bit gray differential image */ 00185 unsigned char cam2[80*60]; 00186 static unsigned char *camp = cam, *cam2p = cam2; 00187 00188 if (!ucam.SnapshotRaw(UCAM_COLOR_TYPE_8BITG, UCAM_RAW_RESOLUTION_80X60, camp)) 00189 goto ERROR; 00190 00191 for (int y=0; y<48; y++) { 00192 unsigned char *v = camp + (80-64)/2 + ((60-48)/2+y)*80; 00193 unsigned char *b = cam2p + (80-64)/2 + ((60-48)/2+y)*80; 00194 unsigned char *p = oled + y*64*2; 00195 00196 for (int x=0; x<64; x++, v++, b++) { 00197 if (abs(*v-*b)>10) { 00198 *p ++ = (*v & 0xf8) | (*v >> 5); 00199 *p ++ = ((*v << 3) & 0xe0) | (*v >> 3); 00200 } else { 00201 *p ++ = 0; 00202 *p ++ = 0; 00203 } 00204 } 00205 } 00206 if (camp == cam) { 00207 camp = cam2; 00208 cam2p = cam; 00209 } else { 00210 camp = cam; 00211 cam2p = cam2; 00212 } 00213 ISC15.Disp(ISC15_DSPMODE_64K, oled); 00214 #endif 00215 00216 #if 0 /* D7: Set 1 to show RGB565 image when images' differential is large */ 00217 unsigned char cam2[80*60*2]; 00218 static unsigned char *camp = cam, *cam2p = cam2; 00219 00220 if (!ucam.SnapshotRawCrop(UCAM_COLOR_TYPE_RGB565, 00221 UCAM_RAW_RESOLUTION_80X60, 8, 6, 64, 48, camp)) 00222 goto ERROR; 00223 00224 unsigned char *rg = camp; 00225 unsigned char *gb = rg + 1; 00226 unsigned char *rg0 = cam2p; 00227 unsigned char *gb0 = rg0 + 1; 00228 unsigned int diff = 0; 00229 00230 for (int i=64*48; i>0; i--, rg+=2, gb+=2, rg0+=2, gb0+=2) 00231 diff += abs(((*rg & 0x7)<<3 | (*gb >> 5))-((*rg0 & 0x7)<<3 | (*gb0>> 5))); 00232 LCDPRINTF("d: %d.\n", diff); 00233 00234 if (diff > 3000) { 00235 rg = camp; 00236 gb = rg + 1; 00237 unsigned char *p = oled; 00238 for (int i=64*48; i>0; i--, rg+=2, gb+=2) { 00239 *p ++ = (*gb <<3) | (*rg & 0x7); 00240 *p ++ = (*gb & 0xe0) | (*rg >> 3); 00241 } 00242 ISC15.Disp(ISC15_DSPMODE_64K, oled); 00243 } else { 00244 ISC15.Cls(); 00245 } 00246 if (camp == cam) { 00247 camp = cam2; 00248 cam2p = cam; 00249 } else { 00250 camp = cam; 00251 cam2p = cam2; 00252 } 00253 #endif 00254 00255 if (sw1pressed) { 00256 char fname[20]; 00257 // sprintf(fname, "/sd/%05d.jpg", n); // Save to SD-Card 00258 sprintf(fname, "/local/%05d.jpg", n); // Save to local flash memory 00259 LCDPRINTF("Saving image\n"); 00260 SaveJPEG(fname); 00261 LCDPRINTF("DONE \n"); 00262 n ++; 00263 sw1pressed = false; 00264 led2 = 0; 00265 } 00266 } 00267 00268 ERROR: 00269 LCDPRINTF("ERROR\n"); 00270 while (1) { 00271 led1 = 1; 00272 wait(0.1); 00273 led1 = 0; 00274 wait(0.1); 00275 } 00276 } 00277 00278 /* ------------------------------------------ */ 00279 /* Check current status of the switch */ 00280 /* The fuction is called by 20ms timer */ 00281 /* ------------------------------------------ */ 00282 void checkSW() { 00283 if (sw1 == 0) { 00284 /* Swtich is pressed */ 00285 sw1pressed = true; 00286 sw1pressing = true; 00287 led2 = 1; 00288 } else { 00289 /* Switch is open */ 00290 sw1pressing = false; 00291 led2 = 0; 00292 } 00293 } 00294 00295 /* ------------------------------------------ */ 00296 /* Save a JPEG image read from uCam to a file */ 00297 /* ------------------------------------------ */ 00298 int SaveJPEG(const char *fname) { 00299 /* Open file */ 00300 FILE *fp = fopen(fname, "wb"); 00301 if (fp == NULL) { 00302 LCDPRINTF("XXX %s\n", fname); 00303 return 0; 00304 } 00305 00306 /* Prepare to recieve JPEG image */ 00307 int sz = ucam.SnapshotJPEGi(UCAM_JPEG_RESOLUTION_320X240, 512); 00308 if (sz == 0) 00309 return 0; 00310 00311 /* Recieve packets */ 00312 int pno = 0; 00313 unsigned char cam[512]; 00314 while (sz > 0) { 00315 int pksz = 512; 00316 led2 = ~led2; 00317 00318 if (sz < (512 - 6)) 00319 pksz = sz + 6; 00320 LCDPRINTF("%d %d\n", pno, pksz); 00321 /* Recieve a packet */ 00322 if (!ucam.SnapshotJPEGd(pno, cam, pksz)) { 00323 if (fp != NULL) 00324 fclose(fp); 00325 return 0; 00326 } 00327 /* Write the packet */ 00328 if (fp != NULL) 00329 fwrite(cam + 4, 1, pksz - 6, fp); 00330 sz -= (pksz - 6); 00331 pno ++; 00332 /* Check end of the image */ 00333 if (sz == 0) { 00334 if (pksz == 512) { 00335 // Send reset command as manual says 00336 wait_ms(3); 00337 ucam.Reset(); 00338 ucam.Init(); 00339 } else { 00340 ucam.ACK_F0F0(); 00341 } 00342 } 00343 } 00344 fclose(fp); 00345 00346 return 1; 00347 }
Generated on Wed Jul 13 2022 21:19:27 by 1.7.2