local api_host = 'api.thingspeak.com'
local api_path = '/update'
local get_template = 'GET '..api_path..'?api_key='..api_key
local function update_factory(getstring)
return function (s)
if debug then print('Connected!') end
if debug then print('Sending: '..getstring) end
s:send(getstring..'\r\n\r\n')
end
end
local function sendUpdate(getstring)
s = net.createConnection(net.TCP, 1)
if debug then print("socket created...") end
s:on("connection", update_factory(getstring) )
s:on("receive", function (s, r) if debug then print("Return from API: "..r) end s:close() s = nil end)
if debug then print("callbacks registered...") end
s:connect(443,api_host)
if debug then print ("connect requested...") end
end
function M.update(data)
local getstring = get_template
print(node.heap())
for i,v in ipairs(data) do
print(node.heap())
if i < 9 then
print(node.heap())
print('Field '..i..':'..v)
getstring = getstring.."&field"..i.."="..v
end
end
print(node.heap())
if debug then print('Preparing connection') end
sendUpdate(getstring)
end
return M
please try a dev firmware release. Latest march release has string memory bug.
https://github.com/nodemcu/nodemcu-firmware/releases
Good luck,
Carsten
- Do as Carsten suggests and use a stable build.
- If you want to understand how Lua allocates its memory, then get a copy of lua / luac 5.1 for your PC and compile your code on you dev PC first. Use the luac -l option to list off the compiled code -- the lua bytecode is basically the same for x86 and the ESP8266.
- Also read this: A No-Frills Introduction to Lua 5.1 VM Instructions
- Read this thread: Massive memory optimization: flash functions! (+SPI SSD1306). You don't need to go the whole hog, but modularising your routines so that you do something like (loadfile "sendUpdate.lc"){1} will add maybe a mSec or so to the runtime but save a lot of memory. Just remember to make everything local and even though an event has fired the reference to it is still in the handlers table, preventing GC, so doing an s:on("connection", nil) in update_factory() will dereference itself allowing GC, etc.
- parameters are only input in lua, though the normal reference vs value rules apply. But the call with a parameter {1} executes a "NEWTABLE / LOADK / SETLIST / CALL" instruction sequence. You can happily overwrite the table in your function thus:Code: Select all
-- set up api_key
local data = ...
for i,v in ipairs(data) do
if i < 9 then
data[i] = "field"..i.."="..v
else
data[i] = nil
end
end
sendUpdate(("GET /update?api_key=%s&%s"):format(api_key, table.concat(data,"&")))
print('Field '..i..':'..v)
with:
print('Field ', i, ':', v)
Also, are you running this as a .lc? If so, try running it as a .lua -- the latter has a bit more debugging information on errors, I find.