lua esp8266 nodemcu

lua - ESP8266 NodeMCU quedando sin memoria de almacenamiento dinámico



(3)

Entonces la solución de Marcel funcionó.

Aquí hay otra opción para resolver el problema:

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)

Estoy tratando de alternar un LED usando ESP8266-01 enviando POST desde mi computadora portátil (usando node.js)

Ahora tengo un problema de memoria porque cada vez que envío una solicitud POST, la memoria utilizada en el ESP aumenta, y la memoria del montón disminuye, y se bloquea (reinicia) cuando no queda memoria.

¿Alguna idea?

Aquí está mi código en el lado ESP (main.lua):

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(conn,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={} print("Method:"..method); if(method == "POST")then if(pinState==0)then gpio.write(3,gpio.HIGH) pinState=1 print("LED ON") message[#message + 1] = "HTTP/1.1 200 OK/r/n" message[#message + 1] = "Content-Type: text/html/r/n/r/n" message[#message + 1] = "POST request successfully received/r/n" elseif(pinState==1)then gpio.write(3,gpio.LOW) pinState=0 print("LED OFF") message[#message + 1] = "HTTP/1.1 200 OK/r/n" message[#message + 1] = "Content-Type: text/html/r/n/r/n" message[#message + 1] = "POST request successfully received/r/n" end elseif(method == "GET")then message[#message + 1] = "HTTP/1.1 200 OK/r/n" message[#message + 1] = "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() end end conn:on("sent", send) send() local message={} local _, _, method, path, vars= {} local heapSize=node.heap() if heapSize<1000 then node.restart() end collectgarbage() print("Memory Used:"..collectgarbage("count")) print("Heap Available:"..heapSize) end) end)

En el nodo.js:

var request = require(''request''); // Configure request var options = { url: ''http://192.168.1.91'',//ESP''s IP address method: ''POST'' } // Start the request request(options, function (error, response, body) { if(!error) { return console.log(''Server responded with:'',body); } if(error) { return console.error(''ERROR:'', error); } })

mi init.lua solo se está conectando a Wifi.

¡Gracias por tu ayuda!

Rey


Hubo un problema en los documentos de NodeMCU con el socket:send ejemplo en el que parece haber basado su implementación. Lo discutimos y lo arreglé.

Una versión mejorada de su código es esta:

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)

Eliminé un message duplicado de código wrt y también eliminé el "restablecimiento" y el código GC al final (ya no es relevante). Sin embargo, el problema real era con upvalues cerrados en las funciones de devolución de llamada.

Cada una de sus funciones de devolución de llamada debe usar su propia copia de la instancia de socket aprobada en lugar de hacer referencia a la de una función de devolución de llamada de ajuste.

  • En la línea 5 srv:listen(80, function(conn) la variable de socket en la devolución de llamada es conn .
  • En la línea 6 hay otra función de devolución de llamada que recibe un socket, esta vez llamada sck . Debe hacerse referencia dentro de esa función como sck ( sck:on() y send(sck) ).
  • La devolución de llamada socket:on("sent") recibe una instancia del socket. Sin embargo, su función original send() no usó eso y usó conn lugar. Entonces, agregué sk y uso este exclusivamente dentro de send() .

Su devolución de llamada enviada debe aceptar un parámetro, una conexión. Y debe configurar el controlador en enviado en el mismo nivel que en recepción: la conexión que se pasa a recepción no es necesariamente la misma conexión que se pasa a srv: escuchar.

Por último, las copias redundantes de literales de cadena son un desperdicio de memoria (aunque eso probablemente no hará que se filtre).