我们:
利用网页web端的目标搭载NodeMcu的es8266连接wifi 硬件准备:
- 基于NodeMCU的esp8266
- 数据线:u***+micro-u***
- 安装有Windows系统的电脑
软件准备:
- java运行环境:自行安装,注意,需要下载jdk8,太高的版本会使软件闪退
- nodemcu-flasheres:p8266闪存烧录程序
- ESPlorer:为NodeMcu设计的编辑、上传软件
- CH340驱动:连接电脑和esp8266码验证ja94
- NodeMcu制作固件:NodeMcu团队为p8266的验证码u5zv
如何下载Github上的源码
我们以nodemcu-flasher的下载为例 进入相关
界面-flasher 进入nodemcu-flasher的项目,只需下载的话是不需要注册的:
![]()
点击下载项目的克隆或下载GitHub时间后点击一个小框,即可下载小框里的zip源代码,下载完毕后解压缩可以
![]()
如何安装CH340驱动
下载百度云内的文件,得到一个叫Setup 32.64位元.exe的程序,执行它安装驱动。安装成功后使用数据线连接esp8266,打开设备管理器,如果下面显示的情况,则说明已经安装完成:
![]()
如果没有显示驱动显示,则有可能是数据线的问题,换数据线。如果显示修改、修复、删除的话,说明你之前已经安装过这个驱动了,如果你的设备管理器没有正常的话,就需要把之前的程序卸载再重新安装
烧录
下载NodeMcu,nodemcu-master-11-modules-2019-07-22-07-39- 2-float.bin,打开Win64Rease,然后打开我们这个NodeMcu-flashp8266到电脑里:选择刷新,再在下面的方框里NodeMcu,连接
文件的本地文件地址,也就是你放的
![]()
我们的本地文件地址回到操作(正常情况下端口后面的选择端口是有值的,为了操作方便没有连接电脑),点击Flash按钮,我会立即被烧录到esp266中。
源代码准备
源代码分为三类:
- 控制esp8266的lua程序
- 控制网页的html程序
- 负责沟通esp8266和网页的http服务器程序
我们需要按以下步骤获得init.lua index.html HttpServe.lua三个文件,并把它们放在一个文件夹
- 新建一个.txt文件
- 复制代码
- 重命名文件为相应的名字
它们的源程序如下:
wifi.setmode(wifi.STATIONAP)cfg={}cfg.ssid="config" --我们的NodeMcu热点cfg.pwd="00000000"--密码wifi.ap.config(cfg)cfg2 ={ip="192.168.1.1",--设置IPnetmask="255.255.255.0",--子网掩码gateway="192.168.1.1"--默认网关}wifi.ap.setip(cfg2)wifi.sta.autoconnect(1)--自动连接dofile('httpServer.lua')--执行HttpServer.lua httpServer:use('/config', function(req, res) if req.query.ssid ~= nil and req.query.pwd ~= nil then print(req.query.ssid ..req.query.pwd) config={} config.ssid=req.query.ssid config.pwd=req.query.pwd wifi.sta.config(config) end res:send(' 配置终端您设置的wifi是:'..req.query.ssid..',请等待红灯常亮即连接完成。')end) httpServer:listen(80) --启动Server
---------------------- helper--------------------function urlDecode(url) return url:gsub('%%(%x%x)', function(x) return string.char(tonumber(x, 16)) end)end function guessType(filename) local types = { ['.css'] = 'text/css', ['.js'] = 'application/javascript', ['.html'] = 'text/html', ['.png'] = 'image/png', ['.jpg'] = 'image/jpeg' } for ext, type in pairs(types) do if string.sub(filename, -string.len(ext)) == ext or string.sub(filename, -string.len(ext .. '.gz')) == ext .. '.gz' then return type end end return 'text/plain'end ---------------------- Response--------------------Res = { _skt = nil, _type = nil, _status = nil, _redirectUrl = nil,} function Res:new(skt) local o = {} setmetatable(o, self) self.__index = self o._skt = skt return oend function Res:redirect(url, status) status = status or 302 self:status(status) self._redirectUrl = url self:send(status)end function Res:type(type) self._type = typeend function Res:status(status) self._status = statusend function Res:send(body) self._status = self._status or 200 self._type = self._type or 'text/html' local buf = 'HTTP/1.1 ' .. self._status .. 'rn' .. 'Content-Type: ' .. self._type .. 'rn' .. 'Content-Length:' .. string.len(body) .. 'rn' if self._redirectUrl ~= nil then buf = buf .. 'Location: ' .. self._redirectUrl .. 'rn' end buf = buf .. 'rn' .. body local function doSend() if buf == '' then self:close() else self._skt:send(string.sub(buf, 1, 512)) buf = string.sub(buf, 513) end end self._skt:on('sent', doSend) doSend()end function Res:sendFile(filename) if file.exists(filename .. '.gz') then filename = filename .. '.gz' elseif not file.exists(filename) then self:status(404) if filename == '404.html' then self:send(404) else self:sendFile('404.html') end return end self._status = self._status or 200 local header = 'HTTP/1.1 ' .. self._status .. 'rn' self._type = self._type or guessType(filename) header = header .. 'Content-Type: ' .. self._type .. 'rn' if string.sub(filename, -3) == '.gz' then header = header .. 'Content-Encoding: gziprn' end header = header .. 'rn' print('* Sending ', filename) local pos = 0 local function doSend() file.open(filename, 'r') if file.seek('set', pos) == nil then self:close() print('* Finished ', filename) else local buf = file.read(512) pos = pos + 512 self._skt:send(buf) end file.close() end self._skt:on('sent', doSend) self._skt:send(header)end function Res:close() self._skt:on('sent', function() end) -- release closures context self._skt:on('receive', function() end) self._skt:close() self._skt = nilend ---------------------- Middleware--------------------function parseHeader(req, res) local _, _, method, path, vars = string.find(req.source, '([A-Z]+) (.+)?(.+) HTTP') if method == nil then _, _, method, path = string.find(req.source, '([A-Z]+) (.+) HTTP') end local _GET = {} if vars ~= nil then vars = urlDecode(vars) for k, v in string.gmatch(vars, '([^&]+)=([^&]*)&*') do _GET[k] = v end end req.method = method req.query = _GET req.path = path return trueend function staticFile(req, res) local filename = '' if req.path == '/' then filename = 'index.html' else filename = string.gsub(string.sub(req.path, 2), '/', '_') end res:sendFile(filename)end ---------------------- HttpServer--------------------httpServer = { _srv = nil, _mids = {{ url = '.*', cb = parseHeader }, { url = '.*', cb = staticFile }}} function httpServer:use(url, cb) table.insert(self._mids, #self._mids, { url = url, cb = cb })end function httpServer:close() self._srv:close() self._srv = nilend function httpServer:listen(port) self._srv = net.createServer(net.TCP) self._srv:listen(port, function(conn) conn:on('receive', function(skt, msg) local req = { source = msg, path = '', ip = skt:getpeer() } local res = Res:new(skt) for i = 1, #self._mids do if string.find(req.path, '^' .. self._mids .url .. '$') and not self._mids.cb(req, res) then break end end collectgarbage() end) end)endnilend---------------------- Middleware--------------------function parseHeader(req, res)local _, _, method, path, vars = string.find(req.source, '([A-Z]+) (.+)?(.+) HTTP')if method == nil then_, _, method, path = string.find(req.source, '([A-Z]+) (.+) HTTP')endlocal _GET = {}if vars ~= nil thenvars = urlDecode(vars)for k, v in string.gmatch(vars, '([^&]+)=([^&]*)&*') do_GET[k] = vendendreq.method = methodreq.query = _GETreq.path = pathreturn trueendfunction staticFile(req, res)local filename = ''if req.path == '/' thenfilename = 'index.html'elsefilename = string.gsub(string.sub(req.path, 2), '/', '_')endres:sendFile(filename)end---------------------- HttpServer--------------------httpServer = {_srv = nil,_mids = {{url = '.*',cb = parseHeader}, {url = '.*',cb = staticFile}}}function httpServer:use(url, cb)table.insert(self._mids, #self._mids, {url = url,cb = cb})endfunction httpServer:close()self._srv:close()self._srv = nilendfunction httpServer:listen(port)self._srv = net.createServer(net.TCP)self._srv:listen(port, function(conn)conn:on('receive', function(skt, msg) local req = { source = msg, path = '', ip = skt:getpeer() }local res = Res:new(skt)for i = 1, #self._mids doif string.find(req.path, '^' .. self._mids.url .. '$')and not self._mids.cb(req, res) thenbreakendendcollectgarbage()end)end)end
配置终端 配置页面 注意:由于NodeMCU内存很小,附近热点过多时,扫描热点会造成内存不足自动重启。请手动输入WIFI信息进行配置。 |