上一篇文章中介绍了NodeMCU连接网络的方法,可以看到联网非常简单。但是其中存在一个问题,WIFI的SSID和password必须写在代码中,如果换一个网络环境需要修改代码重新下载。如何让WIFI的信息可以动态修改,将在本文配置网络中介绍。
NodeMCU包含enduser setup模块,用于对模块进行无线配网,但是作为学习系列,本文会创建一个http服务器来实现配网功能,原理上是类似的。
为了实现配网功能,将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)
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);
为了将配网信息传给NodeMCU,比较方便的方法是通过浏览器输入参数并提交,整个过程使用了HTTP的GET和POST请求。不同的请求本质上都是通过客户端(如浏览器)向服务端发送数据,根据数据内容不同进行相应的操作。
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网页的数据,客户端浏览器收到后显示出来。
客户端发出请求后,服务端返回相应数据,即为请求的响应,格式为:
HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: [length]
[body]
其中,第一行表示响应的状态,成功为200,找不到资源404 Not Found
第二行表示数据的格式
第三行Content-Length表示响应数据部分的长度
第四行空行 表示请求响应头部结束
第五行请求响应的数据部分,长度与Content-Lengt一致
响应数据部分为:
web_html =
[[
Config
Config page