ESP8266 based web configurable wifi general purpose control (Part II)

NOTE: Ready to go boards can be purchased here

On Part II I will go over how to program the ESP8266 so a USB to serial module and a terminal is not necessary: it will all be done via web. Also, I will explain how to drive a binary counter and control 4 relays (multi on/multi off) using GPIO0 as control and GPIO2 as reset. This way the ESP8266 really turns into a powerful device that can be added to any automation project and its easy to program on site.

The control firmware

The firmware needs to be able to allow the user to connect to the module and set the SSID and password of the network the module will be connected to. The steps to design the firmware are as follows:

  1. set the module to server (AP) mode
  2. set a name and password
  3. create a server
  4. listen on port 80
  5. module address is 192.168.4.1
  6. present a web page asking for SSID and password
  7. switch to Station mode and set SSID and password
  8. connect to network
  9. start listening for events coming on the ip address assigned by the network and port 9999

Here is the code to do it:

file.open(“init.lua”,”w”)
file.writeline([[print(“WIFI control”)]])
— put module in AP mode
file.writeline([[wifi.setmode(wifi.SOFTAP)]])
file.writeline([[print(“ESP8266 mode is: ” .. wifi.getmode())]])
file.writeline([[cfg={}]])
— Set the SSID of the module in AP mode and access password
file.writeline([[cfg.ssid=”ESP_STATION”]])
file.writeline([[cfg.pwd=”the_ESP8266_WIFI_password”]])
file.writeline([[if ssid and password then]])
file.writeline([[print(“ESP8266 SSID is: ” .. cfg.ssid .. ” and PASSWORD is: ” .. cfg.password)]])
file.writeline([[end]])
— Now you should see an SSID wireless router named ESP_STATION when you scan for available WIFI networks
— Lets connect to the module from a computer of mobile device. So, find the SSID and connect using the password selected
file.writeline([[wifi.ap.config(cfg)]])
file.writeline([[ap_mac = wifi.ap.getmac()]])
— create a server on port 80 and wait for a connection, when a connection is coming in function c will be executed
file.writeline([[sv=net.createServer(net.TCP,30)]])
file.writeline([[sv:listen(80,function(c)]])
file.writeline([[c:on(“receive”, function(c, pl)]])

— print the payload pl received from the connection
file.writeline([[print(pl)]])
file.writeline([[print(string.len(pl))]])

— wait until SSID comes back and parse the SSID and the password
file.writeline([[print(string.match(pl,”GET”))]])
file.writeline([[ssid_start,ssid_end=string.find(pl,”SSID=”)]])
file.writeline([[if ssid_start and ssid_end then]])
file.writeline([[amper1_start, amper1_end =string.find(pl,”&”, ssid_end+1)]])
file.writeline([[if amper1_start and amper1_end then]])
file.writeline([[http_start, http_end =string.find(pl,”HTTP/1.1″, ssid_end+1)]])
file.writeline([[if http_start and http_end then]])
file.writeline([[ssid=string.sub(pl,ssid_end+1, amper1_start-1)]])
file.writeline([[password=string.sub(pl,amper1_end+10, http_start-2)]])
file.writeline([[print(“ESP8266 connecting to SSID: ” .. ssid .. ” with PASSWORD: ” .. password)]])
file.writeline([[if ssid and password then]])
file.writeline([[sv:close()]])
— close the server and set the module to STATION mode
file.writeline([[wifi.setmode(wifi.STATIONAP)]])
file.writeline([[print(“ESP8266 mode now is: ” .. wifi.getmode())]])
— configure the module wso it can connect to the network using the received SSID and password
file.writeline([[wifi.sta.config(ssid,password)]])
file.writeline([[print(“Setting up ESP8266 for station mode…Please wait.”)]])
file.writeline([[tmr.delay(10000000)]])
file.writeline([[print(“ESP8266 STATION IP now is: ” .. wifi.sta.getip())]])
file.writeline([[print(“ESP8266 AP IP now is: ” .. wifi.ap.getip())]])
— now the module is configured and connected to the network so lets start setting things up for the control logic
file.writeline([[gpio.mode(8,gpio.OUTPUT)]])
file.writeline([[gpio.mode(9,gpio.OUTPUT)]])

file.writeline([[tmr.delay(10) ]])
file.writeline([[gpio.write(8,gpio.HIGH)]])
file.writeline([[tmr.delay(10)]])
file.writeline([[gpio.write(8,gpio.LOW)]])
file.writeline([[sv=net.createServer(net.TCP, 30) ]])
file.writeline([[sv:listen(9999,function(c)]])
file.writeline([[c:on(“receive”, function(c, pl)]])
file.writeline([[if tonumber(pl) ~= nil then]])
file.writeline([[if tonumber(pl) >= 1 and tonumber(pl) <= 16 then]])
file.writeline([[print(tonumber(pl))]])
file.writeline([[tmr.delay(10)]])
file.writeline([[gpio.write(8,gpio.HIGH)]])
file.writeline([[tmr.delay(10)]])
file.writeline([[gpio.write(8,gpio.LOW)]])
file.writeline([[for count =1,tonumber(pl) do]])
file.writeline([[ print(count)]])
file.writeline([[tmr.delay(10) ]])
file.writeline([[ gpio.write(9,gpio.LOW)]])
file.writeline([[tmr.delay(10)]])
file.writeline([[gpio.write(9,gpio.HIGH)]])
file.writeline([[c:send(“Sequence finished”) ]])
file.writeline([[end]])
file.writeline([[end]])
file.writeline([[end]])

file.writeline([[print(“ESP8266 STATION IP now is: ” .. new_ip)]])

file.writeline([[c:send(“ESP8266 STATION IP now is: ” .. new_ip) ]])

file.writeline([[c:send(“Action completed”) ]])
file.writeline([[end)]])
file.writeline([[end)]])

file.writeline([[end]])
file.writeline([[end]])
file.writeline([[end]])
file.writeline([[end]])
— this is the web page that requests the SSID and password from the user
file.writeline([[c:send(“<!DOCTYPE html> “)]])
file.writeline([[c:send(“<html lang=’en’> “)]])
file.writeline([[c:send(“<body> “)]])
file.writeline([[c:send(“<h1>ESP8266 Wireless control setup</h1> “)]])
file.writeline([[mac_mess1 = “The module MAC address is: ” .. ap_mac]])
file.writeline([[mac_mess2 = “You will need this MAC address to find the IP address of the module, please take note of it.”]])

file.writeline([[c:send(“<h2>” .. mac_mess1 .. “</h2> “)]])
file.writeline([[c:send(“<h2>” .. mac_mess2 .. “</h2> “)]])
file.writeline([[c:send(“<h2>Enter SSID and Password for your WIFI router</h2> “)]])
file.writeline([[c:send(“</form> </body> </html>”)]])
file.writeline([[c:send(“<form action=” method=’get’>”)]])
file.writeline([[c:send(“SSID:”)]])
file.writeline([[c:send(“<input type=’text’ name=’SSID’ value=” maxlength=’100′ />”)]])
file.writeline([[c:send(“<br />”)]])
file.writeline([[c:send(“Password:”)]])
file.writeline([[c:send(“<input type=’text’ name=‘Password’ value=” maxlength=’100′ />”)]])
file.writeline([[c:send(“<input type=’submit’ value=’Submit’ />”)]])
file.writeline([[end)]])
file.writeline([[end)]])
file.close()

Loading the firmware and testing

Load the file with the code written above as explained in Part I. Once the file is sent to the module you should do a node.restart() and will see the following:

CompleteFirmware
OK. The module is now in AP mode so it is like a WIFI router and you should see ESP_STATION on your list of WIFI networks.

WIFI

Now connect to ESP_STATION using the password that you have programmed into the firmware, “the_ESP8266_WIFI_password” above. Now connect to 192.168.4.1 from a browser. You should see the webpage below. Enter SSID and password of your WIFI network so the ESP8266 can connect to it.

webpage

 

After a few seconds of waiting you should receive a message on the web browser with the IP address assigned to the module by your router; if you get a 0.0.0.0, just refresh the browser pointing to 192.168.4.1 and you should get the new IP address. Since for this test we are monitoring the ESP8266 through a serial terminal, lets check what the output was:

newIP

 

On your browser you should see:

NewIpOnBrowser

Now the ESP8266 is connected to our WIFI network and has IP address 192.168.1.49. However, if you don;t get the browser to show the IP address, you can always refer to the MAC address of the ESP8266 shown on the SSID/Password entry page and the user will have to find the IP address by going into the router setup, depending on what kind of router that is. I will in the future figure out how to ensure that IP address is always posted back to the browser.

Summary

On Part II we saw how to configure the ESP8266 directly from a web browser and bypassing the USB to serial. Now we are getting closer to something that can be commercialized.

On Part III (yes, sorry, I chopped it into 3 parts) I will show how to connect the GPIO0 and GPIO2 signals to some binary counters and driver to drive relays or any other device.

Advertisements

About hbouzas

Born in Buenos Aires, Argentina. Studied Physics at the University of Buenos Aires. Joined Schlumberger in February 1985 in Houston, Texas, and worked in several technical and managerial positions until 2000. From 2000 until 2008 held several management positions in Abingdon, UK; Calgary, Alberta and London, UK. Worked in the areas of Geophysical Exploration, Geological Modeling, Structural Modeling, Reservoir Modeling and Petroleum Economics and holds several patents. He is currently the Norway Technology Center Manager for Schlumberger Information Solutions and is based in Oslo and Stavanger. Main interest are software, technology, innovation, 3D visualization, design, human computer interaction, energy, environment.
This entry was posted in Uncategorized. Bookmark the permalink.

37 Responses to ESP8266 based web configurable wifi general purpose control (Part II)

  1. UC says:

    Thankx a lot. There were few syntax errors that we corrected and we successfully tested these till here in hardware.

    • hbouzas says:

      Thanks for the comment. Could you please point to the syntax errors so i can edit the post?

      • ucpatnaik says:

        The program is still working with some problem. Pls clarify why a bracket is missing at line 23 &24 as noted below but the program still works. There are 3( opens, but 2) close
        file.writeline([[sv:listen(80,function(c)]])
        file.writeline([[c:on(“receive”, function(c, pl)]])

  2. ucpatnaik says:

    pls note these inverted double commas “ ” are required to be replaced by ” ” as available in the key pad Besides that Line number 5 and 8 from the bottom have one ”extra , so that has to be removed appearing aafter value=.
    Below is the corrected code that works absolutely OK.But I face atypical problem though it works. While this code is pasted and executed on a lua uploader it works fine with init.lua size at some 2500 bytes but while i save the same on the ESP it generates an error that on the first line itself as init.lua:1: unexpected symbol near ‘?’. And the init.lua size is =0
    file.open(“init.lua”,”w”)
    file.writeline([[print(“WIFI control”)]])
    file.writeline([[wifi.setmode(wifi.SOFTAP)]])
    file.writeline([[print(“ESP8266 mode is: ” .. wifi.getmode())]])
    file.writeline([[cfg={}]])
    file.writeline([[cfg.ssid=”ESP_STATION”]])
    file.writeline([[cfg.pwd=”password”]])
    file.writeline([[if ssid and password then]])
    file.writeline([[print(“ESP8266 SSID is: ” .. cfg.ssid .. ” and PASSWORD is: ” .. cfg.password)]])
    file.writeline([[end]])
    file.writeline([[wifi.ap.config(cfg)]])
    file.writeline([[ap_mac = wifi.ap.getmac()]])
    file.writeline([[sv=net.createServer(net.TCP,30)]])
    file.writeline([[sv:listen(80, function(c)]])
    file.writeline([[c:on(“receive”, function(c, pl)]])

    file.writeline([[print(pl)]])
    file.writeline([[print(string.len(pl))]])
    file.writeline([[print(string.match(pl,”GET”))]])
    file.writeline([[ssid_start,ssid_end=string.find(pl,”SSID=”)]])
    file.writeline([[if ssid_start and ssid_end then]])
    file.writeline([[amper1_start, amper1_end =string.find(pl,”&”, ssid_end+1)]])
    file.writeline([[if amper1_start and amper1_end then]])
    file.writeline([[http_start, http_end =string.find(pl,”HTTP/1.1″, ssid_end+1)]])
    file.writeline([[if http_start and http_end then]])
    file.writeline([[ssid=string.sub(pl,ssid_end+1, amper1_start-1)]])
    file.writeline([[password=string.sub(pl,amper1_end+10, http_start-2)]])
    file.writeline([[print(“ESP8266 connecting to SSID: ” .. ssid .. ” with PASSWORD: ” .. password)]])
    file.writeline([[if ssid and password then]])
    file.writeline([[sv:close()]])
    file.writeline([[wifi.setmode(wifi.STATIONAP)]])
    file.writeline([[print(“ESP8266 mode now is: ” .. wifi.getmode())]])
    file.writeline([[wifi.sta.config(ssid,password)]])
    file.writeline([[print(“Setting up ESP8266 for station mode…Please wait.”)]])
    file.writeline([[tmr.delay(10000000)]])
    file.writeline([[print(“ESP8266 STATION IP now is: ” .. wifi.sta.getip())]])
    file.writeline([[print(“ESP8266 AP IP now is: ” .. wifi.ap.getip())]])
    file.writeline([[gpio.mode(8,gpio.OUTPUT)]])
    file.writeline([[gpio.mode(9,gpio.OUTPUT)]])

    file.writeline([[tmr.delay(10) ]])
    file.writeline([[gpio.write(8,gpio.HIGH)]])
    file.writeline([[tmr.delay(10)]])
    file.writeline([[gpio.write(8,gpio.LOW)]])
    file.writeline([[sv=net.createServer(net.TCP, 30) ]])
    file.writeline([[sv:listen(9999,function(c)]])
    file.writeline([[c:on(“receive”, function(c, pl)]])
    file.writeline([[if tonumber(pl) ~= nil then]])
    file.writeline([[if tonumber(pl) >= 1 and tonumber(pl) <= 16 then]])
    file.writeline([[print(tonumber(pl))]])
    file.writeline([[tmr.delay(10)]])
    file.writeline([[gpio.write(8,gpio.HIGH)]])
    file.writeline([[tmr.delay(10)]])
    file.writeline([[gpio.write(8,gpio.LOW)]])
    file.writeline([[for count =1,tonumber(pl) do]])
    file.writeline([[ print(count)]])
    file.writeline([[tmr.delay(10) ]])
    file.writeline([[ gpio.write(9,gpio.LOW)]])
    file.writeline([[tmr.delay(10)]])
    file.writeline([[gpio.write(9,gpio.HIGH)]])
    file.writeline([[c:send("Sequence finished") ]])
    file.writeline([[end]])
    file.writeline([[end]])
    file.writeline([[end]])

    file.writeline([[print("ESP8266 STATION IP now is: " .. new_ip)]])

    file.writeline([[c:send("ESP8266 STATION IP now is: " .. new_ip) ]])

    file.writeline([[c:send("Action completed") ]])
    file.writeline([[end)]])
    file.writeline([[end)]])

    file.writeline([[end]])
    file.writeline([[end]])
    file.writeline([[end]])
    file.writeline([[end]])
    file.writeline([[c:send(" “)]])
    file.writeline([[c:send(” “)]])
    file.writeline([[c:send(” “)]])
    file.writeline([[c:send(“ESP8266 Wireless control setup “)]])
    file.writeline([[mac_mess1 = “The module MAC address is: ” .. ap_mac]])
    file.writeline([[mac_mess2 = “You will need this MAC address to find the IP address of the module, please take note ofit.”]])

    file.writeline([[c:send(“” .. mac_mess1 .. ” “)]])
    file.writeline([[c:send(“” .. mac_mess2 .. ” “)]])
    file.writeline([[c:send(“Enter SSID and Password for your WIFI router “)]])
    file.writeline([[c:send(” “)]])
    file.writeline([[c:send(“”)]])
    file.writeline([[c:send(“SSID:”)]])
    file.writeline([[c:send(“”)]])
    file.writeline([[c:send(“”)]])
    file.writeline([[c:send(“Password:”)]])
    file.writeline([[c:send(“”)]])
    file.writeline([[c:send(“”)]])
    file.writeline([[end)]])
    file.writeline([[end)]])
    file.close()

  3. ucpatnaik says:

    O! my GOD while posting here the ” gets automatically changed to inverted commas

  4. CJ says:

    With latest NodeMCU fw, I get this upon reboot:

    > NodeMCU 0.9.5 build 20150107 powered by Lua 5.1.4
    lua: init.lua:81: ‘)’ expected near ‘method’

  5. ucpatnaik says:

    delete the ” before method and also delete ” after value= in 2 places in next few lines

  6. Moe says:

    NodeMCU 0.9.5 build 20150212 powered by Lua 5.1.4
    lua: not enough memory
    >
    this is what i get when i run following code in to interpreter
    file.open(“init.lua”,”w”)
    file.writeline([[print(“WIFI control”)]])
    — put module in AP mode
    file.writeline([[wifi.setmode(wifi.SOFTAP)]])
    file.writeline([[print(“ESP8266 mode is: ” .. wifi.getmode())]])
    file.writeline([[cfg={}]])
    — Set the SSID of the module in AP mode and access password
    file.writeline([[cfg.ssid=”ESP_DEVBRD”]])
    file.writeline([[cfg.pwd=”esp8266″]])
    file.writeline([[if ssid and password then]])
    file.writeline([[print(“ESP8266 SSID is: ” .. cfg.ssid .. ” and PASSWORD is: ” .. cfg.password)]])
    file.writeline([[end]])
    — Now you should see an SSID wireless router named ESP_STATION when you scan for available WIFI networks
    — Lets connect to the module from a computer of mobile device. So, find the SSID and connect using the password selected
    file.writeline([[wifi.ap.config(cfg)]])
    file.writeline([[ap_mac = wifi.ap.getmac()]])
    — create a server on port 80 and wait for a connection, when a connection is coming in function c will be executed
    file.writeline([[sv=net.createServer(net.TCP,30)]])
    file.writeline([[sv:listen(80,function(c)]])
    file.writeline([[c:on(“receive”, function(c, pl)]])

    — print the payload pl received from the connection
    file.writeline([[print(pl)]])
    file.writeline([[print(string.len(pl))]])

    — wait until SSID comes back and parse the SSID and the password
    file.writeline([[print(string.match(pl,”GET”))]])
    file.writeline([[ssid_start,ssid_end=string.find(pl,”SSID=”)]])
    file.writeline([[if ssid_start and ssid_end then]])
    file.writeline([[amper1_start, amper1_end =string.find(pl,”&”, ssid_end+1)]])
    file.writeline([[if amper1_start and amper1_end then]])
    file.writeline([[http_start, http_end =string.find(pl,”HTTP/1.1″, ssid_end+1)]])
    file.writeline([[if http_start and http_end then]])
    file.writeline([[ssid=string.sub(pl,ssid_end+1, amper1_start-1)]])
    file.writeline([[password=string.sub(pl,amper1_end+10, http_start-2)]])
    file.writeline([[print(“ESP8266 connecting to SSID: ” .. ssid .. ” with PASSWORD: ” .. password)]])
    file.writeline([[if ssid and password then]])
    file.writeline([[sv:close()]])
    — close the server and set the module to STATION mode
    file.writeline([[wifi.setmode(wifi.STATIONAP)]])
    file.writeline([[print(“ESP8266 mode now is: ” .. wifi.getmode())]])
    — configure the module wso it can connect to the network using the received SSID and password
    file.writeline([[wifi.sta.config(ssid,password)]])
    file.writeline([[print(“Setting up ESP8266 for station mode…Please wait.”)]])
    file.writeline([[tmr.delay(10000000)]])
    file.writeline([[print(“ESP8266 STATION IP now is: ” .. wifi.sta.getip())]])
    file.writeline([[print(“ESP8266 AP IP now is: ” .. wifi.ap.getip())]])
    — now the module is configured and connected to the network so lets start setting things up for the control logic
    file.writeline([[gpio.mode(8,gpio.OUTPUT)]])
    file.writeline([[gpio.mode(9,gpio.OUTPUT)]])

    file.writeline([[tmr.delay(10) ]])
    file.writeline([[gpio.write(8,gpio.HIGH)]])
    file.writeline([[tmr.delay(10)]])
    file.writeline([[gpio.write(8,gpio.LOW)]])
    file.writeline([[sv=net.createServer(net.TCP, 30) ]])
    file.writeline([[sv:listen(9999,function(c)]])
    file.writeline([[c:on(“receive”, function(c, pl)]])
    file.writeline([[if tonumber(pl) ~= nil then]])
    file.writeline([[if tonumber(pl) >= 1 and tonumber(pl) <= 16 then]])
    file.writeline([[print(tonumber(pl))]])
    file.writeline([[tmr.delay(10)]])
    file.writeline([[gpio.write(8,gpio.HIGH)]])
    file.writeline([[tmr.delay(10)]])
    file.writeline([[gpio.write(8,gpio.LOW)]])
    file.writeline([[for count =1,tonumber(pl) do]])
    file.writeline([[ print(count)]])
    file.writeline([[tmr.delay(10) ]])
    file.writeline([[ gpio.write(9,gpio.LOW)]])
    file.writeline([[tmr.delay(10)]])
    file.writeline([[gpio.write(9,gpio.HIGH)]])
    file.writeline([[c:send("Sequence finished") ]])
    file.writeline([[end]])
    file.writeline([[end]])
    file.writeline([[end]])

    file.writeline([[print("ESP8266 STATION IP now is: " .. new_ip)]])

    file.writeline([[c:send("ESP8266 STATION IP now is: " .. new_ip) ]])

    file.writeline([[c:send("Action completed") ]])
    file.writeline([[end)]])
    file.writeline([[end)]])

    file.writeline([[end]])
    file.writeline([[end]])
    file.writeline([[end]])
    file.writeline([[end]])
    — this is the web page that requests the SSID and password from the user
    file.writeline([[c:send(" “)]])
    file.writeline([[c:send(” “)]])
    file.writeline([[c:send(” “)]])
    file.writeline([[c:send(“ESP8266 Wireless control setup “)]])
    file.writeline([[mac_mess1 = “The module MAC address is: ” .. ap_mac]])
    file.writeline([[mac_mess2 = “You will need this MAC address to find the IP address of the module, please take note of it.”]])

    file.writeline([[c:send(“” .. mac_mess1 .. ” “)]])
    file.writeline([[c:send(“” .. mac_mess2 .. ” “)]])
    file.writeline([[c:send(“Enter SSID and Password for your WIFI router “)]])
    file.writeline([[c:send(” “)]])
    file.writeline([[c:send(“”)]])
    file.writeline([[c:send(“SSID:”)]])
    file.writeline([[c:send(“”)]])
    file.writeline([[c:send(“”)]])
    file.writeline([[c:send(“Password:”)]])
    file.writeline([[c:send(“”)]])
    file.writeline([[c:send(“”)]])
    file.writeline([[end)]])
    file.writeline([[end)]])
    file.close()
    this html portion has to be modified
    my email is azizimoe@gmail.com

  7. Hi,
    Thanks for code. After replacing all the double commas manually (couldn’t use find and replace as the double comma character was nor recognised), I now get an error init.lua:37: ambiguous syntax (function call x new statement) near ‘)’.
    I’m using NodeMCU with 0.9.5 build 20150105. Init.lua File size is 3577.
    Any suggestions for fix?
    Keep up the good work

  8. Itai says:

    Once successfully loaded, after reset ESP, I keep getting a reboot loop with this code….
    The only way I have is to reflash the module and try again.

  9. nonnie says:

    Please send a working lua file to my mail id sreenathsreekumar@yahoo.com.I am using ESP-01 with lua 0.9.5.

    • hbouzas says:

      Thanks for All the comments. The code shown here is as example only. It works under my environment which I tried to describe as accurately as possible. Unfortunately I cannot debug those cases that are showing problems, the potential for issues is quite large. Many people have taken the code and it worked as published.

      • Mike says:

        Horacio, thankyou very much for your efforts.

        It is much appreciated.

        I am, however, having a real problem using CoolTerm – it turns every ” into some unfathomable character.

        If I cut and paste, if I send a text file, if I send a string – same result.

        I don’t know what I am doing different that I get these errors:

        file.open(…init.lua…,…w…)
        stdin:1: unexpected symbol near ‘Ã’

      • ledaero says:

        Horacio, thank you very much for your efforts. It is much appreciated.

        I am, however, having a real problem using CoolTerm – it turns every ” into some unfathomable character.

        If I cut and paste, if I send a text file, if I send a string – same result.

        I don’t know what I am doing different that I get these errors:

        file.open(…init.lua…,…w…)
        stdin:1: unexpected symbol near ‘Ã’

      • hbouzas says:

        I suppose you are using a Mac and textedit to edit the files? To get the right ” you need to type Shft-CTL-” at the same time.
        Let me know if this was the problem.

  10. ledaero says:

    It most certainly was!

    It was a problem with copying from the web and pasting into textedit/TextWrangler.

    A lot of the ‘ ‘ were picked up as “, as were the — converted to -, for some strange reason. So all the comments were a problem, as were the values =” statements. Once I saw what was wrong, it was fine. Not bad for my first day with an ESP8266 and Lua. I think it’s going to be a happy relationship.

    I ended up editing the whole thing as a standalone init.lua document to load via ESPlorer and it worked fine, once I had all the syntax errors sorted out. I can really recommend ESPlorer and esptool for Mac users – it makes flashing firmware and loading files to your ESP a breeze.

    Now, all I need to do is find some way of getting mDNS response in NodeMCU and I will have a transportable module! 🙂

    Here is the code in Pastebin: http://pastebin.com/KHpUNnsR

    You can add a Pastebin plugin for WordPress, which would get rid of such transcription errors and make the code easier to read and copy!

    Again, thanks for the time you took to write this, to document it and to respond. I really appreciate it.

    • uc patnaik says:

      Thanks a lot for posting the corrected code. Can you please modify the same on the GPIO0 , ,GPIO1 code section to just switch on and off a LED by sending ON and OFF command instead of numbers for which the code is written?

  11. James Heires says:

    Thanks for the continued discussion on this clever lua script. I am trying again after discovering a bad 8266 module and replacing it. I’m now on 0.9.5 (20150214), and am also running out of memory, according to ESPlorer, when I attempt to Send to or Save to ESP. The only other script I have successfully Sent/Saved to ESP is about half as long (# of lines) as yours, so I tend to believe this error is correct. I don’t feel that the nodemcu firmware is at fault – what leads you to this conclusion?
    Not sure if this is helpful or not, but after partially loading your script above (with all the file.writeline statements converted into proper lua source code), I ran the node.heap() command and received a value of 14176. Does this mean that after loading the script, I still have 14K bytes remaining? Cuz, after removing init.lua from my 8266, I get a response of 21784. My editor (Notepad++) tells me that the script is 3523 bytes in length, which doesn’t make up the difference in heap sizes reported above.

    • hbouzas says:

      I suggest you modify the script and use node.compile to save memory. Also set all variables to nil when you are done with them and call collectgarbage()
      I am not sure whether loading a lua text file into the ESP chews the same amount of memory as the size of the file in bytes, thats a question for the NodeMCU guys.

    • ledaero says:

      The relation between the number of bytes of code and the number of bytes taken up in an MCU is not linear. For example local d = sqrt(b^2 – 4*a*c) takes about 25 bytes to code, but the result in storage will be quite different.

  12. ucpatnaik says:

    No knowledge on coding

    • ledaero says:

      Neither did I, so I sat down and learned.

      Never saw a Lua program until I saw this one. Took me about two days of being tenacious.

      If you can’t take the time to learn to code, mcu’s are probably not for you.

      • ucpatnaik says:

        I have spent more than 6 months for about 1800 hours on ESP8266,lua,node MCU,Thingspeak etc and have developed 8 IOT projects including this one which are already working successfully controlled from an Android based GUI application.I have gone one step ahead by eliminating the ESP by simply using a GSM modem with an internet enabled SIM for many other projects.The purpose of using the GSM was to get over the wifi SSID and password problem which needed to be written in the program, so not making it possible to be changed by any other user at different WiFi location. But for this I tried a lot to replace the number pulses in this project to simply a on and off but could not succeed.

    • ledaero says:

      So when you said “I have spent more than 6 months for about 1800 hours on ESP8266,lua,node MCU,Thingspeak etc and have developed 8 IOT projects including this one which are already working successfully controlled from an Android based GUI application.” what part of “no knowledge of coding” was that?

      Or is that teenspeak for “do my work for me”?

      Maybe I should try that – just demand that people do stuff for me. Who knows, it might work?

  13. hbouzas says:

    Using NodeMCU LUA implementation you can set the SSID and password remotely. Moreover, you can reprogram the ESP8266 module however you want by sending ad-hoc commands and translating them into LUA code. You can even set a fixed IP address if you want. I am doing this. The modules I am selling in Tindie have that implementation.
    I dont understand your comment: “But for this I tried a lot to replace the number pulses in this project to simply a on and off but could not succeed.” can you explain?

    • ledaero says:

      I’m more confused by “no knowledge of coding” followed by “1800 hours of coding”.

      Now if I could only get mDNS working… 🙂

      (let’s see if someone will do it for me…)

  14. Hi , guys, can anyone help me ?
    I used this code but error is occurring, the ESP keep restarting each time, and display the following message :

    NodeMCU 0.9.5 build 20150318 powered by Lua 5.1.4
    “Ê#
    ºþS:Õþ™RCú™RCl6´âø

    NodeMCU 0.9.5 build 20150318 powered by Lua 5.1.4
    “ʃ
    ÿ:6® ùAÂH| ³ø

    NodeMCU 0.9.5 build 20150318 powered by Lua 5.1.4
    “ʃ
    –ÃóƪÄrF!úAÊöð

    NodeMCU 0.9.5 build 20150318 powered by Lua 5.1.4
    “ʃ
    –ÃóƪÄrF!úAÊöð

    NodeMCU 0.9.5 build 20150318 powered by Lua 5.1.4

    • hbouzas says:

      Looks like you are running out of memory. Strip out some code and put a print( node.heap()) in a few places to check your heap memory

    • James Heires says:

      ManoelPS,
      Check your ESP power source and connections too. You may be short on current, which can cause the ESP to restart repeatedly. I use a 300mA wall-wart power source for my work, and I don’t see this kind of behavior.

  15. can any one please explain the program .. i am getting an error. below mention the error.
    >> print(pl)
    >> print(string.len(pl))
    >>
    >> . ]p
    . rJLNa.N|..Htx.p&.B.’3\D”N~..<~
    L. ]`.aDFsP..J"<..JsP..3\C.N~..J.
    @f. ]L.!.#pqG}Kd|..d.+. 3\B O~.6<y
    .v,v0 ]PKEa@Fs.wHtx.P.+.'3\C"J~ .8|
    |.@]pJF!.N|,
    .2p0*&.+.'3D"N~.E<~
    NodeMcu 0.9.2 build 20141207 powered by Lua 5.1.4
    lua: init.lua:1: unexpected symbol near '\'

    please help…
    part1 of this tutorial is perfectly working for me.

    • hbouzas says:

      Looks like you are entering LUA commands on the double chevron prompt, that is a problem. The other stuff seems like a syntax issue.

      • hello sir,
        i am not entering lua commands. i am uploading .lua file.
        file.open(“init.lua”,”w”)
        print(“WIFI control”)
        wifi.setmode(wifi.SOFTAP)
        print(“The ESP8266 WiFi mode is: ” .. wifi.getmode())
        cfg={}
        cfg.ssid=”ESP_STATION”
        cfg.pwd=”password”
        if cfg.ssid and cfg.pwd then
        print(“ESP8266 SSID is ” .. cfg.ssid .. ” and PASSWORD is: ” .. cfg.pwd)
        end

        — Now you should see an SSID wireless router named ESP_STATION when you scan for available WIFI networks
        — Lets connect to the module from a computer of mobile device. So, find the SSID and connect using the password selected
        wifi.ap.config(cfg)
        ap_mac = wifi.ap.getmac()

        — create a server on port 80 and wait for a connection, when a connection is coming in function c will be executed
        sv=net.createServer(net.TCP,30)
        sv:listen(80,function(c)
        c:on(“receive”, function(c, pl)

        — print the payload pl received from the connection
        print(pl)
        print(string.len(pl))

        — wait until SSID comes back and parse the SSID and the password
        print(string.match(pl,”GET”))
        ssid_start,ssid_end=string.find(pl,”SSID=”)
        if ssid_start and ssid_end then
        amper1_start, amper1_end =string.find(pl,”&”, ssid_end+1)
        if amper1_start and amper1_end then
        http_start, http_end =string.find(pl,”HTTP/1.1″, ssid_end+1)
        if http_start and http_end then
        ssid=string.sub(pl,ssid_end+1, amper1_start-1)
        password=string.sub(pl,amper1_end+10, http_start-2)
        print(“ESP8266 connecting to SSID: ” .. ssid .. ” with PASSWORD: ” .. password)
        if ssid and password then
        sv:close()
        — close the server and set the module to STATION mode
        wifi.setmode(wifi.STATIONAP)
        print(“ESP8266 mode now is: ” .. wifi.getmode())
        — configure the module wso it can connect to the network using the received SSID and password
        wifi.sta.config(ssid,password)
        print(“Setting up ESP8266 for station mode…Please wait.”)
        tmr.delay(10000000)
        print(“ESP8266 STATION IP now is: ” .. wifi.sta.getip())
        print(“ESP8266 AP IP now is: ” .. wifi.ap.getip())
        — now the module is configured and connected to the network so lets start setting things up for the control logic
        gpio.mode(8,gpio.OUTPUT)
        gpio.mode(9,gpio.OUTPUT)

        tmr.delay(10)
        gpio.write(8,gpio.HIGH)
        tmr.delay(10)
        gpio.write(8,gpio.LOW)
        sv=net.createServer(net.TCP, 30)
        sv:listen(9999,function(c)
        c:on(“receive”, function(c, pl)
        if tonumber(pl) ~= nil then
        if tonumber(pl) >= 1 and tonumber(pl) <= 16 then
        print(tonumber(pl))
        tmr.delay(10)
        gpio.write(8,gpio.HIGH)
        tmr.delay(10)
        gpio.write(8,gpio.LOW)
        for count =1,tonumber(pl) do
        print(count)
        tmr.delay(10)
        gpio.write(9,gpio.LOW)
        tmr.delay(10)
        gpio.write(9,gpio.HIGH)
        c:send("Sequence finished")
        end
        end
        end

        print("ESP8266 STATION IP now is: " .. new_ip)

        c:send("ESP8266 STATION IP now is: " .. new_ip)

        c:send("Action completed")
        end)
        end)

        end
        end
        end
        end
        — this is the web page that requests the SSID and password from the user
        c:send(" “)
        c:send(” “)
        c:send(” “)
        c:send(“Wifi Wireless control setup “)
        mac_mess1 = “The module MAC address is: ” .. ap_mac
        mac_mess2 = “You will need this MAC address to find the IP address of the module, please take note of it.”

        c:send(“” .. mac_mess1 .. ” “)
        c:send(“” .. mac_mess2 .. ” “)
        c:send(“Enter SSID and Password for your WIFI router “)
        c:send(” “)
        c:send(“”)
        c:send(“SSID:”)
        c:send(“”)
        c:send(“”)
        c:send(“Password:”)
        c:send(“”)
        c:send(“”)
        end)
        end)
        above code i am using in init.lua file.

        the output i am getting in CoolTerm is mention below

        > file.open(“init.lua”,”w”)
        >
        > print(“WIFI control”)
        WIFI control
        > wifi.setmode(wifi.SOFTAP)
        > print(“The ESP8266 WiFi mode is: ” .. wifi.getmode())
        The ESP8266 WiFi mode is: 2
        >
        > cfg={}
        > cfg.ssid=”ESP_STATION”
        > cfg.pwd=”password”
        > if cfg.ssid and cfg.pwd then
        >> print(“ESP8266 SSID is ” .. cfg.ssid .. ” and PASSWORD is: ” .. cfg.pwd)
        >> end
        ESP8266 SSID is ESP_STATION and PASSWORD is: password
        >
        >
        > — Now you should see an SSID wireless router named ESP_STATION when you scan for available WIFI networks
        > — Lets connect to the module from a computer of mobile device. So, find the SSID and connect using the password selected
        > wifi.ap.config(cfg)
        > ap_mac = wifi.ap.getmac()
        >
        > — create a server on port 80 and wait for a connection, when a connection is coming in function c will be executed
        > sv=net.createServer(net.TCP,30)
        > sv:listen(80,function(c)
        >>
        >> c:on(“receive”, function(c, pl)
        >>
        >> — print the payload pl received from the connection
        >> print(pl)
        >> print(string.len(pl))
        >>
        >> — wait until SSID comes back and parse the SSID and the password
        >>
        >> print(string.match(pl,”GET”))
        >>
        >> ssid_start,ssid_end=string.find(pl,”SSID=”)
        >>
        >> if ssid_start and ssid_end then
        >> amper1_start, amper1_end =string.find(pl,”&”, ssid_end+1)
        >> if amper1_start and amper1_end then
        >> http_start, http_end =string.find(pl,”HTTP/1.1″, ssid_end+1)
        >>
        >> if http_start and http_end then
        >> ssid=string.sub(pl,ssid_end+1, amper1_start-1)
        >>
        >> password=string.sub(pl,amper1_end+10, http_start-2)
        >> print(“ESP8266 connecting to SSID: ” .. ssid .. ” with PASSWORD: ” .. password)
        >> if ssid and password then
        >> sv:close()
        >> — close the server and set the module to STATION mode
        >> wifi.setmode(wifi.STATIONAP)
        >> print(“ESP8266 mode now is: ” .. wifi.getmode())
        >> — configure the module wso it can connect to the network using the received SSID and password
        >> wifi.sta.config(ssid,password)
        >> print(“Setting up ESP8266 for station modePlease wait.”)
        >> tmr.delay(10000000)
        >> print(“ESP8266 STATION IP now is: ” .. wifi.sta.getip())
        >> print(“ESP8266 AP IP now is: ” .. wifi.ap.getip())
        >> — now the module is configured and connected to the network so lets start setting things up for the control logic
        >> gpio.mode(8,gpio.OUTPUT)
        >> . rJLNa.DN|G}[t|..d.+..LTB!O~.6,~
        NodeMcu 0.9.2 build 20141207 powered by Lua 5.1.4
        lua: init.lua:1: unexpected symbol near ‘\’
        > gpio.mode(9,gpio.OUTPUT)
        >
        > tmr.delay(10)
        > gpio.write(8,gpio.HIGH)
        > tmr.delay(10)
        > gpio.write(8,gpio.LOW)
        > sv=net.createServer(net.TCP, 30)
        > sv:listen(9999,function(c)
        >>
        >> c:on(“receive”, function(c, pl)
        >> if tonumber(pl) ~= nil then
        >> if tonumber(pl) >= 1 and tonumber(pl) > print(tonumber(pl))
        >> tmr.delay(10)
        >> gpio.write(8,gpio.HIGH)
        >> tmr.delay(10)
        >> gpio.write(8,gpio.LOW)
        >> for count =1,tonumber(pl) do
        >> print(count)
        >> tmr.delay(10)
        >> gpio.write(9,gpio.LOW)
        >> tmr.delay(10)
        >> gpio.write(9,gpio.HIGH)
        >> c:send(“Sequence finished”)
        >> end
        >> end
        >>
        >> end
        >>
        >>
        >> print(“ESP8266 STATION IP now is: ” .. new_ip)
        >>
        >> c:send(“ESP8266 STATION IP now is: ” .. new_ip)
        >>
        >>
        >> c:send(“Action completed”)
        >> end)
        >> end)
        >
        >
        > end
        stdin:1: ” expected near ‘end’
        > end
        stdin:1: ” expected near ‘end’
        > end
        stdin:1: ” expected near ‘end’
        > end
        stdin:1: ” expected near ‘end’
        >
        > — this is the web page that requests the SSID and password from the user
        >
        > c:send(” “)
        stdin:1: attempt to index global ‘c’ (a nil value)
        > c:send(” “)
        stdin:1: attempt to index global ‘c’ (a nil value)
        > c:send(” “)
        stdin:1: attempt to index global ‘c’ (a nil value)
        >
        > c:send(“Wifi Wireless control setup “)
        stdin:1: attempt to index global ‘c’ (a nil value)
        > mac_mess1 = “The module MAC address is: ” .. ap_mac
        stdin:1: attempt to concatenate global ‘ap_mac’ (a nil value)
        > mac_mess2 = “You will need this MAC address to find the IP address of the module, please take note of it.”
        >
        > c:send(“” .. mac_mess1 .. ” “)
        stdin:1: attempt to index global ‘c’ (a nil value)
        > c:send(“” .. mac_mess2 .. ” “)
        stdin:1: attempt to index global ‘c’ (a nil value)
        > c:send(“Enter SSID and Password for your WIFI router “)
        stdin:1: attempt to index global ‘c’ (a nil value)
        > c:send(” “)
        stdin:1: attempt to index global ‘c’ (a nil value)
        > c:send(“”)
        stdin:1: attempt to index global ‘c’ (a nil value)
        >
        > c:send(“SSID:”)
        stdin:1: attempt to index global ‘c’ (a nil value)
        > c:send(“”)
        stdin:1: attempt to index global ‘c’ (a nil value)
        > c:send(“”)
        stdin:1: attempt to index global ‘c’ (a nil value)
        >
        > c:send(“Password:”)
        stdin:1: attempt to index global ‘c’ (a nil value)
        > c:send(“”)
        stdin:1: attempt to index global ‘c’ (a nil value)
        > c:send(“”)
        stdin:1: attempt to index global ‘c’ (a nil value)
        > end)
        stdin:1: ” expected near ‘end’
        > end)
        stdin:1: ” expected near ‘end’
        > file.close()
        > node.restart()
        .v,.D.1.~.LC..Jzbgf.hD`n
        NodeMcu 0.9.2 build 20141207 powered by Lua 5.1.4
        lua: init.lua:1: unexpected symbol near ‘\’
        > . ]p
        a.DN|G}Kt|.d.+..LTC O~…
        NodeMcu 0.9.2 build 20141207 powered by Lua 5.1.4
        lua: init.lua:1: unexpected symbol near ‘\’
        > . ]pJDa.N|..Htx.P’…3\L”N~..8|
        NodeMcu 0.9.2 build 20141207 powered by Lua 5.1.4
        lua: init.lua:1: unexpected symbol near ‘\’
        >

        sir please help me. getting error . And if possible can you please send me init.lua file in my mail i.e. mike@nutsandboltz.in

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s