插座连接后ESP8266复位(无应急)

时间:2015-12-28 01:28:49

标签: lua esp8266 nodemcu

我有一个完全工作的esp芯片连接到wifi并创建一个服务器。当我发送一个OTA命令时,它运行一个使用套接字连接下载文件的函数。

这是我正在使用的upgradeder.lua:

--------------------------------------
-- Upgrader module for NODEMCU
-- LICENCE: http://opensource.org/licenses/MIT
-- cloudzhou<wuyunzhou@espressif.com> - Heavily modified by aschmois
--------------------------------------

--[[
update('file.lua', 'http://IP.ADRESS/path/file.lua')
]]--

local header = ''
local isTruncated = false
local function save(filename, response)
    if isTruncated then
        file.write(response)
        return
    end
    header = header..response
    local i, j = string.find(header, '\r\n\r\n')
    if i == nil or j == nil then
        return
    end
    prefixBody = string.sub(header, j+1, -1)
    file.write(prefixBody)
    header = ''
    isTruncated = true
    return
end

----
function update(filename, url, cn)
    local tmpError = nil
    local running = true
    local error = nil
    local success = false
    print("Downloading from: " .. url)
    local ip, port, path = string.gmatch(url, 'http://([0-9.]+):?([0-9]*)(/.*)')()
    if ip == nil then
        return false
    end
    if port == nil or port == '' then
        port = 80
    end
    port = port + 0
    if path == nil or path == '' then
        path = '/'
    end
    print("-- Detailed Connection Info --")
    print("IP: ".. ip)
    print("Port: ".. port)
    print("Path: ".. path)
    print("-- END --")
    local function timeout() 
        error = tmpError
        file.remove(filename)
        conn:close()
        running = false
    end
    conn = net.createConnection(net.TCP, false)
    conn:on('connection', function(sck, response)
        tmr.stop(1)
        file.open(filename, 'w')
        conn:send('GET '..path..' HTTP/1.0\r\nHost: '..ip..'\r\n'..'Connection: close\r\nAccept: */*\r\n\r\n')
        tmpError = "READ TIMEOUT"
        tmr.alarm(1, 10000, 0, timeout)
    end)
    conn:on('receive', function(sck, response)
        tmr.stop(1)
        tmpError = "READ(2) TIMEOUT"
        tmr.alarm(1, 10000, 0, timeout)
        print(response)
        save(filename, response)
    end)
    conn:on('disconnection', function(sck, response)
        tmr.stop(1)
        local function reset()
            local list = file.list()
            for k,v in pairs(list) do
                if(filename == k) then
                    if(v == 0) then
                        success = false
                        file.close()
                        file.remove(filename)
                    else
                        file.close()
                        success = true
                    end
                end
            end
            print(header)
            header = ''
            isTruncated = false
            if(success) then
                print(filename..' saved')
            else
                print("Could not download `".. filename.."`")
            end
            running = false
        end
        tmr.alarm(0, 2000, 0, reset)
    end)
    conn:connect(port, ip)
    tmpError = "CONN TIMEOUT"
    tmr.alarm(1, 10000, 0, timeout)
    tmr.alarm(2, 1000, 1, function()
        if(running == false) then
            tmr.stop(2)
            local buf = ''
            if(success) then
                buf = buf.."HTTP/1.1 200 OK\r\nServer: WiFi Relay\r\nContent-Type: text/plain\r\n\r\n"
                buf = buf.."1"
            else
                buf = buf.."HTTP/1.1 500\r\nServer: WiFi Relay\r\nContent-Type: text/plain\r\n\r\n"
                buf = buf.."0"
                buf = buf.."\n"
                if(error ~= nil) then
                    buf = buf..error
                else
                    buf = buf.."UNKNOWN ERROR"
                end
            end
            cn:send(buf)
            cn:close()
        end
    end)
    return true
end

作为测试我发送它:filename = rz.lua和url = http://192.168.1.132/rz.lua。 cn变量是将信息发送回客户端的连接。

esp芯片打印:

Downloading from: http://192.168.1.132/rz.lua
-- Detailed Connection Info --
IP: 192.168.1.132
Ò_ÇRöfJSúfÊÃjêÐÿ (junk reset data)

问题似乎与conn:send()命令有关。如果它在on connect功能中,则重置。如果它在外面,我将得到读取超时(因为从未调用读取)。我真的不知道还能做什么。

这是ESP固件信息:

NodeMCU custom build by frightanic.com
    branch: master
    commit: 93421f2702fb02ce169f82f96be7f2a8865511e1
    SSL: false
    modules: node,file,gpio,wifi,net,tmr,uart

2 个答案:

答案 0 :(得分:2)

您正在重置。 &#34;垃圾&#34;是波特率错误的BootROM消息。

请勿在同一回调中执行发送后关闭。使用开(&#39;已发送&#39;,...)来触发关闭。因此,警报2回调的21行主体将更好地编写:

local response = "HTTP/1.1 200 OK\r\nServer: WiFi Relay\r\nContent-Type: text/plain\r\n\r\n%s"
cn:send(response:format(success and "1" or ("0\n\r" .. (error or "UNKNOWN ERROR")))
cn:on('sent', function(cn) cn:close() end)

在那个注意事项上你的27行断开回调会写得更好:

tmr.stop(1)
tmr.alarm(0, 2000, 0, function()
  local len = file.list()(filename)
  success = len and len > 0
  file.close()
  if not success then file.remove(filename)
  file.flush()
  end)

请注意,在写入或删除文件后刷新SPIFFS总是明智的。

您使用标准模式,所以为什么不封装它:

local conn = net.createConnection(net.TCP, false) 
local function setTimeout(reason)
 -- tmr.stop(1)   -- not needed is the next line resets the alarm
  tmr.alarm(1, 10000, 0, function ()
    -- you don't need tmpError as reason is a local and bound as an upval
    error, running = reason, false
    file.remove(filename) file.flush()
    return conn:close()
  end)
end

我可以继续,但我把它留给你。稍加思考,您的代码将是大小的三分之一,更具可读性。

答案 1 :(得分:0)

我无法确定但问题似乎是内存错误(因为没有恐慌所以很奇怪)所以这就是我所做的修复它:

local request = table.concat({"GET ", path,
                        " / HTTP/1.1\r\n", 
                        "Host: ", ip, "\r\n",
                        "Connection: close\r\n",
                        "Accept: */*\r\n",
                        "User-Agent: Mozilla/4.0 (compatible; esp8266 Lua;)",
                        "\r\n\r\n"})
    conn = net.createConnection(net.TCP, false)
    conn:on('connection', function(sck, response)
        tmr.stop(1)
        tmpError = "READ TIMEOUT"
        tmr.alarm(1, 10000, 0, timeout)
        conn:send(request)
    end)

我使用table.concat方法创建了请求,并使用表而不是一个大字符串。希望这能帮助那些有需要的人。