嵌入式系统与单片机|技术阅读
登录|注册

您现在的位置是:嵌入式系统与单片机 > 技术阅读 > ESP8266物联网入门(十四)用浏览器访问8266上的 WEB 服务器

ESP8266物联网入门(十四)用浏览器访问8266上的 WEB 服务器

上一篇我已经简单的实现了数据上传云平台,这一篇我们简单把ESP8266配置成web服务器,用手机(或电脑)的浏览器来访问8266上的服务器,8266将模拟的温度数据发送给浏览器。


WEB实验简介:

今天我们使用HTTP协议中的GET方法来获取8266的温度数据。首先我们把8266配置成web  server,然后通过浏览器输入8266的IP地址来访问,8266服务器每隔2秒更新一次温度数据(温度数据每访问一次自动加1)。

 程序流程如下图所示:


一个简单的HTML网页


那要访问web服务器了,是不是我们也要制作一个网站让浏览器访问呢?

是的,简单弄了一个HTML网页,并使用JavaScript脚本语言实现了服务器每隔2秒更新一下温度数据。

HTML网页的程序我们就不讲了,我把它贴到下面,大家复制下就可以了,到时候下载到8266就可以访问,程序如下:

<!DOCTYPE html PUBLIC "-//xsc//DTD XHTML 1.0 Transitional//EN" "https://mp.weixin.qq.com/s/9l5G5uIFHQzYhEnqQy5DtA"><html xmlns="https://mp.weixin.qq.com/s/9l5G5uIFHQzYhEnqQy5DtA"><head><style type="text/css">INPUT {font-size:30px};TEXTAREA{font-size:30px};</style><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><title>微信公众号:嵌入式小书虫</title></head><body>
<div id="嵌入式小书虫">温度为:0℃</div><script type="text/javascript">var syp_http_request;var Myhost=window.location.host;var URL="http://"+Myhost+"/xiaoshuchong.php";var myid;if(window.XMLHttpRequest){ syp_http_request=new XMLHttpRequest; if(syp_http_request.overrideMimeType) { syp_http_request.overrideMimeType("text/xml"); } }else if(window.ActiveXObject){ try{ syp_http_request=new ActiveXObject("Microsoft.XMLHTTP"); }catch(e){} }
if(!syp_http_request){ window.alert("不能创建 嵌入式小书虫XMLHTTPRequest对象!");}myid=window.setInterval(mytip,2000);my_send_request("GET",URL+"&random="+Math.random(),"","TEXT",syp_processTextResponse);function mytip(){ my_send_request("GET",URL+"&random="+Math.random(),"","TEXT",syp_processTextResponse);}function my_send_request(method,url,content,responseType,callback){ if(responseType.toLowerCase()=="text"){ syp_http_request.onreadystatechange=callback; }else if(responseType.toLowerCase()=="xml"){ syp_http_request.onreadystatechange=callback; window.alert("响应参数错误"); return false; } if(method.toLowerCase()=="get"){ syp_http_request.open(method,url,true); }else if(method.toLowerCase()=="post"){ syp_http_request.open(method,url,true); syp_http_request.setRequestHeader("Content-Type","application/x-www-form-urlencoded"); syp_http_request.setRequestHeader("Accept-Language","Zh-cn"); }else{ alert("HTTP请求错误"); return false; } syp_http_request.send(content); }function syp_processTextResponse(){ if(syp_http_request.readyState==4 && syp_http_request.status==200){ var b=syp_http_request.responseText; var myobject=eval('('+b+')'); document.getElementById("嵌入式小书虫").innerHTML="温度为:"+(myobject.success.value)/10+"℃" ; } }</script></body></html>
  • 把这个文件复制到XXXXX.html文件中,复制完成后用浏览器就可以打开, 查看是否复制正确,正确会出现一个网页。


8266web程序设计

把8266配置成AP(路由)模式
开启HTTP web服务
侦听 TCP 连接
有client客户端连接,发送温度数据
温度数据加1
浏览器中查看温度数据


8266web程序实现


首先我们把8266配置成AP(路由)模式,程序如下:

void ICACHE_FLASH_ATTR syp_userAP_init(void) {  struct ip_info info; ||设置成AP模式 wifi_set_opmode(STATIONAP_MODE); //Set softAP + station mode ||停止dhcp服务 wifi_softap_dhcps_stop();  ||设置8266服务器IP IP4_ADDR(&info.ip, 192, 168, 5, 1); IP4_ADDR(&info.gw, 192, 168, 5, 1); IP4_ADDR(&info.netmask, 255, 255, 255, 0); wifi_set_ip_info(SOFTAP_IF, &info); dhcps_lease_test(); ||启动dhcp服务 wifi_softap_dhcps_start();  ||开启web服务 start_web_server();}


开启web服务的程序如下:

void ICACHE_FLASH_ATTR start_web_server(void){ struct ip_info info; ||获取服务器IP wifi_get_ip_info(SOFTAP_IF, &info); ||初始化web server  syp_web_server_init(&info.ip, 80);}
void ICACHE_FLASH_ATTR syp_web_server_init(struct ip_addr *local_ip,int port){ LOCAL struct espconn esp_conn_syp;  ||初始化espconn参数 esp_conn_syp.type=ESPCONN_TCP; esp_conn_syp.state=ESPCONN_NONE; esp_conn_syp.proto.tcp=(esp_tcp *)os_malloc(sizeof(esp_tcp)); os_memcpy(esp_conn_syp.proto.tcp->local_ip,local_ip,4); esp_conn_syp.proto.tcp->local_port=port;
  ||注册连接成功回调函数和重新连接回调函数 espconn_regist_connectcb(&esp_conn_syp,web_server_listen_syp); espconn_regist_reconcb(&esp_conn_syp,web_server_recon_syp); ||侦听 TCP 连接 espconn_accept(&esp_conn_syp);}


回调函数如下:

void ICACHE_FLASH_ATTR web_server_listen_syp(void *arg) { struct espconn *pespconn = arg; ||注册接收回调函数 espconn_regist_recvcb(pespconn, web_server_recv_syp);  ||注册发送回调函数 espconn_regist_sentcb(pespconn, web_server_sent_syp); || 断开连接回调函数 espconn_regist_disconcb(pespconn, web_server_discon_syp);}
void ICACHE_FLASH_ATTR web_server_recon_syp(void *arg,sint8 err){ os_printf("连接错误,错误代码为:%d\r\n",err);}
void ICACHE_FLASH_ATTR web_server_sent_syp(void *arg){ os_printf("发送成功\r\n");}
void ICACHE_FLASH_ATTR web_server_discon_syp(void *arg){ os_printf("连接已经断开!");}


web 服务器接收回调函数程序如下:

#define tempjson "{\"success\": {\"key\": \"temp\",\"value\": \"%d\",\"value2\": \"20\"}}"||解析URLbool ICACHE_FLASH_ATTR parse_url_syp(char *precv_data,URLFrame *pURL_frame){ char *pbuffer_date=NULL; char *str=NULL; int length=0; ||数据为空,返回false if(precv_data==NULL || pURL_frame==NULL){ os_printf("%s","Wrong"); return false; } ||查找host  pbuffer_date=(char *)os_strstr(precv_data,"Host: ");   if(pbuffer_date != NULL){    os_memset(pURL_frame->pFilename,0,URLSize);        if(os_strncmp(precv_data,"GET ",4)==0){      ||查找GET   pURL_frame->Type = GET; pbuffer_date = precv_data + 4; }else if(os_strncmp(precv_data,"POST ",5)==0){ ||查找POST pURL_frame->Type=POST; pbuffer_date=precv_data + 5; }else{ return false; } pbuffer_date++; ||查找HTTP str=(char *)os_strstr(pbuffer_date," HTTP"); if(str !=NULL){ length=str-pbuffer_date;      os_memcpy(pURL_frame->pFilename,pbuffer_date,length); }else{ os_printf("%s","Can not find HTTP");    } }else{ os_printf("%s","Can not find Host"); return false;  } return true;}
void ICACHE_FLASH_ATTR web_server_recv_syp(void *arg,char *pdata,unsigned short len){
char index2[4096]; URLFrame *pURLFrame=NULL; char *pParseBuffer=NULL; char *precvdata = NULL; static int Temp = 0;
pURLFrame=(URLFrame *)os_zalloc(sizeof(URLFrame)); precvdata=(char *)os_zalloc(len+1);  os_memcpy(precvdata,pdata,len); ||解析URL  parse_url_syp(precvdata,pURLFrame); switch(pURLFrame->Type) { case GET: if(strncmp(pURLFrame->pFilename,"xiaoshuchong.php",16)==0) { os_printf("收到浏览器发来的数据xiaoshuchong.php:%s", pdata);      os_sprintf(index2,tempjson,Temp );      ||温度数据每次加1      Temp++;      ||发送温度数据      data_send_syp(arg,true,index2);    }else os_printf("收到浏览器发来的数据:%s", pdata); err = spi_flash_read(0x10 * 4096, (uint32 *) index2, 4096);      index2[INDEX_SIZE] = 0;        ||发送网页    data_send_syp(arg, true, index2); } break;  case POST:        break; } os_free(pURLFrame); pURLFrame=NULL; os_free(precvdata);  precvdata=NULL;}
  • 如果收到GET请求包的文件名是xiaoshuchong.php则发送温度数据

  • 否则发送flash中保存的网页数据。


HTTP  web服务器发送温度数据函数如下

void ICACHE_FLASH_ATTR data_send_syp(void *arg,bool responseis_OK,char *psenddata){ char httphead[256]; char *sypbuf_datas=NULL; uint16 date_length; struct espconn *syp_espconn=arg;
if(responseis_OK){ ||HTTP请求正确,回复200 os_sprintf(httphead,"HTTP/1.1 200 OK\r\nContent-Length: %d\r\nServer: lwIP/1.4.0\r\n",psenddata ? os_strlen(psenddata) : 0);    if(psenddata){    ||准备HTTP数据头 os_sprintf(httphead+strlen(httphead),"Content-Type: text/html; charset=utf-8\r\nPragma: no-cache\r\n\r\n"); date_length=os_strlen(httphead)+os_strlen(psenddata); sypbuf_datas=(char *)os_zalloc(date_length+1); os_memcpy(sypbuf_datas,httphead,os_strlen(httphead));      os_memcpy(sypbuf_datas+os_strlen(httphead),psenddata,os_strlen(psenddata)); }else{ os_sprintf(httphead+os_strlen(httphead),"\r\n"); date_length=os_strlen(httphead); } }else{ ||HTTP请求错误,回复400 os_sprintf(httphead,"HTTP/1.1 400 BadRequest\r\nContent-Length: 0\r\nServer: lwIP/1.4.0\r\n"); date_length=os_strlen(httphead); } ||发送数据  if(psenddata){  espconn_sent(syp_espconn,sypbuf_datas,date_length);   }else{   espconn_sent(syp_espconn,httphead,date_length); } ||释放内存 if(sypbuf_datas){ os_free(sypbuf_datas); sypbuf_datas=NULL; }}


程序编写完成,编译下载,电脑连接8266的热点,打开浏览器,输入8266服务器IP,就会出现温度数据,如下图:


同样的操作,在手机端也连接8266的热点并打开浏览器查看,如下图:

看到了吧,我们的温度是变化的。


我们在看下串口助手打印的数据,如下图:


好了,今天web服务器应用就讲完了,接下来我们会讲一下arm公司开源的arm-2D,据说是专门为小资源单片机设计的,连接如下:



补充:

今天的网页文件XXXX.html要烧写到FLASH的0x10000这个地址,如下图:



原创不易,如果你喜欢我的公众号、觉得我 文章对你有所启发,

请务必“点赞、收藏、转发”,这对我很重要,谢谢!

欢迎订阅    嵌入式小书虫