In this example, the image data acquired from the camera is stored on the Micro SD card and displayed through a web browser.
Dependencies: Ethernet_Camera_LS_Y201_SDcard SDFileSystem WIZnetInterface mbed
Fork of HTTP_SDcard_file_server_WIZwiki-W7500 by
Prerequisite
In this example, the image data acquired from the camera is stored on the Micro SD card and displayed through a web browser.
To implement this function, you need a Platform board, network Interface board, camera module.
This example uses LS-Y201 Camera module.
- WIZwiki-W7500 from WIZnet (Platform board and Ethernet I/F board)
- LS-Y201 (Camera module)
- Micro SD Card
Hardware Configuration
- connect Ethernet Cable & USB Cable
- connect Camera module
Software
Init network information
#define IP "192.168.0.100" #define MASK "255.255.255.0" #define GATEWAY "192.168.0.1" #define PORT 80
Caution
Must fix network information
Revision 0:fbb29d9ea96b, committed 2013-04-07
- Comitter:
- azsymaivan
- Date:
- Sun Apr 07 11:23:03 2013 +0000
- Child:
- 1:7d3ed406dd3d
- Commit message:
- HTTP Server, using SD card and EthernetInterface. This code work, but sometimes mbed frizing. Always frizing occurs when mbed sent information to HTTP client. Exactly when call function tcpip_apimsg(struct api_msg *apimsg) in file "tcpip.c".
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/EthernetInterface.lib Sun Apr 07 11:23:03 2013 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/EthernetInterface/#9b2d10dc0392
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SDFileSystem.lib Sun Apr 07 11:23:03 2013 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/azsymaivan/code/SDFileSystem/#f242d7bdef28
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/filelib.h Sun Apr 07 11:23:03 2013 +0000
@@ -0,0 +1,127 @@
+#ifndef filelib
+#define filelib
+
+#include "mbed.h"
+#include <time.h>
+#include <ff.h> //found in lib SDFileSystem->FATFileSystem/ChaN
+#include "SDFileSystem.h"
+
+
+/*
+typedef enum {
+ FR_OK = 0, // (0) Succeeded
+ FR_DISK_ERR, // (1) A hard error occurred in the low level disk I/O layer
+ FR_INT_ERR, // (2) Assertion failed
+ FR_NOT_READY, // (3) The physical drive cannot work
+ FR_NO_FILE, // (4) Could not find the file
+ FR_NO_PATH, // (5) Could not find the path
+ FR_INVALID_NAME, // (6) The path name format is invalid
+ FR_DENIED, // (7) Access denied due to prohibited access or directory full
+ FR_EXIST, // (8) Access denied due to prohibited access
+ FR_INVALID_OBJECT, // (9) The file/directory object is invalid
+ FR_WRITE_PROTECTED, // (10) The physical drive is write protected
+ FR_INVALID_DRIVE, // (11) The logical drive number is invalid
+ FR_NOT_ENABLED, // (12) The volume has no work area
+ FR_NO_FILESYSTEM, // (13) There is no valid FAT volume
+ FR_MKFS_ABORTED, // (14) The f_mkfs() aborted due to any parameter error
+ FR_TIMEOUT, // (15) Could not get a grant to access the volume within defined period
+ FR_LOCKED, // (16) The operation is rejected according to the file sharing policy
+ FR_NOT_ENOUGH_CORE, // (17) LFN working buffer could not be allocated
+ FR_TOO_MANY_OPEN_FILES, // (18) Number of open files > _FS_SHARE
+ FR_INVALID_PARAMETER // (19) Given parameter is invalid
+} FRESULT;
+
+*/
+/*
+mode_t values in octal
+ S_IFREG 0100000
+ S_IFDIR 040000
+ S_IRUSR 0400 read permission, owner
+ S_IWUSR 0200 write permission, owner
+ S_IXUSR 0100 execute/search permission, owner
+ S_IRGRP 040 read permission, group
+ S_IWGRP 020 write permission, group
+ S_IXGRP 010 execute/search permission, group
+ S_IROTH 04 read permission, others
+ S_IWOTH 02 write permission, others
+ S_IXOTH 01 execute/search permission, others
+*/
+struct sMystat {
+// dev_t st_dev; /* ID of device containing file */
+// ino_t st_ino; /* inode number */
+ mode_t st_mode; /* protection */
+// nlink_t st_nlink; /* number of hard links */
+// uid_t st_uid; /* user ID of owner */
+// gid_t st_gid; /* group ID of owner */
+// dev_t st_rdev; /* device ID (if special file) */
+ // off_t st_size; /* total size, in bytes */
+ DWORD st_size; /* total size, in bytes */
+// blksize_t st_blksize; /* blocksize for file system I/O */
+// blkcnt_t st_blocks; /* number of 512B blocks allocated */
+// time_t st_atime; /* time of last access */
+ time_t st_mtime; /* time of last modification */
+// time_t st_ctime; /* time of last status change */
+};
+
+sMystat myStatBuf; //store info for file
+FILINFO finfo; //global file info struct see ff.h
+FATFS_DIR dinfo; //global directoty info struct see ff.h
+
+FRESULT get_fileInfo(const char *path) //use finfo for get result fields
+{
+ FRESULT res = f_stat(path,&finfo); /* Get file status */
+ if (EnDebugMSG)
+ if (res)
+ printf("\n-->get_fileInfo:%s ,res=%d ,Not Found!",path,res);
+ else
+ printf("\n-->get_fileInfo:%s ,res=%d ,Found!",path,res);
+ return res;
+}
+
+FRESULT get_dirInfo(const char *path)
+{
+ FRESULT res= f_opendir (&dinfo,path); /* FR_OK(0): successful, !=0: error code */
+ if (EnDebugMSG)
+ if (res)
+ printf("\n-->get_dirInfo :%s res=%d ,This is Not Directory!",path,res);
+ else
+ printf("\n-->get_dirInfo :%s res=%d ,This is Directory!",path,res);
+ return res;
+}
+
+FRESULT Mystat(const char *path, struct sMystat *buf)
+{
+ FRESULT res = f_stat(path,&finfo); /* Get file status */
+ if (res == FR_OK) {
+ buf->st_size = finfo.fsize;
+ buf->st_mtime = finfo.ftime; //fdate;
+ buf->st_mode = 4; //?
+ }
+ if (EnDebugMSG)
+ printf("\n--Mystat Path:%s ,filesize:%14lld ,res=%d",path, buf->st_size, res);
+ return res;
+}
+
+
+static char* get_mime_type( char* filename )
+{
+ char* extension;
+ extension = strrchr( filename, '.' ); //get string after last .
+ if (EnDebugMSG)
+ printf("\n-->get_mime_tipe filename:%s, extension:%s",filename, extension);
+ if (extension !=NULL) {
+ if (strcasecmp(extension,".htm")==0 || strcasecmp(extension,".html") ==0)
+ return "text/html; charset=iso-8859-1";
+ if (strcasecmp(extension,".png")==0)
+ return "image/png";
+ if (strcasecmp(extension,".css")==0)
+ return "text/css";
+ if (strcasecmp(extension,".gif")==0)
+ return "image/gif";
+ if (strcasecmp(extension,".jpg")==0 || strcasecmp(extension,".jpeg" )==0)
+ return "image/jpeg";
+ }
+ return "text/plain; charset=iso-8859-1";
+}
+
+#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp Sun Apr 07 11:23:03 2013 +0000
@@ -0,0 +1,370 @@
+#include "mbed.h"
+#include "EthernetInterface.h"
+#include "SDFileSystem.h"
+
+#define EnDebugMSG false //true-> print debug message to PC USB terminal, false->not print
+#include "filelib.h"
+
+#define IP "192.168.100.100"
+#define MASK "255.255.255.0"
+#define GATEWAY "192.168.100.1"
+#define PORT 80
+
+Serial pc (USBTX,USBRX); // tx, rx
+SDFileSystem sd(p5, p6, p7, p8, "wfs"); // the pinout on the mbed
+
+char sMethod[7];
+char sURL[250];
+char sProtocol[8];
+
+EthernetInterface eth;
+
+TCPSocketServer svr;
+bool serverIsListened = false;
+
+TCPSocketConnection client;
+bool clientIsConnected = false;
+
+char sentBuffer[1608] = {}; // 2*536=1072, 3*536=1608, 4*536=2144 !1500
+char line_response[256]= {0};
+char file_path[256] = {0};
+
+DigitalOut led1(LED1); //server listning status
+DigitalOut led2(LED2); //socket connecting status
+
+Ticker ledTick;
+
+void ledTickfunc()
+{
+ if(serverIsListened) {
+ led1 = !led1;
+ } else {
+ led1 = false;
+ }
+}
+
+void send_HTTP_header(char* protocol, int code, char* title, char* mime_type, long long lengthBody)
+{
+ snprintf(line_response, sizeof(line_response),"%s %d %s\r\n", protocol, code, title );
+ snprintf(sentBuffer, sizeof(sentBuffer),"%s",line_response);
+
+ if ( mime_type != NULL ) {
+ snprintf(line_response, sizeof(line_response), "Content-Type: %s\r\n", mime_type );
+ snprintf(sentBuffer, sizeof(sentBuffer), "%s%s",sentBuffer,line_response); //append to sentBuffer
+ }
+ if ( lengthBody >= 0 ) {
+ snprintf(line_response, sizeof(line_response), "Content-Length: %lld\r\n", lengthBody );
+ snprintf(sentBuffer, sizeof(sentBuffer), "%s%s",sentBuffer,line_response); //append to sentBuffer
+ }
+ snprintf(line_response, sizeof(line_response), "Connection: close\r\n" );
+ snprintf(sentBuffer, sizeof(sentBuffer),"%s%s\r\n",sentBuffer,line_response); //append to sentBuffer
+
+ if (EnDebugMSG)
+ printf("\n-->sent Header--\n");
+
+ client.send_all(sentBuffer,strlen(sentBuffer));
+ if (EnDebugMSG) {
+ printf(sentBuffer);
+ printf("\n--end Header-- bytes:%d",strlen(sentBuffer));
+ }
+ Thread::wait(200); //200ms important for browser!
+}
+
+void send_HTML_line(char* line, unsigned int length_line)
+{
+ client.send_all(line,length_line);
+ if (EnDebugMSG)
+ printf("\n-->send HTML line:\n%s ...Ok!",line);
+ Thread::wait(10);
+}
+
+void send_HTML_error( int status_code, char* title, char* body_text)
+{
+ send_HTTP_header("HTTP/1.1", status_code, title, "text/html", -1);
+ if (EnDebugMSG)
+ printf("\n-->send_error...\n");
+ sentBuffer[0]=NULL; //clear buffer
+ sprintf(line_response, "<!DOCTYPE html>\r\n<html>\r\n<head>\r\n<title>%d %s</title>\r\n</head>\r\n", status_code, title);
+ snprintf(&(sentBuffer[strlen(sentBuffer)]),sizeof(sentBuffer),"%s",line_response); //append to buffer
+ sprintf(line_response, "<body><center><h2><center>%d %s</center></h2>\r\n",status_code, title );
+ snprintf(&(sentBuffer[strlen(sentBuffer)]),sizeof(sentBuffer),"%s",line_response); //append to buffer
+ sprintf(line_response, "%s\r\n", body_text );
+ snprintf(&(sentBuffer[strlen(sentBuffer)]),sizeof(sentBuffer),"%s",line_response); //append to buffer
+ sprintf(line_response, "<p>mbed HTTP File Server</p>\r\n</center></body></html>\r\n");
+ snprintf(&(sentBuffer[strlen(sentBuffer)]),sizeof(sentBuffer),"%s",line_response); //append to buffer
+ send_HTML_line(sentBuffer, strlen(sentBuffer));
+}
+
+int send_file(char *path_file)
+{
+ char *mime_type = {0};
+ unsigned int bytes_for_send=0;
+ long long filesize, all_send_bytes = 0;
+
+ mime_type = get_mime_type( path_file );
+ snprintf(file_path, sizeof(file_path),"/wfs/%s",path_file);
+ if (EnDebugMSG) {
+ printf("\n-->from send_file:%s",file_path);
+ printf("\n-->from send_file mime type:%s",mime_type);
+ }
+
+ if (Mystat(path_file, &myStatBuf)) { //fault with file
+ send_HTML_error( 403, "Forbidden", "403 - File access forbidden.");
+ return 403;
+ }
+ FILE* fp = NULL;
+ fp = fopen(file_path,"r");
+ if (fp==NULL ) {
+ send_HTML_error( 403, "Forbidden", "403 - File access forbidden.");
+ return 403;
+ }
+
+ filesize = myStatBuf.st_size;
+ send_HTTP_header("HTTP/1.1", 200, "Ok", mime_type, myStatBuf.st_size);
+ //binary send
+ all_send_bytes=0;
+ while(filesize) { //check for EOF !feof(fp)
+ bytes_for_send = filesize;
+ if (bytes_for_send > sizeof(sentBuffer)) {
+ bytes_for_send = sizeof(sentBuffer);
+ }
+ fread (sentBuffer,1,bytes_for_send,fp);
+ filesize -= bytes_for_send;
+ if (EnDebugMSG)
+ printf("\n---bytes_for_send...%d",bytes_for_send);
+ client.send_all(sentBuffer,bytes_for_send);
+ //Thread::wait(10);
+ all_send_bytes += bytes_for_send;
+ }
+ if (EnDebugMSG)
+ printf("\n---buffer fill end - all ...%lld", all_send_bytes);
+ //binary send
+
+ sprintf(line_response, "\r\n");
+ client.send_all(line_response,strlen(line_response));
+ if ( fp != NULL )
+ fclose(fp);
+ //Thread::wait(10);
+ return 0;
+}
+
+int send_directory(char *path)
+{
+ char process_name[64]= {0};
+
+ char posOfLastSlash;
+ char *pLS;
+
+ struct dirent *p;
+ struct sMystat sb;
+ struct tm *timeinfo;
+ char timeBuf[40];
+
+ if (EnDebugMSG)
+ printf("\n-->from send_directory:%s",path);
+ snprintf(file_path,sizeof(file_path),"/wfs%s",path);
+ DIR *d = opendir(file_path);
+ if (EnDebugMSG && d!=NULL)
+ printf("\n-->from send_directory:%s ...open OK",file_path);
+ if (d==NULL) { //error open dir
+ send_HTML_error( 403, "Forbidden", "403 - Directory access forbidden.");
+ return -1;
+ }
+ send_HTTP_header("HTTP/1.1", 200, "Ok",NULL, -1);
+ sentBuffer[0]=NULL;
+ sprintf(line_response,"<!DOCTYPE html>\r\n<html>\n<head><title>Index of %s</title>\n",path);
+ snprintf(&(sentBuffer[strlen(sentBuffer)]),sizeof(sentBuffer),"%s",line_response); //append to buffer
+
+ sprintf(line_response,"<meta content=\"text/html; charset=iso-8859-1\" http-equiv=\"Content-Type\"></head>\n");
+ snprintf(&(sentBuffer[strlen(sentBuffer)]),sizeof(sentBuffer),"%s",line_response); //append to buffer
+
+
+ sprintf(line_response,"<body><center>\n<h3>Index of %s</h3>\n", path);
+ snprintf(&(sentBuffer[strlen(sentBuffer)]),sizeof(sentBuffer),"%s",line_response); //append to buffer
+ send_HTML_line(sentBuffer, strlen(sentBuffer));
+//begin table
+ sentBuffer[0]=NULL; //clear buffer
+ sprintf(line_response,"<table border=\"0\">\n");
+ snprintf(&(sentBuffer[strlen(sentBuffer)]),sizeof(sentBuffer),"%s",line_response); //append to buffer
+ sprintf(line_response,"<tr><th align=\"left\" width=\"200\">Name</th><th align=\"right\" width=\"100\">Size(bytes)</th><th align=\"right\" width=\"200\">Date/Time</th></tr>\n");
+ snprintf(&(sentBuffer[strlen(sentBuffer)]),sizeof(sentBuffer),"%s",line_response); //append to buffer
+//begin table
+
+ pLS=strrchr(path,'/');
+ posOfLastSlash=pLS-path+1;
+ if (EnDebugMSG)
+ printf("\r\n>>posOfLastSlash=%d",posOfLastSlash);
+ snprintf(process_name,posOfLastSlash+1,"%s",path);
+ if (EnDebugMSG)
+ printf("\r\n>>process_name=%s",process_name);
+ sprintf(line_response,"<tr><td align=\"left\"><a href=\"%s\">../</a></td></tr>\n",process_name);
+ snprintf(&(sentBuffer[strlen(sentBuffer)]),sizeof(sentBuffer),"%s",line_response); //append to buffer
+ while((p = readdir(d)) != NULL) {
+ if (EnDebugMSG)
+ printf("\n :%s",p->d_name);
+ sprintf(file_path,"%s/%s",path,p->d_name);
+ Mystat( file_path, &sb );
+ if (get_dirInfo(file_path)==0 ) { //this is directory path
+ if (EnDebugMSG)
+ printf("\nDIR");
+ sprintf(line_response, "<tr><td align=\"left\"><a href=\"%s\">%s</a><br></td></tr>\n",file_path,p->d_name);
+ if (strlen(line_response)>(sizeof(sentBuffer)-strlen(sentBuffer))) { //buffer must be sent
+ send_HTML_line(sentBuffer, strlen(sentBuffer));
+ sentBuffer[0]=NULL; //clear buffer
+ }
+ snprintf(&(sentBuffer[strlen(sentBuffer)]),sizeof(sentBuffer),"%s",line_response); //append to buffer
+
+ } else { //this is file
+ if (EnDebugMSG)
+ printf("\nFILE");
+ timeinfo = localtime (&sb.st_mtime);
+ //strftime(timeBuf,40, "%I:%M:%S %p (%Y/%m/%d)\r\n", localtime(&sb.st_mtime));
+ strftime(timeBuf, 40, "%c", timeinfo);
+ sprintf(line_response, "<tr><td align=\"left\"><a href=\"%s\">%s</a></td><td align=\"right\">%lld</td><td align=\"right\">%s</td></tr>\n", file_path, p->d_name,(long long) sb.st_size,timeBuf); // asctime(timeinfo) );
+
+ if (strlen(line_response)>(sizeof(sentBuffer)-strlen(sentBuffer))) { //buffer must be sent
+ send_HTML_line(sentBuffer, strlen(sentBuffer));
+ sentBuffer[0]=NULL; //clear buffer
+ }
+ snprintf(&(sentBuffer[strlen(sentBuffer)]),sizeof(sentBuffer),"%s",line_response); //append to buffer
+ }
+ }
+ send_HTML_line(sentBuffer, strlen(sentBuffer));
+ closedir(d);
+
+ sprintf(line_response, "</table>\n<br><h4>mbed HTTP File Server</h4>\n</center></body></html>\n");
+ send_HTML_line(line_response, strlen(line_response));
+
+ return 0;
+}
+
+void parseHTTPRequest(char* buffer)
+{
+ char spacePos;
+ char *tmpBuffer;
+ spacePos = strcspn(buffer, " ") + 1; //position of first space character
+ snprintf(sMethod, spacePos,"%s", buffer);
+
+ //get Protocol
+ tmpBuffer=&(buffer[spacePos]); //move pointer to buffer (delete Method)
+ spacePos = strcspn(tmpBuffer, "\r\n") + 1;
+ tmpBuffer[spacePos]='\0'; //set end of string ...cut
+ sprintf(sProtocol, "%s", strrchr(tmpBuffer,' ')); //get string after last (space )
+ printf("\r\nsProtocol:%s", tmpBuffer);
+ buffer = &(sProtocol[1]); //cut first character (space)
+ sprintf(sProtocol, "%s", buffer);
+
+ //get URL
+ snprintf(sURL,strlen(tmpBuffer)-strlen(sProtocol),"%s\r\n", tmpBuffer); //URL is between Method and Protocol
+
+ printf("\nParse Method:%s",sMethod);
+ printf("\nParse URL:%s",sURL);
+ printf("\nParse PROTOCOL:%s",sProtocol);
+ printf("\n\r\n");
+}
+
+int processHTTP(char* sMethod, char* sURL, char* sProtocol)
+{
+ int gdi, gfi; //status of get_dir_info(xxx), and get_file_info(xxx)
+
+ if (strcmp(sMethod,"GET")!=0) {
+ send_HTML_error( 501, "501 Not Implemented", "501 - The server either does not recognize the request method");
+ return 501;
+ }
+ if (sURL[0]!= '/') {
+ send_HTML_error( 400, "Bad Request", "400 - The request cannot be fulfilled due to bad syntax.");
+ return 400;
+ }
+ if (sURL[strlen(sURL)-1]=='/') {
+ sURL[strlen(sURL)-1]=sURL[strlen(sURL)]; //delete last symbol
+ if (EnDebugMSG)
+ printf("\n delete last:%s",sURL);
+ }
+ gdi= get_dirInfo(sURL);
+ gfi= get_fileInfo(sURL);
+ if (gfi!=0) { //!=0 file not found
+ if (gdi==0) { //0-ok this is directory
+ return send_directory(sURL);
+ }
+ if (EnDebugMSG)
+ printf("\n404-br File not found or...(Fresult is:%d)",gfi);
+ send_HTML_error( 404, "Not Found","404 - The requested resource could not be found.");
+ return 404;
+ } else { //==0 found
+ if (gdi==0) //0-ok this is directory
+ return send_directory(sURL);
+ else
+ return send_file(sURL);
+ }
+}
+
+int main()
+{
+
+
+ ledTick.attach(&ledTickfunc,0.5);
+ //ledTick.detach();
+ //setup ethernet interface
+ //eth.init(); //Use DHCP
+ eth.init(IP,MASK,GATEWAY); //IP,mask,Gateway
+ eth.connect();
+ printf("IP Address is %s\n\r", eth.getIPAddress());
+
+ //setup tcp socket
+ if(svr.bind(PORT)< 0) {
+ printf("tcp server bind failed.\n\r");
+ return -1;
+ } else {
+ printf("tcp server bind successed.\n\r");
+ serverIsListened = true;
+ }
+
+ if(svr.listen(1) < 0) {
+ printf("tcp server listen failed.\n\r");
+ return -1;
+ } else {
+ printf("tcp server is listening...\n\r");
+ }
+
+ //listening for http GET request
+ while (serverIsListened) {
+ //blocking mode(never timeout)
+ if(svr.accept(client)<0) {
+ printf("failed to accept connection.\n\r");
+ } else {
+ //client.set_blocking(false,5000); //5000=5sec
+ printf("connection success!\n\rIP: %s\n\r",client.get_address());
+ clientIsConnected = true;
+ led2 = true;
+ while(clientIsConnected) {
+ char buffer[1024] = {};
+ switch(client.receive(buffer, 1023)) {
+ case 0:
+ printf("recieved buffer is empty.\n\r");
+ clientIsConnected = false;
+ break;
+ case -1:
+ printf("failed to read data from client.\n\r");
+ clientIsConnected = false;
+ break;
+ default:
+ printf("Recieved Data: %d\n\r\n\r%.*s\n\r",strlen(buffer),strlen(buffer),buffer);
+ parseHTTPRequest(buffer);
+ //if(buffer[0] == 'G' && buffer[1] == 'E' && buffer[2] == 'T' ) {
+ if (strcmp(sMethod, "GET" ) == 0 ) {
+ printf("GET request incomming.\n\r");
+ processHTTP(sMethod, sURL, sProtocol);
+ clientIsConnected = false;
+ }//if get
+ break;
+ } //switch
+ //ledTick.attach(&ledTickfunc,0.5);
+ }//while
+ printf("close connection.\n\rHTTP server is listening...\n\r\n");
+ client.close();
+ Thread::wait(50);
+ led2 = false;
+ }
+ }
+
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed-rtos.lib Sun Apr 07 11:23:03 2013 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed-rtos/#53e6cccd8782
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Sun Apr 07 11:23:03 2013 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed/builds/5e5da4a5990b \ No newline at end of file
