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
- Committer:
- non
- Date:
- 2011-10-13
- Revision:
- 2:0621feb3adf2
- Parent:
- 0:07d02a20d1cc
File content as of revision 2:0621feb3adf2:
/* This software 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. * * 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" // #define USE_LCD // Need this if you want to use text LCD #ifdef USE_LCD #include "TextLCD.h" #endif // #include "SDFileSystem.h" // Need this if you want to save to SD-Card #include "isc15.h" #include "ucam.h" // SDFileSystem sd(p5, p6, p7, p8, "sd"); // Need this if you want to save to SD-Card LocalFileSystem local("local"); // Need this if you want to save to local flash SPI spi(p11, p12, p13); // mosi(SDO), miso(SDI), sclk(SCLK) ISC15 ISC15(p16, p15, p14, p18); // NKK IS-C15 oLED swtich DigitalOut led1(LED1), led2(LED2); // On board LEDs DigitalIn sw1(p17); // Shutter switch (IS-C15) uCam ucam(p9, p10); // uCam-TTL (p9=TX, p10=RX) Ticker timer; bool sw1pressed = false; bool sw1pressing = false; #ifdef USE_LCD TextLCD lcd(p24, p26, p27, p28, p29, p30); // rs, e, d0-d3 #define LCDPRINTF(...) lcd.printf(__VA_ARGS__) #else #define LCDPRINTF(...) #endif /* USE_LCD */ /* Function prototypes */ void checkSW(); int SaveJPEG(const char *fname); /* main fuction */ int main() { unsigned char cam[80*60*2]; unsigned char oled[64*48*2]; int n = 0; sw1.mode(PullUp); led1 = led2 = 1; // Setup the spi for 8 bit data, high steady state clock, // second edge capture, with a 4MHz clock rate spi.format(8, 3); spi.frequency(4000000); // Initialize IS Color 15's oLED ISC15.Init(ISC15_DEVICE_ISC15, &spi); // Clear oLED display ISC15.Cls(); // Initialize uCam-TTL LCDPRINTF("Init Camera..\n"); if (!ucam.Init()) { LCDPRINTF("Init failed.\n"); goto ERROR; } // Set AC frequency (60 for Kansai-area, 50 for Kanto-area) if (!ucam.LightFreq(60)) goto ERROR; // Attach tick timer to checkSW function timer.attach_us(checkSW, 20000); LCDPRINTF("Starting.\n"); led1 = led2 = 0; for (;;) { // Flush LED led1 = 1; wait(0.1); led1 = 0; #if 1 /* D1: Set 1 to test RGB565 mode */ if (!ucam.SnapshotRaw(UCAM_COLOR_TYPE_RGB565, UCAM_RAW_RESOLUTION_80X60, cam)) goto ERROR; for (int y=0; y<48; y++) { unsigned char *rg = cam + (80-64)/2 + ((60-48)/2+y)*80*2; unsigned char *gb = rg + 1; unsigned char *p = oled + y*64*2; for (int x=0; x<64; x++, rg+=2, gb+=2) { *p ++ = (*gb <<3) | (*rg & 0x7); *p ++ = (*gb & 0xe0) | (*rg >> 3); } } ISC15.Disp(ISC15_DSPMODE_64K, oled); #endif #if 0 /* D2: Set 1 to test 4bit gray mode */ if (!ucam.SnapshotRaw(UCAM_COLOR_TYPE_4BITG, UCAM_RAW_RESOLUTION_80X60, cam)) goto ERROR; for (int y=0; y<48; y++) { unsigned char *v = cam + ((80-64)/2 + ((60-48)/2+y)*80)/2; unsigned char *p = oled + y*64*2; for (int x=0; x<64; x++, v++) { int V = (*v & 0xf0) >> 4; *p ++ = (V << 4) | (V >> 1); *p ++ = ((V << 2) & 0xe0) | (V << 1); x ++; V = *v & 0xf; *p ++ = (V << 4) | (V >> 1); *p ++ = ((V << 2) & 0xe0) | (V << 1); } } ISC15.Disp(ISC15_DSPMODE_64K, oled); #endif #if 0 /* D3: Set 1 to test 8bit gray mode */ if (!ucam.SnapshotRaw(UCAM_COLOR_TYPE_8BITG, UCAM_RAW_RESOLUTION_80X60, cam)) goto ERROR; for (int y=0; y<48; y++) { unsigned char *v = cam + (80-64)/2 + ((60-48)/2+y)*80; unsigned char *p = oled + y*64*2; for (int x=0; x<64; x++, v++) { *p ++ = (*v & 0xf8) | (*v >> 5); *p ++ = ((*v << 3) & 0xe0) | (*v >> 3); } } ISC15.Disp(ISC15_DSPMODE_64K, oled); #endif #if 0 /* D4: Set 1 to test RGB332 mode */ if (!ucam.SnapshotRaw(UCAM_COLOR_TYPE_RGB332, UCAM_RAW_RESOLUTION_80X60, cam)) goto ERROR; for (int y=0; y<48; y++) { unsigned char *v = cam + ((80-64)/2 + ((60-48)/2+y)*80); unsigned char *p = oled + y*64*2; for (int x=0; x<64; x++, v++) { int B = (*v & 0xe0) >> 5; /* 3bits */ int G = (*v & 0x1c) >> 3; /* 3bits */ int R = (*v & 0x3); /* 2bits */ *p ++ = (B << 6) | G; *p ++ = R << 2; } } ISC15.Disp(ISC15_DSPMODE_64K, oled); #endif #if 0 /* D5: Set 1 to test cropping (digital zoom) */ if (!ucam.SnapshotRawCrop(UCAM_COLOR_TYPE_RGB565, UCAM_RAW_RESOLUTION_160X120, 48, 36, 64, 48, cam)) goto ERROR; unsigned char *rg = cam; unsigned char *gb = rg + 1; unsigned char *p = oled; for (int i=64*48; i>0; i--, rg+=2, gb+=2) { *p ++ = (*gb <<3) | (*rg & 0x7); *p ++ = (*gb & 0xe0) | (*rg >> 3); } ISC15.Disp(ISC15_DSPMODE_64K, oled); #endif #if 0 /* D6: Set 1 to test 8bit gray differential image */ unsigned char cam2[80*60]; static unsigned char *camp = cam, *cam2p = cam2; if (!ucam.SnapshotRaw(UCAM_COLOR_TYPE_8BITG, UCAM_RAW_RESOLUTION_80X60, camp)) goto ERROR; for (int y=0; y<48; y++) { unsigned char *v = camp + (80-64)/2 + ((60-48)/2+y)*80; unsigned char *b = cam2p + (80-64)/2 + ((60-48)/2+y)*80; unsigned char *p = oled + y*64*2; for (int x=0; x<64; x++, v++, b++) { if (abs(*v-*b)>10) { *p ++ = (*v & 0xf8) | (*v >> 5); *p ++ = ((*v << 3) & 0xe0) | (*v >> 3); } else { *p ++ = 0; *p ++ = 0; } } } if (camp == cam) { camp = cam2; cam2p = cam; } else { camp = cam; cam2p = cam2; } ISC15.Disp(ISC15_DSPMODE_64K, oled); #endif #if 0 /* D7: Set 1 to show RGB565 image when images' differential is large */ unsigned char cam2[80*60*2]; static unsigned char *camp = cam, *cam2p = cam2; if (!ucam.SnapshotRawCrop(UCAM_COLOR_TYPE_RGB565, UCAM_RAW_RESOLUTION_80X60, 8, 6, 64, 48, camp)) goto ERROR; unsigned char *rg = camp; unsigned char *gb = rg + 1; unsigned char *rg0 = cam2p; unsigned char *gb0 = rg0 + 1; unsigned int diff = 0; for (int i=64*48; i>0; i--, rg+=2, gb+=2, rg0+=2, gb0+=2) diff += abs(((*rg & 0x7)<<3 | (*gb >> 5))-((*rg0 & 0x7)<<3 | (*gb0>> 5))); LCDPRINTF("d: %d.\n", diff); if (diff > 3000) { rg = camp; gb = rg + 1; unsigned char *p = oled; for (int i=64*48; i>0; i--, rg+=2, gb+=2) { *p ++ = (*gb <<3) | (*rg & 0x7); *p ++ = (*gb & 0xe0) | (*rg >> 3); } ISC15.Disp(ISC15_DSPMODE_64K, oled); } else { ISC15.Cls(); } if (camp == cam) { camp = cam2; cam2p = cam; } else { camp = cam; cam2p = cam2; } #endif if (sw1pressed) { char fname[20]; // sprintf(fname, "/sd/%05d.jpg", n); // Save to SD-Card sprintf(fname, "/local/%05d.jpg", n); // Save to local flash memory LCDPRINTF("Saving image\n"); SaveJPEG(fname); LCDPRINTF("DONE \n"); n ++; sw1pressed = false; led2 = 0; } } ERROR: LCDPRINTF("ERROR\n"); while (1) { led1 = 1; wait(0.1); led1 = 0; wait(0.1); } } /* ------------------------------------------ */ /* Check current status of the switch */ /* The fuction is called by 20ms timer */ /* ------------------------------------------ */ void checkSW() { if (sw1 == 0) { /* Swtich is pressed */ sw1pressed = true; sw1pressing = true; led2 = 1; } else { /* Switch is open */ sw1pressing = false; led2 = 0; } } /* ------------------------------------------ */ /* Save a JPEG image read from uCam to a file */ /* ------------------------------------------ */ int SaveJPEG(const char *fname) { /* Open file */ FILE *fp = fopen(fname, "wb"); if (fp == NULL) { LCDPRINTF("XXX %s\n", fname); return 0; } /* Prepare to recieve JPEG image */ int sz = ucam.SnapshotJPEGi(UCAM_JPEG_RESOLUTION_320X240, 512); if (sz == 0) return 0; /* Recieve packets */ int pno = 0; unsigned char cam[512]; while (sz > 0) { int pksz = 512; led2 = ~led2; if (sz < (512 - 6)) pksz = sz + 6; LCDPRINTF("%d %d\n", pno, pksz); /* Recieve a packet */ if (!ucam.SnapshotJPEGd(pno, cam, pksz)) { if (fp != NULL) fclose(fp); return 0; } /* Write the packet */ if (fp != NULL) fwrite(cam + 4, 1, pksz - 6, fp); sz -= (pksz - 6); pno ++; /* Check end of the image */ if (sz == 0) { if (pksz == 512) { // Send reset command as manual says wait_ms(3); ucam.Reset(); ucam.Init(); } else { ucam.ACK_F0F0(); } } } fclose(fp); return 1; }