how to setup a rapid development environment for NodeMCU and Lua scripts - Page 1
Forum section: electronics / projects

author: FrankBuss
author_rank: Unknown
timestamp: January 29, 2017, 03:01:49 am
content: I bought aNodeMcu Lua CH340G ESP8266 Wireless WIFI Internet Development Board Module TE437. First impression was bad, because it comes with no manual and the examples fromhttp://www.nodemcu.comdidn't work. Fortunately I foundthis page, which explains how to start working with it. I'll post the relevant information from it for my module, and at the end some advanced stuff for rapid development, where you can edit a Lua script on PC, and load it to the module over wifi with just pressing the reset button on it.I tested the board in Linux. lsusb shows this information:Code:Bus 001 Device 012: ID 1a86:7523 QinHeng Electronics HL-340 USB-Serial adapterThe board is a 0.9 hardware version according to the CNXSoft blog, with some disadvantages compared to the latest 1.0 version (wrong pin distance for a breadboard, fewer GPIOs). I can connect to the board with minicom (note: you have to disable hardware flow control, if enabled. On Windows you can use putty or any other terminal program that supports COM ports) :Code:minicom --device /dev/ttyUSB0 --baudrate 115200After pressing the reset button (it resets the ESP8266 module only, not the USB virtual COM port chip) it shows this information:Code:Ai-Thinker Technology Co. Ltd.readyI guess this is an old version or the AT command version, but no AT commands work. Ok, so I installed the latest pre-compiled firmware:Quote(if there is an error "ImportError: No module named serial", then do a "sudo python2 -m pip install pyserial". If you have only Python 2.x installed, you can use "python" instead of "python2", this is just my system, where I have Python 3.x installed, too).Then I can start minicom again. With 115200 baud it shows some garbage text and "MEM CHECK FAIL!!!" after reset. Looks like like there is still some problem, but it works. Later it switches to 9600 baud. When using 9600 baud, I can read this:Code:NodeMCU 0.9.6 build 20150704 powered by Lua 5.1.4lua: cannot open init.lua>Now I can interactively enterCode:print("Hello Lua")and it executes the command, and the examples fromhttp://www.nodemcu.comwork, too. That's a good start! Maybe the eBay seller just didn't care to flash the right firmware version.Now let's implement a webserver, which toggles the LED and another GPIO pin. Save this as init.lua (slightly modified script from the CNXSoft blog) :Code:wifi.setmode(wifi.STATION)wifi.sta.config("ROUTER_ESSID","WIFI_PASSWORD")print(wifi.sta.getip())gpio.mode(0, gpio.OUTPUT)gpio.mode(4, gpio.OUTPUT)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");endlocal _GET = {}if (vars ~= nil)thenfor k, v in string.gmatch(vars, "(%w+)=(%w+)&*") do_GET = vendendbuf = buf.."<h1> ESP8266 Web Server</h1>";buf = buf.."<p>GPIO0 <a href=\"?pin=ON1\"><button>ON</button></a> <a href=\"?pin=OFF1\"><button>OFF</button></a></p>";buf = buf.."<p>GPIO4 / LED <a href=\"?pin=ON2\"><button>ON</button></a> <a href=\"?pin=OFF2\"><button>OFF</button></a></p>";local _on,_off = "",""if(_GET.pin == "ON1")thengpio.write(0, gpio.HIGH);elseif(_GET.pin == "OFF1")thengpio.write(0, gpio.LOW);elseif(_GET.pin == "ON2")thengpio.write(4, gpio.HIGH);elseif(_GET.pin == "OFF2")thengpio.write(4, gpio.LOW);endclient:send(buf);client:close();collectgarbage();end)end)Replace ROUTER_ESSID and WIFI_PASSWORD with your router information. You can upload it to the module like this:QuoteAfter flashing, it restarts the module. With minicom you can get the IP address:Code:= wifi.sta.getip()("=" is a shortcut for "print" in the Lua shell)GPIO0 is labeled D0 on the board and GPIO4 is D4, and the blue LED on the board. That's one direction of an "internet of things" thing, now the other direction, the thing calling the internet.What I really like about Lua is the interactive shell in minicom, you can try anything you want without the usual compile/upload/run cycle. For a full API documentation take a look athttp://nodemcu.readthedocs.io/en/master/I have a local Apache server installed on my PC. To get a page from it, I can enter this in minicom (one line at a time, looks like it has some problems when you paste lots of data) :Code:conn = net.createConnection(net.TCP, false)conn:on("receive", function(conn, pl) print(pl) end)conn:connect(80, "192.168.11.27")conn:send("GET /init2.lua HTTP/1.1\r\nHost: localhost\r\n\r\n")Another nice feature of Lua is that you can execute source code from within Lua:Code:> test1='print("test")'> test2=loadstring(test1)> test2()testPutting it all together and for faster development, this init.lua script loads the file init2.lua from a server and executes it:Code:wifi.setmode(wifi.STATION)wifi.sta.config("ROUTER_ESSID","WIFI_PASSWORD")function executeString(s)local fun = loadstring(s)fun()endfunction stripHeader(s)local pos = string.find(s, "\r\n\r\n")return s:sub(pos + 4)endfunction runScript(host, url)receivedPage = ""conn = net.createConnection(net.TCP, false)conn:on("receive", function(conn, data) receivedPage = receivedPage .. data end)conn:on("disconnection", function(conn, data) executeString(stripHeader(receivedPage)) end)conn:connect(80, host)conn:send("GET /" .. url .. " HTTP/1.1\r\nHost: " .. host .. "\r\nConnection: close\r\n\r\n")endtmr.alarm(0, 3000, 1, function() tmr.stop(0) runScript("192.168.11.27","init2.lua") end)The 3 second delay before starting is necessary, because it needs some time after reset to establish the wifi connection. In later releases of the firmware you can use wifi.sta.eventMonReg, but for this you have to build your own version of the firmware, or use the firmware build service here:https://nodemcu-build.comFor the the later releases they don't provide a default firmware anymore, because they say there are too many modules which the user can select. Yeah, good idea for beginnersWith this setup, I can just change init2.lua on my PC, then hit the reset button on the module and the new code gets loaded. Once I'm done with developing, I can upload init2.lua to the platform, so that I don't need a local webserver anymore.An interesting application is to get data from the web and display it with some device, for example a clock. There is no internal clock in the firmware, but there is the rtctime module in later releases, which in combination with sntp.sync could be used to load the time from a NTP time server for initialization and then display it. Unfortunately none of these modules are in the old pre-compiled firmware archive.A simple solution for the old firmware is to create a PHP page on your server which returns the time. The server can be synchronized with ntpd to a NTP time server. For example save this as time.php on your webserver:Code:<?phpdate_default_timezone_set("Europe/Berlin");echodate('H:i:s',time());?>Then save this code for init2.lua:Code:function showTime(s)print(s)endfunction trim(s)return s:match "^%s*(.-)%s*$"endfunction stripHeader(s)local pos = string.find(s, "\r\n\r\n")return s:sub(pos + 4)endfunction getTime(host)receivedPage = ""conn = net.createConnection(net.TCP, false)conn:on("receive", function(conn, data) receivedPage = receivedPage .. data end)conn:on("disconnection", function(conn, data) showTime(trim(stripHeader(receivedPage))) end)conn:connect(80, host)conn:send("GET /time.php HTTP/1.1\r\nHost: " .. host .. "\r\nConnection: close\r\n\r\n")endtmr.alarm(0, 1000, 1, function() getTime("192.168.11.27") end)and in minicom you can see the time ticking after a reset:Code:NodeMCU 0.9.6 build 20150704 powered by Lua 5.1.4> 14:25:4814:25:4914:25:5014:25:5114:25:5214:25:5314:25:5414:25:55Of course, instead of the time, the PHP script can return any other information you want to display. Controlling the GPIO pins to show the info with a Nixie tube or any other display in the showTime function is trivial and left as an excercise for the reader.Conclusion: the firmware looks a bit rough, I wouldn't create mission critical projects with it, and if you bought a module with the wrong firmware, it is not easy for beginners to flash a new firmware and to get started, but once this is done and with my network load script, it is a nice platform for fast prototyping and hobby projects.

author: djnz
author_rank: Regular Contributor
timestamp: January 29, 2017, 06:50:59 am
content: Also consider:MicroPython ->https://docs.micropython.org/en/latest/esp8266/esp8266/tutorial/intro.htmlPlatformIO ->http://platformio.org/

author: FrankBuss
author_rank: Unknown
timestamp: April 15, 2017, 09:27:49 am
content: I think I'm 80% done with my WiFi ePaper project, which uses this module:https://hackaday.io/project/20466-wifi-epaper/log/57324-first-working-prototypePlease like the project on Hackaday.io, if you like it, because the project owners get one dollar for parts cost for each like

author: kripton2035
author_rank: Super Contributor
timestamp: April 15, 2017, 10:18:35 am
content: I definitely had stability issues with nodemcu/lua boards.I reprogrammed them with arduino ide and no more problems...

author: FrankBuss
author_rank: Unknown
timestamp: April 15, 2017, 10:45:40 am
content: What kind of stability problems? There are some traps for young players, like the watchdog timer, which can reset the module, if your Lua function runs too long without feeding the dog, or the default 4096 bytes limit for strings, which can be increased at runtime.

author: kripton2035
author_rank: Super Contributor
timestamp: April 15, 2017, 12:39:59 pm
content: frequent disconnections, module did not respond after some (varying) time. even if it was continuously sending datas, it stopped.redid the same program in arduino mode and no problem.it's not a watchdog problem because it should have restarted to send datas by itself even after a watchdog reset, but it stopped.