Biyau
Biyau

Reputation: 121

Lua function returns string, but calling function gets nil

I'm writing a function for Nodemcu (esp8266) Lua to build command strings from UART (someone typing). When it finishes capturing characters, it's supposed to return the string to the calling function, but the calling function only gets nil. I'm new to Lua, What am I missing?

local function getcmd()

  local t = { }
  local cmd
  
  -- Callback function
  uart.on("data", 0, function(data)
    
    if data~='\r' then
      --Echo input
      t[#t+1] = data
      uart.write(0,t[#t])

      -- BACKSPACE/DEL
      if t[#t] == '' then
        t[#t] = nil
        t[#t] = nil
      end

      -- NEED <TAB> handling here too

    else
      --Disables callback
      --uart.on("data")

      -- Print table, convert to string.
      for i = 1, #t do
        uart.write(0, t[i])
        if i==1 then
          cmd = tostring(t[i])
        else
          cmd = cmd .. tostring(t[i])
        end
      end
      t = { }

      if cmd ~= nil then
        uart.write(0, "Before Return> "..cmd)
        -- type() String
        return cmd
      end
    end
  end,0)
end

local function config()

  local cmdstr

  -- Testing
  cmdstr = getcmd()
  print("func() "..getcmd())

  if cmdstr ~= nil then
    uart.write(0, cmdstr.."> ")
  end
end

Upvotes: 0

Views: 467

Answers (1)

Biyau
Biyau

Reputation: 121

Thanks to @EgorSkriptunoff for helping me understand what was happening.

Below is the code that works (so far). What I tried was a While loop around the event handler inside of getcmd(). This fails because it stops execution of all the background events that keep things like wifi and other essential functions that keep the ESP8266 running, so it crashes/reboots repeatedly.

What I did instead of returning from getcmd() was call config() directly and pass it the input I collected in the event handler, like this: config(cmd)

The potential problem is, the event handler is still running since it never reached the end and that could cause some stack/memory issues if I don't return from config() before calling another function.

Anyway, here is the code that is working for the moment:

function getcmd()

  local t = { }
  cmd=nil

    uart.on("data", 0, function(data)
      
      if data~='\r' then
        --Echo input
        t[#t+1] = data
        uart.write(0,t[#t])
  
        -- BACKSPACE/DEL
        if t[#t] == 'BS' then
          t[#t] = nil
          t[#t] = nil
        end
      else
        --uart.on("data")
  
        if #t ~= nil then
          uart.write(0,"\r\n"..#t.."\r\n")
        end
  
        for i = 1, #t do
          uart.write(0, t[i])
          if i==1 then
            cmd = tostring(t[i])
          else
            cmd = cmd .. tostring(t[i])
          end
        end
        t = { }
        if cmd ~= nil then
          -- Calling config() here doesn't allow event handler on.uart() to end.
          config(cmd)
        end
      end
    end,0)

  end

------------------------------------------------------
function config(cmd)

  print("\r<<"..cmd..">>\r")
  
  -- Now parse cmd and return.
end

Upvotes: 0

Related Questions