Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
main.cpp
00001 // Written by IVA2K 00002 // 00003 // Example of HTTPServer with additional features: 00004 // * SNTP Client (Simple NTP) 00005 // * Link status indication (LED4 or RJ45 socket LED on MBED-BoB2-mod) 00006 // * Local file system (create index.htm page on MBED!) 00007 // * SD-based WebServer 00008 // * RPC-able class (myrpc, allows remote function call that blinks LED1 N times) 00009 // * Static HTML page 00010 // * Dynamic HTML page 00011 // 00012 // Instructions: 00013 // 1 Plug MBED into MBED-BoB2 (or other ETH connector breakout) 00014 // 2 Plug ETH connector into your network (needs DHCP to get IP address and Internet connection) 00015 // 3 Power up MBED using USB cable 00016 // 4 Install MBED serial driver (http://mbed.org/handbook/SerialPC) 00017 // 5 Copy compiled .bin to your MBED (make sure target device selected in the compiler is correct) 00018 // 6 Open terminal on the mbed serial port 00019 // 7 Push MBED reset button 00020 // 8 Terminal will display info message with mac address, followed by IP address (if connection succeeds) 00021 // in the following items, replace 10.0.0.321 with actual MBED IP address from the terminal 00022 // 9 Open browser and enter the following URL: 00023 // http://192.168.1.2/rpc/myrpc1/blink,10 00024 // 10 MBED will blink the LED 10 times 00025 // 11 Open browser and enter the following URL: 00026 // http://192.168.1.2/rpc/myrpc1/gettime 00027 // 12 The browser will show date and time from the MBED synchronized to NTP server 00028 // 13 Open browser and enter the following URL: 00029 // http://192.168.1.2/static.htm 00030 // 14 The browser will show static HTML page 00031 // 15 Open browser and enter the following URL: 00032 // http://192.168.1.2/dynamic.htm 00033 // 16 The browser will show dynamic HTML page 00034 // 17 Create a simple index.htm page on the MBED 00035 // 18 Open browser and enter the following URL: 00036 // http://192.168.1.2 00037 // 19 The browser will show index HTML page 00038 // 20 Create a simple index.htm page on a micro SD card, plug the card into MBED-BoB2 00039 // 21 Open browser and enter the following URL: 00040 // http://192.168.1.2 00041 // 22 The browser will show index HTML page from SD card 00042 // 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. 00043 // 00044 // Notes: there are still some bugs in HTTPServer code. 00045 // To help fight some of them, copy a valid favicon.ico (a 16x16 icon) file to MBED. 00046 // 00047 00048 #include "mbed.h" 00049 #include "SDFileSystem.h" 00050 #include "HTTPServer.h" 00051 #include "HTTPRPC.h" 00052 #include "HTTPFS.h" 00053 #include "HTTPStaticPage.h" 00054 #include "HTTPDynamicPage.h" 00055 #include "HTTPLinkStatus.h" 00056 #include "SNTPClient.h" 00057 00058 #define CLS "\033[2J" 00059 00060 const char content[] = 00061 "<HTML>" 00062 "<HEAD>" 00063 "<title>Static Page</title>" 00064 "</HEAD>" 00065 "<BODY>" 00066 "<H1>Hello World</H1>" 00067 "<p>Page generated statically from code.</p>" 00068 "</BODY></HTML>" 00069 ; 00070 00071 #define MAX_DYNAMIC_CONTENT_LEN 2048 00072 char dynamic_content[MAX_DYNAMIC_CONTENT_LEN]; 00073 00074 const char content_fmt[] = 00075 "<HTML>" 00076 "<HEAD>" 00077 "<title>Dynamic Page</title>" 00078 "</HEAD>" 00079 "<BODY>" 00080 "<H1>Hello World</H1>" 00081 "<p>Page generated dynamically from code.</p>" 00082 "<p>URL=%s</p>" 00083 "<p>Header Fields=%s</p>" 00084 "</BODY></HTML>" 00085 ; 00086 00087 DigitalOut led1(LED1, "led1"); 00088 DigitalOut led2(LED2, "led2"); 00089 DigitalOut led3(LED3, "led3"); 00090 DigitalOut led4(LED4, "led4"); 00091 DigitalIn sw1(p13, "sw1"); 00092 DigitalIn sw2(p14, "sw2"); 00093 LocalFileSystem local("local"); 00094 //SDFileSystem sd(p5, p6, p7, p8, "sd"); // MBED-BoB2 00095 00096 #include "CameraC328.h" 00097 00098 DigitalIn pir(p6); 00099 DigitalOut led(LED1); 00100 00101 //InterruptIn PIR(p6); 00102 00103 00104 int i=0,j=0; 00105 CameraC328 camera(p9, p10, CameraC328::Baud115200); 00106 const int IMG_X = 80; 00107 const int IMG_Y = 60; 00108 char buf[IMG_X * IMG_Y * 2]; 00109 FILE *fp_jpeg; 00110 00111 #include "myrpc.h" 00112 myrpc myrpc1(LED1, "myrpc1"); 00113 ; 00114 00115 extern Ethernet eth; // eth is defined elsewhere, avoid compiler error. 00116 Serial pc(USBTX, USBRX); 00117 int gDebug=1; 00118 float gWait = 0.005; // Main loop wait timeout 00119 00120 HTTPStatus myDynamicPage(HTTPConnection *con, HTTPDynamicPageData *pd) { 00121 #if 0 00122 // Static example. With this, we don't really need HTTPStaticPage 00123 pd->size = 0; // let it measure our page 00124 pd->page = (char*)content; // Nothing dynamic about that yet, but we can now get loose here. 00125 pd->page_free = NULL; // No mem free() needed 00126 #elif 0 00127 // Dynamic example, static buffer 00128 pd->size = sprintf(dynamic_content, content_fmt, con->getURL(), con->getHeaderFields()); 00129 pd->page = (char*)dynamic_content; 00130 pd->page_free = NULL; // No mem free() needed 00131 if(pd->size > sizeof(dynamic_content)) printf("ASSERTION FAILED: %s:%d\r\n", __FILE__, __LINE__); // Buffer overrun 00132 #else 00133 // Dynamic example, dynamic buffer 00134 int size = sizeof(content_fmt) + 512; // Just guess how much the data will expand 00135 char *buf = (char *)malloc(size); 00136 if (buf) { 00137 pd->size = sprintf(buf, content_fmt, con->getURL(), con->getHeaderFields()); 00138 pd->page = buf; 00139 pd->page_free = &free; // Use free() when done 00140 if(pd->size > size) printf("ASSERTION FAILED: %s:%d\r\n", __FILE__, __LINE__); // Buffer overrun 00141 #endif 00142 } 00143 return HTTP_OK; 00144 } 00145 00146 00147 00148 00149 00150 void uncompressed_callback(size_t done, size_t total, char c) { 00151 buf[done - 1] = c; 00152 } 00153 00154 void jpeg_callback(char *buf, size_t siz) { 00155 for (int i = 0; i < (int)siz; i++) { 00156 fprintf(fp_jpeg, "%c", buf[i]); 00157 } 00158 } 00159 void sync(void) { 00160 CameraC328::ErrorNumber err = CameraC328::NoError; 00161 00162 err = camera.sync(); 00163 if (CameraC328::NoError == err) { 00164 printf("[ OK ] : CameraC328::sync\n"); 00165 } else { 00166 printf("[FAIL] : CameraC328::sync (Error=%02X)\n", (int)err); 00167 00168 } 00169 } 00170 00171 void test_uncompressed_snapshot_picture(void) { 00172 CameraC328::ErrorNumber err = CameraC328::NoError; 00173 00174 err = camera.init(CameraC328::Color16bit, CameraC328::RawResolution80x60, CameraC328::JpegResolution160x128); 00175 if (CameraC328::NoError == err) { 00176 printf("[ OK ] : CameraC328::init\n"); 00177 } else { 00178 printf("[FAIL] : CameraC328::init (Error=%02X)\n", (int)err); 00179 } 00180 00181 for (int i = 0; i < 1; i++) { 00182 err = camera.getUncompressedSnapshotPicture(uncompressed_callback); 00183 if (CameraC328::NoError == err) { 00184 printf("[ OK ] : CameraC328::getUncompressedSnapshotPicture\n"); 00185 } else { 00186 printf("[FAIL] : CameraC328::getUncompressedSnapshotPicture (Error=%02X)\n", (int)err); 00187 } 00188 00189 char fname[64]; 00190 snprintf(fname, sizeof(fname), "/local/ucss%04d.ppm", i); 00191 FILE *fp = fopen(fname, "w"); 00192 fprintf(fp, "P3\n"); 00193 fprintf(fp, "%d %d\n", IMG_X, IMG_Y); 00194 fprintf(fp, "%d\n", 255); 00195 for (int y = 0; y < IMG_Y; y++) { 00196 for (int x = 0; x < IMG_X; x++) { 00197 int adrofs = y * (IMG_X * 2) + (x * 2); 00198 uint16_t dat = (buf[adrofs + 0] << 8) | (buf[adrofs + 1] << 0); 00199 uint8_t r = ((dat >> 11) & 0x1f) << 3; 00200 uint8_t g = ((dat >> 5) & 0x3f) << 2; 00201 uint8_t b = ((dat >> 0) & 0x1f) << 3; 00202 fprintf(fp,"%d %d %d\n", r, g, b); 00203 } 00204 } 00205 fclose(fp); 00206 } 00207 } 00208 00209 void test_uncompressed_preview_picture(void) { 00210 CameraC328::ErrorNumber err = CameraC328::NoError; 00211 00212 err = camera.init(CameraC328::Color16bit, CameraC328::RawResolution80x60, CameraC328::JpegResolution160x128); 00213 if (CameraC328::NoError == err) { 00214 printf("[ OK ] : CameraC328::init\n"); 00215 } else { 00216 printf("[FAIL] : CameraC328::init (Error=%02X)\n", (int)err); 00217 } 00218 00219 for (int i = 0; i < 1; i++) { 00220 err = camera.getUncompressedPreviewPicture(uncompressed_callback); 00221 if (CameraC328::NoError == err) { 00222 printf("[ OK ] : CameraC328::getUncompressedPreviewPicture\n"); 00223 } else { 00224 printf("[FAIL] : CameraC328::getUncompressedPreviewPicture (Error=%02X)\n", (int)err); 00225 } 00226 00227 char fname[64]; 00228 snprintf(fname, sizeof(fname), "/local/ucpv%04d.ppm", i); 00229 FILE *fp = fopen(fname, "w"); 00230 fprintf(fp, "P3\n"); 00231 fprintf(fp, "%d %d\n", IMG_X, IMG_Y); 00232 fprintf(fp, "%d\n", 255); 00233 for (int y = 0; y < IMG_Y; y++) { 00234 for (int x = 0; x < IMG_X; x++) { 00235 int adrofs = y * (IMG_X * 2) + (x * 2); 00236 uint16_t dat = (buf[adrofs + 0] << 8) | (buf[adrofs + 1] << 0); 00237 uint8_t r = ((dat >> 11) & 0x1f) << 3; 00238 uint8_t g = ((dat >> 5) & 0x3f) << 2; 00239 uint8_t b = ((dat >> 0) & 0x1f) << 3; 00240 fprintf(fp,"%d %d %d\n", r, g, b); 00241 } 00242 } 00243 fclose(fp); 00244 } 00245 } 00246 00247 void test_jpeg_snapshot_picture(void) { 00248 CameraC328::ErrorNumber err = CameraC328::NoError; 00249 00250 err = camera.init(CameraC328::Jpeg, CameraC328::RawResolution160x120, CameraC328::JpegResolution640x480); 00251 if (CameraC328::NoError == err) { 00252 printf("[ OK ] : CameraC328::init\n"); 00253 } else { 00254 printf("[FAIL] : CameraC328::init (Error=%02X)\n", (int)err); 00255 } 00256 00257 for (int i = 0; i < 1; i++) { 00258 char fname[64]; 00259 snprintf(fname, sizeof(fname), "/local/jpss%04d.jpg", i); 00260 fp_jpeg = fopen(fname, "w"); 00261 00262 err = camera.getJpegSnapshotPicture(jpeg_callback); 00263 if (CameraC328::NoError == err) { 00264 printf("[ OK ] : CameraC328::getJpegSnapshotPicture\n"); 00265 } else { 00266 printf("[FAIL] : CameraC328::getJpegSnapshotPicture (Error=%02X)\n", (int)err); 00267 } 00268 00269 fclose(fp_jpeg); 00270 } 00271 } 00272 00273 void test_jpeg_preview_picture(void) { 00274 sync(); 00275 CameraC328::ErrorNumber err = CameraC328::NoError; 00276 00277 err = camera.init(CameraC328::Jpeg, CameraC328::RawResolution160x120, CameraC328::JpegResolution640x480); 00278 if (CameraC328::NoError == err) { 00279 printf("[ OK ] : CameraC328::init\n"); 00280 } else { 00281 printf("[FAIL] : CameraC328::init (Error=%02X)\n", (int)err); 00282 } 00283 00284 //for (int i = 0; i < 1; i++) { 00285 char fname[64]; 00286 00287 snprintf(fname, sizeof(fname), "/local/jppv%04d.jpg", j++); 00288 fp_jpeg = fopen(fname, "w"); 00289 i=j; 00290 if(i>10) 00291 i=0; 00292 00293 err = camera.getJpegPreviewPicture(jpeg_callback); 00294 if (CameraC328::NoError == err) { 00295 printf("[ OK ] : CameraC328::getJpegPreviewPicture\n"); 00296 } else { 00297 printf("[FAIL] : CameraC328::getJpegPreviewPicture (Error=%02X)\n", (int)err); 00298 } 00299 00300 00301 00302 00303 fclose(fp_jpeg); 00304 00305 FILE *fp = fopen("/local/index.htm", "w"); // Open local filename 00306 00307 00308 fprintf(fp, "<title> cam images </title>\n"); 00309 00310 fprintf(fp, "<body> camera pictures page "); 00311 fprintf(fp,"<META HTTP-EQUIV='Refresh'CONTENT='10; URL=192.168.1.2'>"); 00312 fprintf(fp,"<div id='my_area' align='left'>"); 00313 00314 if(i>=1) 00315 fprintf(fp, "<IMG SRC='jppv0000.jpg' width='100' height='100' alt='image1' >" ); 00316 if(i>=2){ 00317 fprintf(fp, "<IMG SRC='jppv0001.jpg' width='100' height='100' alt='image2'>"); 00318 } 00319 if(i>=3){ 00320 fprintf(fp, "<IMG SRC='jppv0002.jpg' width='100' height='100' alt='image3'>"); 00321 } 00322 if(i>=4){ 00323 fprintf(fp, "<IMG SRC='jppv0003.jpg' width='100' height='100' alt='image4'>"); 00324 } 00325 if(i>=5){ 00326 fprintf(fp, "<IMG SRC='jppv0004.jpg' width='100' height='100' alt='image5'>"); 00327 } 00328 if(i>=6){ 00329 fprintf(fp, "<IMG SRC='jppv0004.jpg' width='100' height='100' alt='image6'>"); 00330 } 00331 if(i>=7){ 00332 fprintf(fp, "<IMG SRC='jppv0004.jpg' width='100' height='100' alt='image7'>"); 00333 } 00334 if(i>=8){ 00335 fprintf(fp, "<IMG SRC='jppv0004.jpg' width='100' height='100' alt='image8'>"); 00336 } 00337 if(i>=9){ 00338 fprintf(fp, "<IMG SRC='jppv0004.jpg' width='100' height='100' alt='image9'>"); 00339 } 00340 if(i>=10){ 00341 fprintf(fp, "<IMG SRC='jppv0004.jpg' width='100' height='100' alt='image10'>"); 00342 fprintf(fp, "plz remove the images"); 00343 } 00344 /* else*/ 00345 // fprintf(fp,"PLZ clear the images"); 00346 fprintf(fp, " </body>\n"); 00347 fprintf(fp, "</a>"); 00348 fclose(fp); 00349 00350 00351 //} 00352 } 00353 00354 00355 00356 00357 int main(void) { 00358 char mac[6]; 00359 int sw1_old=0, sw2_old=0; 00360 bool use_sd = false; 00361 00362 led1=1; 00363 led2=1; 00364 led3=1; 00365 led4=1; 00366 00367 // Start RTC 00368 time_t seconds = time(NULL); 00369 if (seconds == (unsigned)-1 || seconds == 0) { 00370 seconds = 1256729737; // Set RTC time to Wed, 28 Oct 2009 11:35:37 00371 set_time(seconds); 00372 printf("RTC initialized, start time %d seconds\r\n", seconds); 00373 } 00374 00375 char *hostname = "mbed"; 00376 HTTPServer http(hostname); // Use DHCP 00377 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. 00378 00379 eth.address(mac); 00380 pc.printf(CLS "\r\n\r\nHTTPServer \"%s\" started\r\nMAC %02X:%02X:%02X:%02X:%02X:%02X\r\n%s", 00381 hostname, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], 00382 gDebug?"Debug is ON\r\n":"" 00383 ); 00384 00385 Base::add_rpc_class<AnalogIn>(); 00386 Base::add_rpc_class<AnalogOut>(); 00387 Base::add_rpc_class<DigitalIn>(); 00388 Base::add_rpc_class<DigitalOut>(); 00389 Base::add_rpc_class<PwmOut>(); 00390 Base::add_rpc_class<Timer>(); 00391 Base::add_rpc_class<SPI>(); 00392 Base::add_rpc_class<BusOut>(); 00393 Base::add_rpc_class<BusIn>(); 00394 Base::add_rpc_class<myrpc>(); 00395 led1=0; 00396 00397 // Check if we can use SD card for the web server 00398 FILE *fp = fopen("/sd/index.htm", "r"); 00399 00400 if (fp == NULL) { 00401 if (gDebug) printf("DEBUG: No SD card found or no index.htm file - using LocalFilesystem for WebServer.\r\n"); 00402 } else { 00403 use_sd = true; 00404 fclose(fp); 00405 if (gDebug) printf("DEBUG: Found SD card with index.htm file - using SD for WebServer.\r\n"); 00406 } 00407 00408 if (0 != SNTPReadIniFile("/sd/sntp.ini") ) 00409 SNTPReadIniFile("/local/sntp.ini"); 00410 SNTPWriteIniFile(stdout); 00411 00412 00413 http.addHandler(new HTTPLinkStatus("/", 00414 #if MBED_BOB2 00415 p25, p26, // MBED-BoB2-mods 00416 #else 00417 LED3, LED4, 00418 #endif 00419 0.1, 00420 /*do_urlfile*/ true, /*do_link_printf*/ true, /*do_log_printf*/ false, 00421 /*log_file*/ ( (gDebug>1) ? (use_sd ? "/sd/httpd.log" : "/local/httpd.log") : NULL) 00422 )); // Should be the first handler to get a preview of all requests 00423 http.addHandler(new HTTPRPC()); 00424 led2=0; 00425 00426 // Static/Dynamic pages must be installed before FileSystem on / 00427 http.addHandler(new HTTPStaticPage("/static.htm", content, strlen(content))); 00428 http.addHandler(new HTTPDynamicPage("/dynamic.htm", &myDynamicPage)); 00429 http.addHandler(new HTTPFileSystemHandler("/", use_sd ? "/sd/" : "/local/")); 00430 led3=0; 00431 00432 // FIXME: BUG If eth is not plugged, http.bind() hangs! 00433 http.bind(); 00434 00435 SNTPClientInit(); 00436 led4 = 0; 00437 00438 // printf("CameraC328\n"); 00439 // sync(); 00440 00441 pc.printf("\r"); // Add linefeed for stupid Hyperterminal 00442 while(1) { 00443 http.poll(); // Have to call this method at least every 250ms to let the http server run. 00444 if (sw1 & !sw1_old) { 00445 printf("SW1\r\n"); 00446 } 00447 if (sw2 && !sw2_old) { 00448 printf(CLS "SW2\r\n"); 00449 } 00450 sw1_old = sw1; 00451 sw2_old = sw2; 00452 00453 if(pir==1){ 00454 printf("somebody detected\n"); 00455 00456 test_jpeg_preview_picture(); 00457 } 00458 wait(gWait); 00459 } 00460 } 00461 00462 //END
Generated on Tue Jul 12 2022 20:39:37 by
1.7.2