ESP8266 NodeMCU堆内存不足 [英] ESP8266 NodeMCU Running Out of Heap Memory
问题描述
我试图通过从笔记本电脑发送POST(使用node.js)来使用ESP8266-01切换LED指示灯
I am trying to toggle an LED using ESP8266-01 by sending POST from my laptop (using node.js)
我现在遇到了内存问题,因为每当我发送POST请求时,ESP中使用的内存就会增加,堆内存会减少,并且在没有剩余内存时会崩溃(重新启动).
I now have a memory issue because whenever I send POST request, the memory used in the ESP increases, and heap memory decreases, and it crashes (restart) when theres no memory left.
有什么想法吗?
这是我在ESP端的代码(main.lua):
Here is my code on the ESP side (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)
在node.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);
}
})
我的init.lua刚刚连接到Wifi.
my init.lua is just connecting to Wifi.
感谢您的帮助!
雷伊
推荐答案
There was a problem in the NodeMCU docs with the socket:send
example you seem to have based your implementation on. We discussed it and I fixed it.
您的代码的改进版本是这样:
An improved version of your code is this:
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)
我删除了一些重复的代码,并填充了message
,最后我也删除了重置"和GC代码(不再相关).真正的问题是关闭了回调函数中的 upvalues .
I removed some duplicated code wrt populating message
and I also remove the "resetting" and GC code at the end (no longer relevant). The real issue though was with closed upvalues in the callback functions.
您的每个回调函数都应使用自己的已传递套接字实例副本,而不是引用包装的回调函数之一.
- 在第5行
srv:listen(80, function(conn)
上,回调中的套接字变量为conn
. - 在第6行上,还有另一个回调函数,该函数接收一个套接字,这次称为
sck
.在该函数中应将其引用为sck
(sck:on()
和send(sck)
). -
socket:on("sent")
回调本身会收到一个/套接字实例.您原来的send()
函数没有使用它,而是使用了conn
.因此,我添加了sk
并将其专门用于send()
.
- On line 5
srv:listen(80, function(conn)
the socket variable in the callback isconn
. - On line 6 there's another callback function which receives a socket, this time called
sck
. It should be referenced within that function assck
(sck:on()
andsend(sck)
). - The
socket:on("sent")
callback itself receives a/the socket instance. Your originalsend()
function didn't not use that though and usedconn
instead. So, I addedsk
and use this one exclusively withinsend()
.
这篇关于ESP8266 NodeMCU堆内存不足的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!