this will take a image from C328 serial camera and store those images in mbed flash as html and this html page is uploaded into the server at ip:192.168.1.2
Diff: main.cpp
- Revision:
- 0:e1a0471e5ffb
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Wed Dec 15 15:01:56 2010 +0000 @@ -0,0 +1,462 @@ +// Written by IVA2K +// +// Example of HTTPServer with additional features: +// * SNTP Client (Simple NTP) +// * Link status indication (LED4 or RJ45 socket LED on MBED-BoB2-mod) +// * Local file system (create index.htm page on MBED!) +// * SD-based WebServer +// * RPC-able class (myrpc, allows remote function call that blinks LED1 N times) +// * Static HTML page +// * Dynamic HTML page +// +// Instructions: +// 1 Plug MBED into MBED-BoB2 (or other ETH connector breakout) +// 2 Plug ETH connector into your network (needs DHCP to get IP address and Internet connection) +// 3 Power up MBED using USB cable +// 4 Install MBED serial driver (http://mbed.org/handbook/SerialPC) +// 5 Copy compiled .bin to your MBED (make sure target device selected in the compiler is correct) +// 6 Open terminal on the mbed serial port +// 7 Push MBED reset button +// 8 Terminal will display info message with mac address, followed by IP address (if connection succeeds) +// in the following items, replace 10.0.0.321 with actual MBED IP address from the terminal +// 9 Open browser and enter the following URL: +// http://192.168.1.2/rpc/myrpc1/blink,10 +// 10 MBED will blink the LED 10 times +// 11 Open browser and enter the following URL: +// http://192.168.1.2/rpc/myrpc1/gettime +// 12 The browser will show date and time from the MBED synchronized to NTP server +// 13 Open browser and enter the following URL: +// http://192.168.1.2/static.htm +// 14 The browser will show static HTML page +// 15 Open browser and enter the following URL: +// http://192.168.1.2/dynamic.htm +// 16 The browser will show dynamic HTML page +// 17 Create a simple index.htm page on the MBED +// 18 Open browser and enter the following URL: +// http://192.168.1.2 +// 19 The browser will show index HTML page +// 20 Create a simple index.htm page on a micro SD card, plug the card into MBED-BoB2 +// 21 Open browser and enter the following URL: +// http://192.168.1.2 +// 22 The browser will show index HTML page from SD card +// 23 Optionally, create file "sntp.ini" on MBED or SD card. Copy-paste SNTP configuration from the terminal into this file and modify to your needs. +// +// Notes: there are still some bugs in HTTPServer code. +// To help fight some of them, copy a valid favicon.ico (a 16x16 icon) file to MBED. +// + +#include "mbed.h" +#include "SDFileSystem.h" +#include "HTTPServer.h" +#include "HTTPRPC.h" +#include "HTTPFS.h" +#include "HTTPStaticPage.h" +#include "HTTPDynamicPage.h" +#include "HTTPLinkStatus.h" +#include "SNTPClient.h" + +#define CLS "\033[2J" + +const char content[] = +"<HTML>" +"<HEAD>" +"<title>Static Page</title>" +"</HEAD>" +"<BODY>" +"<H1>Hello World</H1>" +"<p>Page generated statically from code.</p>" +"</BODY></HTML>" +; + +#define MAX_DYNAMIC_CONTENT_LEN 2048 +char dynamic_content[MAX_DYNAMIC_CONTENT_LEN]; + +const char content_fmt[] = +"<HTML>" +"<HEAD>" +"<title>Dynamic Page</title>" +"</HEAD>" +"<BODY>" +"<H1>Hello World</H1>" +"<p>Page generated dynamically from code.</p>" +"<p>URL=%s</p>" +"<p>Header Fields=%s</p>" +"</BODY></HTML>" +; + +DigitalOut led1(LED1, "led1"); +DigitalOut led2(LED2, "led2"); +DigitalOut led3(LED3, "led3"); +DigitalOut led4(LED4, "led4"); +DigitalIn sw1(p13, "sw1"); +DigitalIn sw2(p14, "sw2"); +LocalFileSystem local("local"); +//SDFileSystem sd(p5, p6, p7, p8, "sd"); // MBED-BoB2 + +#include "CameraC328.h" + +DigitalIn pir(p6); +DigitalOut led(LED1); + +//InterruptIn PIR(p6); + + +int i=0,j=0; +CameraC328 camera(p9, p10, CameraC328::Baud115200); +const int IMG_X = 80; +const int IMG_Y = 60; +char buf[IMG_X * IMG_Y * 2]; +FILE *fp_jpeg; + +#include "myrpc.h" +myrpc myrpc1(LED1, "myrpc1"); +; + +extern Ethernet eth; // eth is defined elsewhere, avoid compiler error. +Serial pc(USBTX, USBRX); +int gDebug=1; +float gWait = 0.005; // Main loop wait timeout + +HTTPStatus myDynamicPage(HTTPConnection *con, HTTPDynamicPageData *pd) { +#if 0 + // Static example. With this, we don't really need HTTPStaticPage + pd->size = 0; // let it measure our page + pd->page = (char*)content; // Nothing dynamic about that yet, but we can now get loose here. + pd->page_free = NULL; // No mem free() needed +#elif 0 + // Dynamic example, static buffer + pd->size = sprintf(dynamic_content, content_fmt, con->getURL(), con->getHeaderFields()); + pd->page = (char*)dynamic_content; + pd->page_free = NULL; // No mem free() needed +if(pd->size > sizeof(dynamic_content)) printf("ASSERTION FAILED: %s:%d\r\n", __FILE__, __LINE__); // Buffer overrun +#else + // Dynamic example, dynamic buffer + int size = sizeof(content_fmt) + 512; // Just guess how much the data will expand + char *buf = (char *)malloc(size); + if (buf) { + pd->size = sprintf(buf, content_fmt, con->getURL(), con->getHeaderFields()); + pd->page = buf; + pd->page_free = &free; // Use free() when done +if(pd->size > size) printf("ASSERTION FAILED: %s:%d\r\n", __FILE__, __LINE__); // Buffer overrun +#endif + } + return HTTP_OK; +} + + + + + +void uncompressed_callback(size_t done, size_t total, char c) { + buf[done - 1] = c; +} + +void jpeg_callback(char *buf, size_t siz) { + for (int i = 0; i < (int)siz; i++) { + fprintf(fp_jpeg, "%c", buf[i]); + } +} +void sync(void) { + CameraC328::ErrorNumber err = CameraC328::NoError; + + err = camera.sync(); + if (CameraC328::NoError == err) { + printf("[ OK ] : CameraC328::sync\n"); + } else { + printf("[FAIL] : CameraC328::sync (Error=%02X)\n", (int)err); + + } +} + +void test_uncompressed_snapshot_picture(void) { + CameraC328::ErrorNumber err = CameraC328::NoError; + + err = camera.init(CameraC328::Color16bit, CameraC328::RawResolution80x60, CameraC328::JpegResolution160x128); + if (CameraC328::NoError == err) { + printf("[ OK ] : CameraC328::init\n"); + } else { + printf("[FAIL] : CameraC328::init (Error=%02X)\n", (int)err); + } + + for (int i = 0; i < 1; i++) { + err = camera.getUncompressedSnapshotPicture(uncompressed_callback); + if (CameraC328::NoError == err) { + printf("[ OK ] : CameraC328::getUncompressedSnapshotPicture\n"); + } else { + printf("[FAIL] : CameraC328::getUncompressedSnapshotPicture (Error=%02X)\n", (int)err); + } + + char fname[64]; + snprintf(fname, sizeof(fname), "/local/ucss%04d.ppm", i); + FILE *fp = fopen(fname, "w"); + fprintf(fp, "P3\n"); + fprintf(fp, "%d %d\n", IMG_X, IMG_Y); + fprintf(fp, "%d\n", 255); + for (int y = 0; y < IMG_Y; y++) { + for (int x = 0; x < IMG_X; x++) { + int adrofs = y * (IMG_X * 2) + (x * 2); + uint16_t dat = (buf[adrofs + 0] << 8) | (buf[adrofs + 1] << 0); + uint8_t r = ((dat >> 11) & 0x1f) << 3; + uint8_t g = ((dat >> 5) & 0x3f) << 2; + uint8_t b = ((dat >> 0) & 0x1f) << 3; + fprintf(fp,"%d %d %d\n", r, g, b); + } + } + fclose(fp); + } +} + +void test_uncompressed_preview_picture(void) { + CameraC328::ErrorNumber err = CameraC328::NoError; + + err = camera.init(CameraC328::Color16bit, CameraC328::RawResolution80x60, CameraC328::JpegResolution160x128); + if (CameraC328::NoError == err) { + printf("[ OK ] : CameraC328::init\n"); + } else { + printf("[FAIL] : CameraC328::init (Error=%02X)\n", (int)err); + } + + for (int i = 0; i < 1; i++) { + err = camera.getUncompressedPreviewPicture(uncompressed_callback); + if (CameraC328::NoError == err) { + printf("[ OK ] : CameraC328::getUncompressedPreviewPicture\n"); + } else { + printf("[FAIL] : CameraC328::getUncompressedPreviewPicture (Error=%02X)\n", (int)err); + } + + char fname[64]; + snprintf(fname, sizeof(fname), "/local/ucpv%04d.ppm", i); + FILE *fp = fopen(fname, "w"); + fprintf(fp, "P3\n"); + fprintf(fp, "%d %d\n", IMG_X, IMG_Y); + fprintf(fp, "%d\n", 255); + for (int y = 0; y < IMG_Y; y++) { + for (int x = 0; x < IMG_X; x++) { + int adrofs = y * (IMG_X * 2) + (x * 2); + uint16_t dat = (buf[adrofs + 0] << 8) | (buf[adrofs + 1] << 0); + uint8_t r = ((dat >> 11) & 0x1f) << 3; + uint8_t g = ((dat >> 5) & 0x3f) << 2; + uint8_t b = ((dat >> 0) & 0x1f) << 3; + fprintf(fp,"%d %d %d\n", r, g, b); + } + } + fclose(fp); + } +} + +void test_jpeg_snapshot_picture(void) { + CameraC328::ErrorNumber err = CameraC328::NoError; + + err = camera.init(CameraC328::Jpeg, CameraC328::RawResolution160x120, CameraC328::JpegResolution640x480); + if (CameraC328::NoError == err) { + printf("[ OK ] : CameraC328::init\n"); + } else { + printf("[FAIL] : CameraC328::init (Error=%02X)\n", (int)err); + } + + for (int i = 0; i < 1; i++) { + char fname[64]; + snprintf(fname, sizeof(fname), "/local/jpss%04d.jpg", i); + fp_jpeg = fopen(fname, "w"); + + err = camera.getJpegSnapshotPicture(jpeg_callback); + if (CameraC328::NoError == err) { + printf("[ OK ] : CameraC328::getJpegSnapshotPicture\n"); + } else { + printf("[FAIL] : CameraC328::getJpegSnapshotPicture (Error=%02X)\n", (int)err); + } + + fclose(fp_jpeg); + } +} + +void test_jpeg_preview_picture(void) { + sync(); + CameraC328::ErrorNumber err = CameraC328::NoError; + + err = camera.init(CameraC328::Jpeg, CameraC328::RawResolution160x120, CameraC328::JpegResolution640x480); + if (CameraC328::NoError == err) { + printf("[ OK ] : CameraC328::init\n"); + } else { + printf("[FAIL] : CameraC328::init (Error=%02X)\n", (int)err); + } + + //for (int i = 0; i < 1; i++) { + char fname[64]; + + snprintf(fname, sizeof(fname), "/local/jppv%04d.jpg", j++); + fp_jpeg = fopen(fname, "w"); + i=j; + if(i>10) + i=0; + + err = camera.getJpegPreviewPicture(jpeg_callback); + if (CameraC328::NoError == err) { + printf("[ OK ] : CameraC328::getJpegPreviewPicture\n"); + } else { + printf("[FAIL] : CameraC328::getJpegPreviewPicture (Error=%02X)\n", (int)err); + } + + + + + fclose(fp_jpeg); + + FILE *fp = fopen("/local/index.htm", "w"); // Open local filename + + + fprintf(fp, "<title> cam images </title>\n"); + + fprintf(fp, "<body> camera pictures page "); + fprintf(fp,"<META HTTP-EQUIV='Refresh'CONTENT='10; URL=192.168.1.2'>"); + fprintf(fp,"<div id='my_area' align='left'>"); + + if(i>=1) + fprintf(fp, "<IMG SRC='jppv0000.jpg' width='100' height='100' alt='image1' >" ); + if(i>=2){ + fprintf(fp, "<IMG SRC='jppv0001.jpg' width='100' height='100' alt='image2'>"); + } + if(i>=3){ + fprintf(fp, "<IMG SRC='jppv0002.jpg' width='100' height='100' alt='image3'>"); + } + if(i>=4){ + fprintf(fp, "<IMG SRC='jppv0003.jpg' width='100' height='100' alt='image4'>"); + } + if(i>=5){ + fprintf(fp, "<IMG SRC='jppv0004.jpg' width='100' height='100' alt='image5'>"); + } + if(i>=6){ + fprintf(fp, "<IMG SRC='jppv0004.jpg' width='100' height='100' alt='image6'>"); + } + if(i>=7){ + fprintf(fp, "<IMG SRC='jppv0004.jpg' width='100' height='100' alt='image7'>"); + } + if(i>=8){ + fprintf(fp, "<IMG SRC='jppv0004.jpg' width='100' height='100' alt='image8'>"); + } + if(i>=9){ + fprintf(fp, "<IMG SRC='jppv0004.jpg' width='100' height='100' alt='image9'>"); + } + if(i>=10){ + fprintf(fp, "<IMG SRC='jppv0004.jpg' width='100' height='100' alt='image10'>"); + fprintf(fp, "plz remove the images"); + } + /* else*/ + // fprintf(fp,"PLZ clear the images"); + fprintf(fp, " </body>\n"); + fprintf(fp, "</a>"); + fclose(fp); + + + //} +} + + + + +int main(void) { + char mac[6]; + int sw1_old=0, sw2_old=0; + bool use_sd = false; + + led1=1; + led2=1; + led3=1; + led4=1; + + // Start RTC + time_t seconds = time(NULL); + if (seconds == (unsigned)-1 || seconds == 0) { + seconds = 1256729737; // Set RTC time to Wed, 28 Oct 2009 11:35:37 + set_time(seconds); + printf("RTC initialized, start time %d seconds\r\n", seconds); + } + + char *hostname = "mbed"; + HTTPServer http(hostname); // Use DHCP + http.timeout(10000); // Sets the timout for a HTTP request. The timout is the time which is allowed to spent between two incomming TCP packets. If the time is passed the connection will be closed. + + eth.address(mac); + pc.printf(CLS "\r\n\r\nHTTPServer \"%s\" started\r\nMAC %02X:%02X:%02X:%02X:%02X:%02X\r\n%s", + hostname, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], + gDebug?"Debug is ON\r\n":"" + ); + + Base::add_rpc_class<AnalogIn>(); + Base::add_rpc_class<AnalogOut>(); + Base::add_rpc_class<DigitalIn>(); + Base::add_rpc_class<DigitalOut>(); + Base::add_rpc_class<PwmOut>(); + Base::add_rpc_class<Timer>(); + Base::add_rpc_class<SPI>(); + Base::add_rpc_class<BusOut>(); + Base::add_rpc_class<BusIn>(); + Base::add_rpc_class<myrpc>(); + led1=0; + + // Check if we can use SD card for the web server + FILE *fp = fopen("/sd/index.htm", "r"); + + if (fp == NULL) { + if (gDebug) printf("DEBUG: No SD card found or no index.htm file - using LocalFilesystem for WebServer.\r\n"); + } else { + use_sd = true; + fclose(fp); + if (gDebug) printf("DEBUG: Found SD card with index.htm file - using SD for WebServer.\r\n"); + } + + if (0 != SNTPReadIniFile("/sd/sntp.ini") ) + SNTPReadIniFile("/local/sntp.ini"); + SNTPWriteIniFile(stdout); + + + http.addHandler(new HTTPLinkStatus("/", +#if MBED_BOB2 + p25, p26, // MBED-BoB2-mods +#else + LED3, LED4, +#endif + 0.1, + /*do_urlfile*/ true, /*do_link_printf*/ true, /*do_log_printf*/ false, + /*log_file*/ ( (gDebug>1) ? (use_sd ? "/sd/httpd.log" : "/local/httpd.log") : NULL) + )); // Should be the first handler to get a preview of all requests + http.addHandler(new HTTPRPC()); + led2=0; + + // Static/Dynamic pages must be installed before FileSystem on / + http.addHandler(new HTTPStaticPage("/static.htm", content, strlen(content))); + http.addHandler(new HTTPDynamicPage("/dynamic.htm", &myDynamicPage)); + http.addHandler(new HTTPFileSystemHandler("/", use_sd ? "/sd/" : "/local/")); + led3=0; + +// FIXME: BUG If eth is not plugged, http.bind() hangs! + http.bind(); + + SNTPClientInit(); + led4 = 0; + + // printf("CameraC328\n"); + // sync(); + + pc.printf("\r"); // Add linefeed for stupid Hyperterminal + while(1) { + http.poll(); // Have to call this method at least every 250ms to let the http server run. + if (sw1 & !sw1_old) { + printf("SW1\r\n"); + } + if (sw2 && !sw2_old) { + printf(CLS "SW2\r\n"); + } + sw1_old = sw1; + sw2_old = sw2; + + if(pir==1){ + printf("somebody detected\n"); + + test_jpeg_preview_picture(); + } + wait(gWait); + } +} + +//END \ No newline at end of file