ESP8266 NodeMCU 运行内存不足
2016-5-19 6:36:20
收藏:0
阅读:69
评论:3
我正尝试通过从我的笔记本电脑 (使用 node.js) 发送 POST 来使用 ESP8266-01 切换 LED
我现在有一个内存问题,因为每当我发送 POST 请求时,ESP 中使用的内存增加,堆内存减少,并且在没有内存时崩溃 (重启).
有什么想法吗?
以下是我在 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 请求成功接收\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 请求成功接收\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 状态="..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("已使用内存:"..collectgarbage("count"))
print("剩余堆内存:"..heapSize)
end)
end)
在 node.js 上:
var request = require('request');
// 配置请求
var options = {
url: 'http://192.168.1.91',//ESP 的 IP 地址
method: 'POST'
}
// 开始请求
request(options, function (error, response, body)
{
if(!error)
{
return console.log('服务器响应:',body);
}
if(error)
{
return console.error('错误:', error);
}
})
我的 init.lua 只连接到 Wifi。
感谢您的帮助!
Rey
点赞
用户1241224
2016-05-20 21:45:44
用户131929
NodeMCU文档中的socket:send示例存在问题,你似乎是基于它来实现的。我们进行了讨论并进行了修复。
你的代码的改进版本是:
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代码(不再相关)。然而,真正的问题在于回调函数中的闭合变量。
每个回调函数都应该使用其自身的传递套接字实例的副本,而不是引用封装回调函数的一个实例的套接字。
- 在第5行
srv:listen(80,function(conn)中,回调中的套接字变量是conn。 - 在第6行,另一个回调函数接收一个套接字,这次称为
sck。它应该在该函数中引用为sck(sck:on()和send(sck))。 socket:on(“sent”)回调本身接收一个/ the套接字实例。但是,你最初的send()函数并没有使用它,而是使用了conn。因此,我添加了sk并在send()中仅使用它。
2016-05-22 20:39:42
用户6354580
所以来自Marcel的解决方案起作用了。
这里有另一种解决问题的选择:
print(“启动main.lua …\ n”)
gpio.mode(3,gpio.OUTPUT)
srv = net.createServer(net.TCP,28800)
print(“服务器已创建…\ n”)
srv:listen(80,function(conn)
conn:on(“receive”,function(conn,request)
local _,_,method,path =字符串.find(request,“([A-Z] +)(.+)?(.+)HTTP”)
local _,_,key,light_level =字符串.find(request,“(%a +)%s *:(%d +)”)
if(方法== nil)then
_,_,method,path =字符串.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作为请求头从node.js发送
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 _,_,方法,路径= nil
local _,_,key,light_level = nil
local duty = nil
- 调试用
local heapSize = node.heap()
if heapSize <2000 then
node.restart()
end
print(“已使用的内存:”..collectgarbage(“count”))
print(“可用的堆栈:”..heapSize)
local heapSize = nil
- 调试结束
end)
end)
2016-05-24 21:13:43
评论区的留言会收到邮件通知哦~
推荐文章
- 如何将两个不同的lua文件合成一个 东西有点长 大佬请耐心看完 我是小白研究几天了都没搞定
- 如何在roblox studio中1:1导入真实世界的地形?
- 求解,lua_resume的第二次调用继续执行协程问题。
- 【上海普陀区】内向猫网络招募【Skynet游戏框架Lua后端程序员】
- SF爱好求教:如何用lua实现游戏内调用数据库函数实现账号密码注册?
- Lua实现网站后台开发
- LUA错误显式返回,社区常见的规约是怎么样的
- lua5.3下载库失败
- 请问如何实现文本框内容和某个网页搜索框内容连接,并把网页输出来的结果反馈到另外一个文本框上
- lua lanes多线程使用
- 一个kv数据库
- openresty 有没有比较轻量的 docker 镜像
- 想问一下,有大佬用过luacurl吗
- 在Lua执行过程中使用Load函数出现问题
- 为什么 neovim 里没有显示一些特殊字符?
- Lua比较两个表的值(不考虑键的顺序)
- 有个lua简单的项目,外包,有意者加微信 liuheng600456详谈,最好在成都
- 如何在 Visual Studio 2022 中运行 Lua 代码?
- addEventListener 返回 nil Lua
- Lua中获取用户配置主目录的跨平台方法