序号

其它NodeMCU LUA开发文档


NodeMCU/ESP8266 DHT11使用


NodeMCU/ESP8266 HTTP POST数据至中国移动OneNET


NodeMCU/ESP8266 MQTT接入中国移动OneNET


NodeMCU/ESP8266 远程升级(OTA)


微信小程序获取中移OneNET数据


NodeMCU/ESP8266 NodeMCU连接阿里云

那么今天来讲一下远程升级。
像平常使用的手机和电脑都会时不时提醒我们更新,那他们不可能派手机或电脑的维护人员亲自跑到我们面前当场写代码更新。所以就可以用到远程升级。

这次我们使用http访问来远程更新。
因这次属于http访问,无加密,所以仅用于体验。

1.大概步骤

①. NodeMCU连网
②. 获取NodeMCU里的version.txt文件并读取版本号
③. 获取服务器version.txt里的版本号并替换
④. 通过版本号判断是否获取服务器的新程序

2.前期准备

①. 准备一个hfs(http文件服务器)用于模拟远端服务器。
②. 一块NodeMCU开发板或ESP8266最小系统都可。

3.开始实施

先新建一个a.lua程序,并保存到ESP8266中,如下图:

lua debug 远程调试 lua远程更新_版本号

①. 连网(此处直接上代码,不会的看视频教程):

--------------------------------
---  name: Cattle_L
---  date: 2020/03/07
---  project: OTA

wifi.setmode(wifi.STATION)
cfg = {}
cfg.ssid = "xxxxxx"     --change your Wi-Fi ssid
cfg.pwd = "xxxxxxxx"    --change your Wi-Fi password
wifi.sta.config(cfg)
wifi.sta.connect()

timer = tmr.create()

function Reconn()
    if wifi.sta.getip() == nil then
        print("waiting...")
    else
        timer:stop()
        print("ip is: "..wifi.sta.getip())
    end
end

timer:alarm(500, tmr.ALARM_AUTO, Reconn)

②. 定义一个读取version.txt的函数并调用

--------------------------------
---  name: Cattle_L
---  date: 2020/03/07
---  project: OTA
wifi.setmode(wifi.STATION)
cfg = {}
cfg.ssid = "xxxxxx"     --change your Wi-Fi ssid
cfg.pwd = "xxxxxxxx"    --change your Wi-Fi password
wifi.sta.config(cfg)
wifi.sta.connect()

timer = tmr.create()

function readfile()
    Version = '1'                           --set Version number
    if file.open("version.txt") then        
        Version = file.readline()
        Version = tonumber(Version)         
        print("old version is:"..Version)
        print("read version.txt success")
    else
        print("not found version.txt")
    end
end

function Reconn()
    if wifi.sta.getip() == nil then
        print("waiting...")
    else
        timer:stop()
        print("ip is: "..wifi.sta.getip())
    end
end

readfile()
timer:alarm(500, tmr.ALARM_AUTO, Reconn)

③. 打开事先准备好的hfs,确保电脑和NodeMCU处于同一个局域网,如下图:

lua debug 远程调试 lua远程更新_lua_02

④. 新建一个version.txt, 里面用于存放版本号,并将此文件拖入hfs中,如下图:

lua debug 远程调试 lua远程更新_lua_03


⑤. 先获取版本号,若获取到的版本号大于本地版本号则更新本地版本号

--------------------------------
---  name: Cattle_L
---  date: 2020/03/07
---  project: OTA

wifi.setmode(wifi.STATION)
cfg = {}
cfg.ssid = "xxxxxx"
cfg.pwd = "xxxxxxxx"
wifi.sta.config(cfg)
wifi.sta.connect()

timer = tmr.create()

function readfile()
    Version = '1'                               --set Version number
    if file.open("version.txt") then
        Version = file.readline()
        Version = tonumber(Version)
        print("old version is:"..Version)
        print("read version.txt success")
    else
        print("not found version.txt")
    end
end


function Reconn()
    if wifi.sta.getip() == nil then
        print("waiting...")
    else
        timer:stop()
        print("ip is: "..wifi.sta.getip())

        --change your ip address here
        http.get('http://192.168.1.103/version.txt',nil,
            function(code, data)
                if code < 0 then
                    print("http error")
                else
                    data = tonumber(data)
                    if data > Version then              --如果读取回来的版本号大于本地的
                        print(data)
                        file.open("version.txt",'w+')   --则打开version.txt(若一开始没有则会创建一个)
                        file.writeline(data)            --清空version.txt并替换里面版本号
                        file.close()                    --关闭文件

                    else                                --若版本号无更新则继续执行以前的代码文件
                        print("not new version")        
                        dofile("a.lua")               --继续执行 led.lua
                    end
                end
            end)
        
    end
end

readfile()
timer:alarm(500, tmr.ALARM_AUTO, Reconn)

⑥. 新建.lua文件做为新程序,用于测试,并拖入hfs中,如下图:

lua debug 远程调试 lua远程更新_lua_04

⑦. 若获取到新的版本号则继续获取新的代码文件,并将新的文件内容替换到本地的文件,也就替换到a.lua

--------------------------------
---  name: Cattle_L
---  date: 2020/03/07
---  project: OTA

wifi.setmode(wifi.STATION)
cfg = {}
cfg.ssid = "xxxxxx"
cfg.pwd = "xxxxxxxx"
wifi.sta.config(cfg)
wifi.sta.connect()

timer = tmr.create()

function readfile()
    Version = '1'                               --set Version number
    if file.open("version.txt") then
        Version = file.readline()
        Version = tonumber(Version)
        print("old version is:"..Version)
        print("read version.txt success")
    else
        print("not found version.txt")
    end
end


function Reconn()
    if wifi.sta.getip() == nil then
        print("waiting...")
    else
        timer:stop()
        print("ip is: "..wifi.sta.getip())

        --change your ip address here
        http.get('http://xxxx.xxxx.xxxx.xxxx/version.txt',nil,
            function(code, data)
                if code < 0 then
                    print("http error")
                else
                    data = tonumber(data)
                    if data > Version then              --如果读取回来的版本号大于本地的
                        print(data)
                        file.open("version.txt",'w+')   --则打开version.txt(若一开始没有则会创建一个)
                        file.writeline(data)            --清空version.txt并替换里面版本号
                        file.close()                    --关闭文件

                        --change your ip address here
                        http.get('http://192.168.1.103/program.lua',nil,
                            function(codes, datas)
                                if codes < 0 then
                                    print("http error")
                                else
                                    file.open("a.lua",'w+')   --打开本地led.lua
                                    file.writeline(datas)       --清空并写入新代码
                                    file.close()                --关闭文件
                                    dofile("a.lua")           --执行led.lua
                                end
                            end)
                            
                    else                                --若版本号无更新则继续执行以前的代码文件
                        print("not new version")        
                        dofile("a.lua")               --继续执行 led.lua
                    end
                end
            end)
        
    end
end

readfile()
timer:alarm(500, tmr.ALARM_AUTO, Reconn)

4. 总结

好的,差不多到这就结束了,大家也可以换成自己真正的服务器,对数据进行加密后再传输,另外应该考虑更多的细节,若内存不够怎么办?传输中途断网?传输超时?等等。