NodeMCU学习系列(三)----配置网络

上一篇文章中介绍了NodeMCU连接网络的方法,可以看到联网非常简单。但是其中存在一个问题,WIFI的SSID和password必须写在代码中,如果换一个网络环境需要修改代码重新下载。如何让WIFI的信息可以动态修改,将在本文配置网络中介绍。

 NodeMCU包含enduser setup模块,用于对模块进行无线配网,但是作为学习系列,本文会创建一个http服务器来实现配网功能,原理上是类似的。

1.STATIONAP模式

 为了实现配网功能,将NodeMCU设置为STATIONAP模式,在此模式下既可以作为AP热点供其他设备连接,也可以连接到路由器的WIFI以确认可以连接。

 配网开始时,开启AP热点等待连接,手机或PC将要连接的WIFI SSID和password传过来后用station模式连接,连接成功则配网成功。配网数据默认保存在flash中,下次上电自动使用,当更换WIFI后会联网超时,再自动打开AP热点等待重新配网。

wifi.setmode(wifi.STATIONAP)
ap_cfg={}
ap_cfg.ssid = "ESP_mytest"
ap_cfg.auth = wifi.OPEN
wifi.ap.config(ap_cfg)

NOTE:开启AP热点后,NodeMCU的默认IP地址为192.168.4.1。如果要修改IP地址,通过接口wifi.ap.setip()修改:
cfg =
{
ip=“192.168.1.1”,
netmask=“255.255.255.0”,
gateway=“192.168.1.1”
}
wifi.ap.setip(cfg)

2.http服务器

 NodeMCU包含httpserver模块,用来实现一个HTTP 1.1服务器。同样,本文不直接使用httpserver模块,而是使用net模块实现功能,这样可以更深入的了解整个配网过程。
 创建服务器(TCP或者UDP协议):
net.createServer([type[, timeout]])
 监听端口:
net.server.listen([port],[ip],function(net.socket))
 注册事件回调:
net.socket:on()支持的事件有"connection", “reconnection”, “disconnection”, “receive” or “sent”
 在回调函数中处理HTTP请求,实现一个简单的HTTP服务器。

httpserver = net.createServer(net.TCP)
httpserver:listen(80, function(conn)
    conn:on("receive", receiver)
  end)

 代码创建了一个TCP协议的服务器,监听80端口,并注册receive事件的回调函数。当收到数据时,会在回调中进行数据处理。
 通过socket向远端发送数据:
send(string[, function(sent)])
 发送完成对应socket产生sent事件,所以使用函数sck:send(data, fnA) 等价于sck:on(“sent”, fnA); sck:send(data);

3.HTTP请求

 为了将配网信息传给NodeMCU,比较方便的方法是通过浏览器输入参数并提交,整个过程使用了HTTP的GET和POST请求。不同的请求本质上都是通过客户端(如浏览器)向服务端发送数据,根据数据内容不同进行相应的操作。

3.1 GET请求

 GET请求是需要向服务器获取数据,手机连上NodeMCU的热点,然后在浏览器打开server的ip地址,其实就是向服务器发送了GET请求,数据如下:

GET / HTTP/1.1
Host: 192.168.4.1
Connection: keep-alive
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Linux; U; Android 7.1.1; zh-CN; OPPO A83 Build/N6F26Q) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/57.0.2987.108 UCBrowser/12.3.6.1016 Mobile Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,en-US;q=0.8
X-UCBrowser-UA: dv(OPPO A83);pr(UCBrowser/12.3.6.1016);ov(Android 7.1.1);ss(360*680);pi(720*1360);bt(YZ);pm(1);bv(1);nm(0);im(0);sr(0);nt(2);

其中,第一行GET / HTTP/1.1 表示GET请求,请求资源路径/,协议版本1.1
第二行表示主机位置
第三行Connection: keep-alive 表示维持连接一段时间,默认3000ms
第四行Upgrade-Insecure-Requests (暂未研究,不清楚)
第五行User-Agent 表示浏览器和系统的一些信息
第六行Accept表示可以接受的数据类型
第七行Accept-Encoding表示支持的压缩格式
第八行Accept-Language表示支持的语言
第九行X-UCBrowser-UA表示UC浏览器的参数,不关注
第十行空行 表示请求命令头部结束
在server端根据收到的数据按行解析,根据请求将数据发送给客户端。当前应用中,此时发给客户端数据就是一个html网页的数据,客户端浏览器收到后显示出来。

3.2 请求响应

 客户端发出请求后,服务端返回相应数据,即为请求的响应,格式为:

HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: [length]

[body]

其中,第一行表示响应的状态,成功为200,找不到资源404 Not Found
第二行表示数据的格式
第三行Content-Length表示响应数据部分的长度
第四行空行 表示请求响应头部结束
第五行请求响应的数据部分,长度与Content-Lengt一致

响应数据部分为:

web_html = 
  [[
  <!DOCTYPE html>
  <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1">
      <title>Config</title>
  </head>
  <body style="text-align:center;background:#f8fffbb2;">
      <h1>Config page</h1>
      <form action="/config" method="post">
          <label>WiFi</label>
          <input type="text" name="ssid" />
          <br />
          <label>password</label>
          <input type="password" name="pwd" />
          <br />
          <input type="submit" value="ok" style="background:#678df9;height:40px;width:60px;border-radius:5px;border:none;outline:none;"/>
      </form>
  </body>
  </html>
  ]]

 由于配网中,只需要浏览器能输入WIFI的SSID和Password,显示页面很简单,所以直接将html代码写在Lua文件中。将这些数据填入请求响应的数据部分,手机浏览器收到响应后会显示出输入框及一个提交按钮。网页代码中有method=“post”,表示点击提交按钮后填入的数据会以POST请求发送给服务器。
 浏览器显示页面如下:

3.3 POST请求

 POST请求是将数据发送给服务器,在打开的页面中输入配网的信息,点击提交就会将数据用POST发送给服务器,数据如下:

POST /config HTTP/1.1
Host: 192.168.4.1
Connection: keep-alive
Content-Length: 16
Cache-Control: max-age=0
Origin: http://192.168.4.1
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Linux; U; Android 7.1.1; zh-CN; OPPO A83 Build/N6F26Q) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/57.0.2987.108 UCBrowser/12.3.6.1016 Mobile Safari/537.36
Content-Type: application/x-www-form-urlencoded
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Referer: http://192.168.4.1/
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,en-US;q=0.8
X-UCBrowser-UA: dv(OPPO A83);pr(UCBrowser/12.3.6.1016);ov(Android 7.1.1);ss(360*680);pi(720*1360);bt(YZ);pm(1);bv(1);nm(0);im(0);sr(0);nt(2);

ssid=123&pwd=456

其中:
第一行POST /config HTTP/1.1表示POST请求,请求资源路径/config,协议版本1.1;
最后一行的数据段就是浏览器表单中填的数据,服务器解析后取出参数并尝试连接网络,连接状态在响应数据端返回。POST请求响应格式与GET请求响应类似,不再叙述。

4 总结

 无线配网步骤是,先在NodeMCU上启动STATIONAP模式,创建一个服务器并监听80端口,手机连接NodeMCU的WIFI后打开网页填写参数提交,服务器端处理GET和POST请求。
 除了配网信息,网页中可以包含更多功能,如开关IO、连接云端的设备信息,都可以通过这种方式配置。

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值