极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 2307|回复: 8

Arduino IDE for ESP8266教程(四)路由系统

  [复制链接]
发表于 2017-5-24 20:50:41 | 显示全部楼层 |阅读模式
本帖最后由 当风过时 于 2017-5-24 20:53 编辑

转自我的博客:http://www.windworkshop.cn/?p=1219

个人认为,作者赋予ESP8266最强大的功能莫过于HTTP路由,HTTP路由,根据不同的url响应不同的任务。在这里就类似于node.js的路由。

在第一个教程里边已经展示了基本路由系统的使用,在我们访问ip的时候引导到了handleRoot
上进行处理。

而在之后获取svg图形的时候也通过路由引导到了drawGraph上返回由ESP8266“亲手”绘制的svg图形。

此外,路由系统还提供了NotFound处理,这个可以用来处理不在预设中的页面,用于引导到404页面或者内置的html页面上。
本次教程的详细代码:

#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
ESP8266WebServer server ( 80 );
String ssid = ""; // 需要连接的wifi热点名称
String password = ""; // 需要连接的wifi热点密码
/* NotFound处理
* 用于处理没有注册的请求地址
* 一般是处理一些页面请求
*/
void handleNotFound() {
  String message = "File Not Found\n\n";
  message += "URI: ";
  message += server.uri();
  message += "\nMethod: ";
  message += ( server.method() == HTTP_GET ) ? "GET" : "POST";
  message += "\nArguments: ";
  message += server.args();
  message += "\n";
  for ( uint8_t i = 0; i < server.args(); i++ ) {
    message += " " + server.argName ( i ) + ": " + server.arg ( i ) + "\n";
  }
  server.send ( 404, "text/plain", message );
}
void handleMain() {
  /* 返回信息给浏览器(状态码,Content-type, 内容)
   * 这里是访问当前设备ip直接返回一个String
   */
  server.send ( 200, "text/html", "Hello, this is handleMain.");
}
/* 引脚更改处理
* 访问地址为htp://192.162.xxx.xxx/pin?a=XXX的时候根据a的值来进行对应的处理
*/
void handlePin() {
  if(server.hasArg("a")) { // 请求中是否包含有a的参数
    String action = server.arg("a"); // 获得a参数的值
    if(action == "on") { // a=on
      digitalWrite(2, LOW); // 点亮8266上的蓝色led,led是低电平驱动,需要拉低才能亮
      server.send ( 200, "text/html", "Pin 2 has turn on"); return; // 返回数据
    } else if(action == "off") { // a=off
      digitalWrite(2, HIGH); // 熄灭板载led
      server.send ( 200, "text/html", "Pin 2 has turn off"); return;
    }
    server.send ( 200, "text/html", "unknown action"); return;
  }
  server.send ( 200, "text/html", "action no found");
}
void setup() {
  // 日常初始化网络
  pinMode(2, OUTPUT);
  Serial.begin ( 115200 );
  int connectCount = 0;
  WiFi.begin ( ssid.c_str(), password.c_str() );
  while ( WiFi.status() != WL_CONNECTED ) {
    delay ( 1000 );
    Serial.print ( "." );
    if(connectCount > 30) {
      Serial.println( "Connect fail!" );
      break;
    }
    connectCount += 1;
  }
  if(WiFi.status() == WL_CONNECTED) {
    Serial.println ( "" );
    Serial.print ( "Connected to " );
    Serial.println ( ssid );
    Serial.print ( "IP address: " );
    Serial.println ( WiFi.localIP() );
    connectCount = 0;
  }
  server.on ("/", handleMain); // 绑定‘/’地址到handleMain方法处理
  server.on ("/pin", HTTP_GET,  handlePin); // 绑定‘/pin’地址到handlePin方法处理
  server.onNotFound ( handleNotFound ); // NotFound处理
  server.begin();
  Serial.println ( "HTTP server started" );
}

void loop() {
  /* 循环处理,因为ESP8266的自带的中断已经被系统占用,
   * 只能用过循环的方式来处理网络请求
   */
  server.handleClient();
}
消息,连接成功之后可以看到返回有一个ip地址,使用浏览器方位这个ip地址就可以看到这个消息:

ESP8266-3-handleMain.png

这就是handleMain中返回给浏览器的String了。

然后可以访问控制引脚的地址:

ESP8266-3-on.png
点亮led

ESP8266-3-off.png
熄灭led

分别访问这两个地址可以看到板载的led点亮和熄灭。这个就是绑定了/pin的功能起的作用了。注意,在这里只允许使用GET方式来进行请求,因为在绑定的时候多输入了一个HTTP_GET参数,这个参数是指明了只绑定GET请求,同理也可以绑定POST等请求。

之后就是随便打个地址比如:

ESP8266-3-nofound.png

就会出现Not Found信息,在未绑路由之外的地方进行的请求一律会跳转到onNotFound绑定的方法中。

有没有感受到这个路由系统的魅力?因为8266本身是单线程运行,在Socket请求中并没有任何优势,在多个客户端同时请求的时候会造成数据错位等原因,所以平时个人都是使用http的形式进行请求来做数据交互。
回复

使用道具 举报

发表于 2017-5-24 21:38:06 | 显示全部楼层
GET请求解析,路径路由。。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-5-24 23:14:34 | 显示全部楼层
迷你强 发表于 2017-5-24 21:38
GET请求解析,路径路由。。

差不多这个意思了基本上和现在的web服务器提供的功能很接近的,感觉有点像nodejs
回复 支持 反对

使用道具 举报

发表于 2017-5-25 00:52:24 | 显示全部楼层
拜读过LZ最近的几篇关于8266d的文章,写得很精彩,很有启发意义
期待您对esp32的研究成果
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-5-25 20:15:11 | 显示全部楼层
wing 发表于 2017-5-25 00:52
拜读过LZ最近的几篇关于8266d的文章,写得很精彩,很有启发意义
期待您对esp32的研究成果

感谢支持,只要你们能看得明白我写这些教程就是有意义的了
关于esp32我在博客里边发有一篇偏向吐槽的试水文章,等有空稍微“润色”一下再发到论坛上来和大家分享
目前esp32的arduino库要感觉还不怎么实用,只是具备简单的io功能和网络交互功能,远远没有达到现在8266的完成度
回复 支持 反对

使用道具 举报

发表于 2017-8-8 13:53:59 | 显示全部楼层
怎么防止多个客户端访问出错啊,我是用多个手机同时访问
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-8-8 15:28:59 | 显示全部楼层
万马奔腾 发表于 2017-8-8 13:53
怎么防止多个客户端访问出错啊,我是用多个手机同时访问

这个目前还没有办法解决,包括arduino在内,目前都不具备多线程能力,没办法处理网络的并发任务,当下还是把它作为一个单独的下位机来用吧
回复 支持 反对

使用道具 举报

发表于 2017-12-5 00:18:24 | 显示全部楼层
本帖最后由 gdgzwqz 于 2017-12-5 17:52 编辑

自己建立热点,能否用这个东东呢?
如果可以,要怎样改呢?
回复 支持 反对

使用道具 举报

高级模式  
您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|联系我们|极客工坊 ( 浙ICP备09023225号 )

GMT+8, 2017-12-18 17:05 , Processed in 0.049086 second(s), 6 queries , File On.

Powered by Discuz! X3.4 Licensed

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表