-->
Page 1 of 3

nodeMCU reboot during string concatenation?

PostPosted: Wed Apr 15, 2015 1:24 pm
by netcrusher88
When calling M.update({15}) I get three numbers from node.heap(), then nothing, which tells me the crash is happening in print('Field '..i..': '..v). Any thoughts?

Code: Select alllocal 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

Re: nodeMCU reboot during string concatenation?

PostPosted: Thu Apr 16, 2015 6:29 am
by cal
Moin,

please try a dev firmware release. Latest march release has string memory bug.

https://github.com/nodemcu/nodemcu-firmware/releases

Good luck,

Carsten

Re: nodeMCU reboot during string concatenation?

PostPosted: Fri Apr 17, 2015 8:52 am
by TerryE
I was about to start rewriting your code, but that's your job so I'll give you some pointers instead: :D
  • 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,"&")))
I haven't tested this so there might be a woopsie in it. But you should get the idea.

Re: nodeMCU reboot during string concatenation?

PostPosted: Fri Apr 17, 2015 10:29 am
by raz123
You're possibly trying to concatenate a nil variable. As a test, try replacing:

Code: Select allprint('Field '..i..':'..v)

with:

Code: Select allprint('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.