Post your best Lua script examples here

User avatar
By roccomuso
#23229 Hi guys,

can someone help me to optimize this code? I'm getting the "Not enough Memory" error :| :|

Code: Select allBOARD_NAME = "minitron"
-- wifi connection
    IPADR = "192.168.1.112" --Requested static IP address for the ESP
   IPROUTER = "192.168.1.1" --IP address for the Wifi router
   wifi.setmode(wifi.STATION)
   wifi.sta.autoconnect(1)
   wifi.sta.setip({ip=IPADR,netmask="255.255.255.0",gateway=IPROUTER})
    wifi.sta.config("SSID","PASSWORD")
print(wifi.sta.getip())
led1 = 3
led2 = 4
gpio.mode(led1, gpio.OUTPUT)
gpio.mode(led2, gpio.OUTPUT)
-- entrambi off all'avvio
gpio.write(led1, gpio.LOW)
gpio.write(led2, gpio.LOW)

srv=net.createServer(net.TCP)
srv:listen(80,function(conn)
    conn:on("receive", function(client,request)
        local buf = "";
        local method, path, vars = string.find(request, "([A-Z]+) (.+)?(.+) HTTP");
        if(method == nil)then
            method, path = string.find(request, "([A-Z]+) (.+) HTTP");
        end
        local _GET = {}
        if (vars ~= nil)then
            for k, v in string.gmatch(vars, "(%w+)=(%w+)&*") do
                _GET[k] = v
            end
        end
      
      if (_GET.ping=="board")then
         client:send("{\"key\": true, \"nome_board\":\""..BOARD_NAME.."\", \"chip_id\":"..node.chipid()..", \"ip_address\": \""..wifi.sta.getip().."\"}")
      elseif(_GET.toggle=="1") then
         new_s = (gpio.read(led1)==1 and gpio.LOW or gpio.HIGH)
            gpio.write(led1, new_s);
            current_status = (new_s==gpio.LOW and 0 or 1);
         client:send("{\"pin\":1, \"new_state\":"..current_status.."}")
      elseif(__GET.toggle=="2") then
         new_s = (gpio.read(led2)==1 and gpio.LOW or gpio.HIGH)
            gpio.write(led2, new_s);
            current_status = (new_s==gpio.LOW and 0 or 1);
         client:send("{\"pin\":2, \"new_state\":"..current_status.."}")
      elseif (_GET.get=="1") then
         client:send("{\"gpio_number\": 1, \"state\":"..gpio.read(led1).."}");
      elseif(_GET.get=="2") then
         client:send("{\"gpio_number\": 2, \"state\":"..gpio.read(led2).."}");
      elseif(_GET.pin == "on1")then
         gpio.write(led1, gpio.HIGH);
         client:send("{\"gpio_number\": 1, \"state\":1}");
      elseif(_GET.pin == "off1")then
         gpio.write(led1, gpio.LOW);
         client:send("{\"gpio_number\": 1, \"state\":0}");
      elseif(_GET.pin == "on2")then
         gpio.write(led2, gpio.HIGH);
         client:send("{\"gpio_number\": 2, \"state\":1}");
      elseif(_GET.pin == "off2")then
         gpio.write(led2, gpio.LOW);
         client:send("{\"gpio_number\": 2, \"state\":0}");
      else
         
         buf = buf.."<h1>ESP8266 Web Server</h1>";
         buf = buf.."<p>GPIO0 <a href=\"?pin=on1\"><button>ON</button></a>&nbsp;<a href=\"?pin=off1\"><button>OFF</button></a> - "..gpio.read(led1).."</p>";
         buf = buf.."<p>GPIO2 <a href=\"?pin=on2\"><button>ON</button></a>&nbsp;<a href=\"?pin=off2\"><button>OFF</button></a> - "..gpio.read(led2).."</p>";
         client:send(buf);
      end
      
       
        client:close();
        collectgarbage();
    end)
end)



I have the latest NodeMCU custom firmware.
User avatar
By dkdileep
#23259 Please paste the code to NODEMCU and see at what point you get the out of memory error.
You can re-arrange the code into separate global functions rather than inline functions.
Also lots of decisions and buf..XX do not help. You just have 20K heap space.

You might be better off by serving HTML from a static file depending on all your boolean conditions.

You can also try to put this code in a file and do node.compile("file"). If the compilation works then you're more safer :)

PS: I wish NodeMCU had more RAM
User avatar
By TerryE
#23279 At its simplest you will probably have enough memory if you spilt your app into three compiled lua files: initial setup, and change the listener function to a few liner which (a) move client to a global and (b) does a get=require("parse_req")(request) followed by(c) a require("process_req")(get) using my ephemeral required function trick as describe in my FAQ.