Lua ESP8266节点MCU堆内存不足

Lua ESP8266节点MCU堆内存不足,lua,esp8266,nodemcu,Lua,Esp8266,Nodemcu,我试图通过从笔记本电脑发送帖子(使用node.js),使用ESP8266-01切换LED 我现在有一个内存问题,因为每当我发送POST请求时,ESP中使用的内存都会增加,堆内存会减少,当没有内存时,它会崩溃(重新启动) 有什么想法吗 以下是我在ESP端的代码(main.lua): 我的init.lua刚刚连接到Wifi 谢谢你的帮助 Rey您发送的回调应该接受一个参数,即连接。您应该将on-sent处理程序设置为与on-receive相同的级别——在接收时传递给的conn不一定与传递给srv:l

我试图通过从笔记本电脑发送帖子(使用node.js),使用ESP8266-01切换LED

我现在有一个内存问题,因为每当我发送POST请求时,ESP中使用的内存都会增加,堆内存会减少,当没有内存时,它会崩溃(重新启动)

有什么想法吗

以下是我在ESP端的代码(main.lua):

我的init.lua刚刚连接到Wifi

谢谢你的帮助


Rey

您发送的回调应该接受一个参数,即连接。您应该将on-sent处理程序设置为与on-receive相同的级别——在接收时传递给的conn不一定与传递给srv:listen的conn相同


最后,字符串文本的冗余副本是对内存的浪费(尽管这可能不会导致它泄漏)。

您的实现所基于的中似乎存在一个问题。我们讨论了一下,我把它修好了

代码的改进版本如下:

gpio.mode(3, gpio.OUTPUT)
srv = net.createServer(net.TCP, 28800)
print("Server created... \n")
local pinState = 0
srv:listen(80, function(conn)
    conn:on("receive", function(sck, request)
        local _, _, method, path, vars = string.find(request, "([A-Z]+) (.+)?(.+) HTTP");
        if (method == nil) then
            _, _, method, path = string.find(request, "([A-Z]+) (.+) HTTP");
        end
        local message = {}
        message[#message + 1] = "HTTP/1.1 200 OK\r\n"
        message[#message + 1] = "Content-Type: text/html\r\n\r\n"
        print("Method:" .. method);
        if (method == "POST") then
            message[#message + 1] = "POST request successfully received\r\n"
            if (pinState == 0) then
                gpio.write(3, gpio.HIGH)
                pinState = 1
                print("LED ON")
            elseif (pinState == 1) then
                gpio.write(3, gpio.LOW)
                pinState = 0
                print("LED OFF")
            end
        elseif (method == "GET") then
            message[#message + 1] = "LED STATE=" .. tostring(pinState) .. "\r\n"
        end
        local function send(sk)
            if #message > 0 then
                sk:send(table.remove(message, 1))
            else
                sk:close()
                message = nil
                print("Heap Available:" .. node.heap())
            end
        end
        sck:on("sent", send)
        send(sck)
    end)
end)
我删除了一些重复的代码wrt填充
消息
,我还删除了末尾的“重置”和GC代码(不再相关)。但真正的问题是回调函数中的closed

每个回调函数都应该使用自己传递的套接字实例的副本,而不是引用包装回调函数的副本。

  • 第5行
    srv:listen(80,函数(conn)
    回调中的套接字变量是
    conn
  • 第6行有另一个接收套接字的回调函数,这次称为
    sck
    。它应该在该函数中作为
    sck
    sck:On()
    send(sck)
    )引用
  • 回调本身接收到一个/socket实例。您原来的
    send()
    函数没有使用它,而是使用了
    conn
    。因此,我添加了
    sk
    ,并在
    send()
    中专门使用这个函数

    • 因此,Marcel的解决方案起了作用

      这里是解决问题的另一个选择:

      print("Starting main.lua... \n")
      gpio.mode(3, gpio.OUTPUT)
      srv=net.createServer(net.TCP,28800)
      print("Server created... \n")
      srv:listen(80,function(conn)
          conn:on("receive", function(conn,request)
              local _,_,method,path= string.find(request, "([A-Z]+) (.+)?(.+) HTTP")
              local _,_,key,light_level = string.find(request, "(%a+)%s*:%s*(%d+)")
              if(method == nil)then
                  _,_,method,path = string.find(request, "([A-Z]+) (.+) HTTP")
              end
              local duty=light_level*1023/100
              pwm.setup(3, 500, duty)
              local message={}
              print("Level:"..light_level)
              if(method == "POST")then --light_level was sent from node.js as the header of the request
                 if(duty>0)then
                    pwm.start(3)
                    message = {"HTTP/1.0 200 OK\r\n Content-Type: text/html\r\n\r\n"}
                    message[#message + 1] = (light_level/100)
                 elseif(duty==0)then
                    pwm.stop(3)
                    message = {"HTTP/1.0 200 OK\r\n Content-Type: text/html\r\n\r\n"}
                    message[#message + 1] = 0
                 end 
              elseif(method == "GET")then
                 message[#message + 1] = "HTTP/1.1 200 OK\r\n Content-Type: text/html\r\n\r\n"
                 message[#message + 1] = "LED STATE="..tostring(pinState).."\r\n"
              end
              local function send()
                if #message > 0 then 
                   conn:send(table.remove(message, 1))
                else
                   conn:close()
                   conn = nil
                   collectgarbage()
                end
              end
              conn:on("sent", send)
              send()
              local message = nil
              local _,_,method,path = nil
              local _,_,key,light_level = nil
              local duty=nil
              --for debugging
              local heapSize=node.heap()
              if heapSize<2000 then
                 node.restart()
              end
              print("Memory Used:"..collectgarbage("count"))
              print("Heap Available:"..heapSize)
              local heapSize=nil
              --debugging end
          end)
      end)
      
      print(“启动main.lua…\n”)
      gpio.mode(3,gpio.OUTPUT)
      srv=net.createServer(net.TCP,28800)
      打印(“服务器已创建…\n”)
      srv:监听(80,功能(连接)
      连接:打开(“接收”,功能(连接,请求)
      本地u,u,方法,路径=string.find(请求,([A-Z]+)(.+)?(.+)HTTP)
      本地u、u、键、灯光级别=字符串。查找(请求,(%a+%s*:%s*(%d+))
      如果(方法==nil),则
      _,方法,路径=string.find(请求,“([A-Z]+)(.+)HTTP”)
      结束
      本地负载=照明水平*1023/100
      脉宽调制设置(3500,占空比)
      本地消息={}
      打印(“级别:…灯光级别)
      如果(method==“POST”),那么--light_level作为请求的头从node.js发送
      如果(占空比>0),则
      pwm.启动(3)
      消息={“HTTP/1.0 200确定\r\n内容类型:text/html\r\n\r\n”}
      消息[#消息+1]=(亮度/100)
      elseif(占空比==0)则
      脉宽调制停止(3)
      消息={“HTTP/1.0 200确定\r\n内容类型:text/html\r\n\r\n”}
      消息[#消息+1]=0
      结束
      elseif(method==“GET”)然后
      message[#message+1]=“HTTP/1.1200确定\r\n内容类型:text/html\r\n\r\n”
      消息[#消息+1]=“LED状态=“…tostring(pinState)…”\r\n
      结束
      本地函数send()
      如果#消息>0,则
      连接:发送(表。删除(消息,1))
      其他的
      康涅狄格州:关闭
      康涅狄格=零
      收集垃圾()
      结束
      结束
      conn:on(“发送”,发送)
      发送()
      本地消息=nil
      局部u,u,方法,路径=nil
      本地u,u,按键,灯光_电平=零
      本地税=零
      --用于调试
      本地heapSize=node.heap()
      
      如果是heapSizeHey Marcel,谢谢你的解决方案!我试过了,它成功了:)有趣的是,我也能用不同的方法解决这个问题(我将在下面发布)。我并不觉得奇怪,但你不应该这样做!
      conn=nil
      是固件应该做的事情,不要弄乱套接字实例。在
      send()
      之后所有的
      local xxx
      声明都是误导性的,因为这些变量已经声明,它们已经过时了。
      gpio.mode(3, gpio.OUTPUT)
      srv = net.createServer(net.TCP, 28800)
      print("Server created... \n")
      local pinState = 0
      srv:listen(80, function(conn)
          conn:on("receive", function(sck, request)
              local _, _, method, path, vars = string.find(request, "([A-Z]+) (.+)?(.+) HTTP");
              if (method == nil) then
                  _, _, method, path = string.find(request, "([A-Z]+) (.+) HTTP");
              end
              local message = {}
              message[#message + 1] = "HTTP/1.1 200 OK\r\n"
              message[#message + 1] = "Content-Type: text/html\r\n\r\n"
              print("Method:" .. method);
              if (method == "POST") then
                  message[#message + 1] = "POST request successfully received\r\n"
                  if (pinState == 0) then
                      gpio.write(3, gpio.HIGH)
                      pinState = 1
                      print("LED ON")
                  elseif (pinState == 1) then
                      gpio.write(3, gpio.LOW)
                      pinState = 0
                      print("LED OFF")
                  end
              elseif (method == "GET") then
                  message[#message + 1] = "LED STATE=" .. tostring(pinState) .. "\r\n"
              end
              local function send(sk)
                  if #message > 0 then
                      sk:send(table.remove(message, 1))
                  else
                      sk:close()
                      message = nil
                      print("Heap Available:" .. node.heap())
                  end
              end
              sck:on("sent", send)
              send(sck)
          end)
      end)
      
      print("Starting main.lua... \n")
      gpio.mode(3, gpio.OUTPUT)
      srv=net.createServer(net.TCP,28800)
      print("Server created... \n")
      srv:listen(80,function(conn)
          conn:on("receive", function(conn,request)
              local _,_,method,path= string.find(request, "([A-Z]+) (.+)?(.+) HTTP")
              local _,_,key,light_level = string.find(request, "(%a+)%s*:%s*(%d+)")
              if(method == nil)then
                  _,_,method,path = string.find(request, "([A-Z]+) (.+) HTTP")
              end
              local duty=light_level*1023/100
              pwm.setup(3, 500, duty)
              local message={}
              print("Level:"..light_level)
              if(method == "POST")then --light_level was sent from node.js as the header of the request
                 if(duty>0)then
                    pwm.start(3)
                    message = {"HTTP/1.0 200 OK\r\n Content-Type: text/html\r\n\r\n"}
                    message[#message + 1] = (light_level/100)
                 elseif(duty==0)then
                    pwm.stop(3)
                    message = {"HTTP/1.0 200 OK\r\n Content-Type: text/html\r\n\r\n"}
                    message[#message + 1] = 0
                 end 
              elseif(method == "GET")then
                 message[#message + 1] = "HTTP/1.1 200 OK\r\n Content-Type: text/html\r\n\r\n"
                 message[#message + 1] = "LED STATE="..tostring(pinState).."\r\n"
              end
              local function send()
                if #message > 0 then 
                   conn:send(table.remove(message, 1))
                else
                   conn:close()
                   conn = nil
                   collectgarbage()
                end
              end
              conn:on("sent", send)
              send()
              local message = nil
              local _,_,method,path = nil
              local _,_,key,light_level = nil
              local duty=nil
              --for debugging
              local heapSize=node.heap()
              if heapSize<2000 then
                 node.restart()
              end
              print("Memory Used:"..collectgarbage("count"))
              print("Heap Available:"..heapSize)
              local heapSize=nil
              --debugging end
          end)
      end)