2015-12-28 7 views
0

У меня есть полностью работающий чип esp, который подключается к Wi-Fi и создает сервер. Когда я отправляю команду OTA, она запускает функцию, которая загружает файл, используя соединение сокета.ESP8266 сброс (без паники) после подключения сокета

Это upgrader.lua, что я использую:

-------------------------------------- 
-- Upgrader module for NODEMCU 
-- LICENCE: http://opensource.org/licenses/MIT 
-- cloudzhou<[email protected]> - 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 

В качестве теста я посылающего его: имя_файла = rz.lua и URL = http://192.168.1.132/rz.lua. Переменная cn - это соединение для отправки обратной информации клиенту.

ЭСП чип печатает:

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

Проблема, как представляется, связано с соед: отправить команду(). Если он находится внутри функции подключения, он сбрасывается. Если он снаружи, я получу таймаут чтения (так как чтение не вызывается). Я действительно не знаю, что еще делать.

Это ESP информация прошивки:

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

'Ò_ÇRöfJSúfÊÃjêÐÿ' <- это не барахло, установите бод на 74880 и смотрите сообщение, которое включает в себя причину последнего мягкого сброса. –

ответ

0

Я не могу быть уверен, но проблема, кажется, была ошибка памяти (странно, так как не было никакой паники), так это то, что я сделал, чтобы исправить it:

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, и используя таблицу вместо одной большой строки. Надеюсь, это поможет тем, кто в этом нуждается.

2

Вы сбрасываете. «Убой» - это сообщение BootROM с неправильной скоростью передачи.

Не отправляйте посылку, за которой следует закрытие в том же обратном вызове. Используйте on ('sent', ...), чтобы вызвать закрытие. Таким образом, 21 линия тела вашей тревоги 2 обратного вызова будет лучше написано:

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 

Я мог бы продолжать, но я оставляю это вам. Немного подумав, ваш код будет третьим размером и более читаемым.

 Смежные вопросы

  • Нет связанных вопросов^_^