Add note about init.lua (#1353)

This commit is contained in:
Marcel Stör 2016-06-13 21:51:48 +02:00 committed by Arnim Läuger
parent 244c6e9db1
commit b47a56de7a
5 changed files with 129 additions and 627 deletions

View File

@ -47,7 +47,7 @@ The NodeMCU libraries act as C wrappers around registered Lua callback functions
### How is coding for the ESP8266 different to standard Lua?
* The ESP8266 use onchip RAM and offchip Flash memory connected using a dedicated SPI interface. Both of these are *very* limited (when compared to systems than most application programmer use). The SDK and the Lua firmware already use the majority of this resource: the later build versions keep adding useful functionality, and unfortunately at an increased RAM and Flash cost, so depending on the build version and the number of modules installed the runtime can have as little as 17KB RAM and 40KB Flash available at an application level. This Flash memory is formatted an made available as a **SPI Flash File System (SPIFFS)** through the `file` library.
* However, if you choose to use a custom build, for example one which uses integer arithmetic instead of floating point, and which omits libraries that aren't needed for your application, then this can help a lot doubling these available resources. (See Marcel Stör's excellent [custom build tool](http://frightanic.com/NodeMCU-custom-build/) that he discusses in [this forum topic](http://www.esp8266.com/viewtopic.php?f=23&t=3001)). Even so, those developers who are used to dealing in MB or GB of RAM and file systems can easily run out of these resources. Some of the techniques discussed below can go a long way to mitigate this issue.
* However, if you choose to use a custom build, for example one which uses integer arithmetic instead of floating point, and which omits libraries that aren't needed for your application, then this can help a lot doubling these available resources. (See Marcel Stör's excellent [custom build tool](http://nodemcu-build.com) that he discusses in [this forum topic](http://www.esp8266.com/viewtopic.php?f=23&t=3001)). Even so, those developers who are used to dealing in MB or GB of RAM and file systems can easily run out of these resources. Some of the techniques discussed below can go a long way to mitigate this issue.
* Current versions of the ESP8266 run the SDK over the native hardware so there is no underlying operating system to capture errors and to provide graceful failure modes, so system or application errors can easily "PANIC" the system causing it to reboot. Error handling has been kept simple to save on the limited code space, and this exacerbates this tendency. Running out of a system resource such as RAM will invariably cause a messy failure and system reboot.
* There is currently no `debug` library support. So you have to use 1980s-style "binary-chop" to locate errors and use print statement diagnostics though the systems UART interface. (This omission was largely because of the Flash memory footprint of this library, but there is no reason in principle why we couldn't make this library available in the near future as an custom build option).
* The LTR implementation means that you can't easily extend standard libraries as you can in normal Lua, so for example an attempt to define `function table.pack()` will cause a runtime error because you can't write to the global `table`. (Yes, there are standard sand-boxing techniques to achieve the same effect by using metatable based inheritance, but if you try to use this type of approach within a real application, then you will find that you run out of RAM before you implement anything useful.)
@ -59,6 +59,7 @@ The NodeMCU libraries act as C wrappers around registered Lua callback functions
```lua
node.restart(); for i = 1, 20 do print("not quite yet -- ",i); end
```
* You therefore *have* to implement ESP8266 Lua applications using an event driven approach. You have to understand which SDK API requests schedule asynchronous processing, and which define event actions through Lua callbacks. Yes, such an event-driven approach makes it difficult to develop procedurally structured applications, but it is well suited to developing the sorts of application that you will typically want to implement on an IoT device.
### So how does the SDK event / tasking system work in Lua?
@ -72,15 +73,15 @@ The NodeMCU libraries act as C wrappers around registered Lua callback functions
* In the case of Lua, these C tasks are typically functions within the Lua runtime library code and these typically act as C wrappers around the corresponding developer-provided Lua callback functions. An example here is the Lua `tmr.alarm(id, interval, repeat, callback)` function. The calls a function in the `tmr` library which registers a C function for this alarm using the SDK, and when this C function is called it then invokes the Lua callback.
The NodeMCU firmware simply mirrors this structure at a Lua scripting level:
* A startup module `init.lua` is invoked on boot. This function module can be used to do any initialisation required and to call the necessary timer alarms or libary calls to bind and callback routines to implement the tasks needed in response to any system events.
* The Lua libraries provide a set of functions for declaring application functions (written in Lua) as callbacks (which are stored in the [Lua registry](#so-how-is-the-lua-registry-used-and-why-is-this-important)) to associate application tasks with specific hardware and timer events. These are non-preemptive at an applications level.
* The Lua libraries work in consort with the SDK to queue pending events and invoke any registered Lua callback routines, which then run to completion uninterrupted.
* A startup module `init.lua` is invoked on boot. This function module can be used to do any initialisation required and to call the necessary timer alarms or library calls to bind and callback routines to implement the tasks needed in response to any system events.
* The Lua libraries provide a set of functions for declaring application functions (written in Lua) as callbacks (which are stored in the [Lua registry](#so-how-is-the-lua-registry-used-and-why-is-this-important)) to associate application tasks with specific hardware and timer events. These are non-preemptive at an applications level* The Lua libraries work in consort with the SDK to queue pending events and invoke any registered Lua callback routines, which then run to completion uninterrupted.
* Excessively long-running Lua functions can therefore cause other system functions and services to timeout, or allocate memory to buffer queued data, which can then trigger either the watchdog timer or memory exhaustion, both of which will ultimately cause the system to reboot.
* By default, the Lua runtime also 'listens' to UART 0, the serial port, in interactive mode and will execute any Lua commands input through this serial port.
This event-driven approach is very different to a conventional procedural implementation of Lua.
Consider a simple telnet example given in `examples/fragment.lua`:
Consider the following snippet:
```lua
s=net.createServer(net.TCP)

View File

@ -1,8 +1,10 @@
As with [flashing](flash.md) there are several ways to upload code from your computer to the device.
Note that the NodeMCU serial interface uses 115200bps at boot time. To change the speed after booting, issue `uart.setup(0,9600,8,0,1,1)`. ESPlorer will do this automatically when changing the speed in the dropdown list. If the device panics and resets at any time, errors will be written to the serial interface at 115200 bps.
Note that the NodeMCU serial interface uses 115'200bps at boot time. To change the speed after booting, issue `uart.setup(0,9600,8,0,1,1)`. ESPlorer will do this automatically when changing the speed in the dropdown list. If the device panics and resets at any time, errors will be written to the serial interface at 115'200 bps.
# ESPlorer
# Tools
## ESPlorer
> The essential multiplatforms tools for any ESP8266 developer from luatool authors, including Lua for NodeMCU and MicroPython. Also, all AT commands are supported. Requires Java (Standard Edition - SE ver 7 and above) installed.
@ -12,7 +14,7 @@ Source: [https://github.com/4refr0nt/ESPlorer](https://github.com/4refr0nt/ESPlo
Supported platforms: OS X, Linux, Windows, anything that runs Java
# nodemcu-uploader.py
## nodemcu-uploader.py
> A simple tool for uploading files to the filesystem of an ESP8266 running NodeMCU as well as some other useful commands.
@ -20,7 +22,7 @@ Source: [https://github.com/kmpm/nodemcu-uploader](https://github.com/kmpm/nodem
Supported platforms: OS X, Linux, Windows, anything that runs Python
# NodeMCU Studio
## NodeMCU Studio
> THIS TOOL IS IN REALLY REALLY REALLY REALLY EARLY STAGE!!!!!!!!!!!!!!!!!!!!!!!!!!!
@ -28,7 +30,7 @@ Source: [https://github.com/nodemcu/nodemcu-studio-csharp](https://github.com/no
Supported platforms: Windows
# luatool
## luatool
> Allow easy uploading of any Lua-based script into the ESP8266 flash memory with NodeMcu firmware
@ -36,6 +38,45 @@ Source: [https://github.com/4refr0nt/luatool](https://github.com/4refr0nt/luatoo
Supported platforms: OS X, Linux, Windows, anything that runs Python
# init.lua
You will see "lua: cannot open init.lua" printed to the serial console when the device boots after it's been freshly flashed. If NodeMCU finds a `init.lua` in the root of the file system it will execute it as part of the boot sequence (standard Lua feature). Hence, your application is initialized and triggered from `init.lua`. Usually you first set up the WiFi connection and only continue once that has been successful.
Be very careful not to lock yourself out! If there's a bug in your `init.lua` you may be stuck in an infinite reboot loop. It is, therefore, advisable to build a small delay into your startup sequence that would allow you to interrupt the sequence by e.g. deleting or renaming `init.lua` (see also [FAQ](lua-developer-faq.md#how-do-i-avoid-a-panic-loop-in-initlua)). Your `init.lua` is most likely going to be different than the one below but it's a good starting point for customizations:
```lua
-- load credentials, 'SSID' and 'PASSWORD' declared and initialize in there
dofile("credentials.lua")
function startup()
if file.open("init.lua") == nil then
print("init.lua deleted or renamed")
else
print("Running")
file.close("init.lua")
-- the actual application is stored in 'application.lua'
-- dofile("application.lua")
end
end
print("Connecting to WiFi access point...")
wifi.setmode(wifi.STATION)
wifi.sta.config(SSID, PASSWORD)
wifi.sta.connect()
tmr.alarm(1, 1000, 1, function()
if wifi.sta.getip() == nil then
print("Waiting for IP address...")
else
tmr.stop(1)
print("WiFi connection established, IP address: " .. wifi.sta.getip())
print("You have 3 seconds to abort")
print("Waiting...")
tmr.alarm(0, 3000, 0, startup)
end
end)
```
Inspired by [https://github.com/ckuehnel/NodeMCU-applications](https://github.com/ckuehnel/NodeMCU-applications)
# Compiling Lua on your PC for Uploading
If you install lua on your development PC or Laptop then you can use the standard Lua

View File

@ -1,521 +0,0 @@
pwm.setup(0,500,50) pwm.setup(1,500,50) pwm.setup(2,500,50)
pwm.start(0) pwm.start(1) pwm.start(2)
function led(r,g,b) pwm.setduty(0,g) pwm.setduty(1,b) pwm.setduty(2,r) end
wifi.sta.autoconnect(1)
a=0
tmr.alarm( 1000,1,function() if a==0 then a=1 led(50,50,50) else a=0 led(0,0,0) end end)
sv:on("receive", function(s,c) s:send("<h1> Hello, world.</h1>") print(c) end )
sk=net.createConnection(net.TCP, 0)
sk:on("receive", function(sck, c) print(c) end )
sk:connect(80,"115.239.210.27")
sk:send("GET / HTTP/1.1\r\nHost: 115.239.210.27\r\nConnection: keep-alive\r\nAccept: */*\r\n\r\n")
sk:connect(80,"192.168.0.66")
sk:send("GET / HTTP/1.1\r\nHost: 192.168.0.66\r\nConnection: keep-alive\r\nAccept: */*\r\n\r\n")
i2c.setup(0,1,0,i2c.SLOW)
function read_bmp(addr) i2c.start(0) i2c.address(0,119,i2c.RECEIVER) c=i2c.read(0,1) i2c.stop(0) print(string.byte(c)) end
function read_bmp(addr) i2c.start(0) i2c.address(0,119,i2c.TRANSMITTER) i2c.write(0,addr) i2c.stop(0) i2c.start(0) i2c.address(0,119,i2c.RECEIVER) c=i2c.read(0,2) i2c.stop(0) return c end
s=net.createServer(net.TCP) s:listen(80,function(c) end)
ss=net.createServer(net.TCP) ss:listen(80,function(c) end)
s=net.createServer(net.TCP) s:listen(80,function(c) c:on("receive",function(s,c) print(c) end) end)
s=net.createServer(net.UDP)
s:on("receive",function(s,c) print(c) end)
s:listen(5683)
su=net.createConnection(net.UDP)
su:on("receive",function(su,c) print(c) end)
su:connect(5683,"192.168.18.101")
su:send("hello")
mm=node.list()
for k, v in pairs(mm) do print('file:'..k..' len:'..v) end
for k,v in pairs(d) do print("n:"..k..", s:"..v) end
gpio.mode(0,gpio.INT) gpio.trig(0,"down",function(l) print("level="..l) end)
t0 = 0;
function tr0(l) print(tmr.now() - t0) t0 = tmr.now()
if l==1 then gpio.trig(0,"down") else gpio.trig(0,"up") end end
gpio.mode(0,gpio.INT)
gpio.trig(0,"down",tr0)
su=net.createConnection(net.UDP)
su:on("receive",function(su,c) print(c) end)
su:connect(5001,"114.215.154.114")
su:send([[{"type":"signin","name":"nodemcu","password":"123456"}]])
su:send([[{"type":"signout","name":"nodemcu","password":"123456"}]])
su:send([[{"type":"connect","from":"nodemcu","to":"JYP","password":"123456"}]])
su:send("hello world")
s=net.createServer(net.TCP) s:listen(8008,function(c) c:on("receive",function(s,c) print(c) pcall(loadstring(c)) end) end)
s=net.createServer(net.TCP) s:listen(8008,function(c) con_std = c function s_output(str) if(con_std~=nil) then con_std:send(str) end end
node.output(s_output, 0) c:on("receive",function(c,l) node.input(l) end) c:on("disconnection",function(c) con_std = nil node.output(nil) end) end)
s=net.createServer(net.TCP)
s:listen(23,function(c)
con_std = c
function s_output(str)
if(con_std~=nil)
then con_std:send(str)
end
end
node.output(s_output, 0)
c:on("receive",function(c,l) node.input(l) end)
c:on("disconnection",function(c)
con_std = nil
node.output(nil)
end)
end)
srv=net.createServer(net.TCP) srv:listen(80,function(conn) conn:on("receive",function(conn,payload)
print(node.heap()) door="open" if gpio.read(8)==1 then door="open" else door="closed" end
conn:send("<h1> Door Sensor. The door is " .. door ..".</h1>") conn:close() end) end)
srv=net.createServer(net.TCP) srv:listen(80,function(conn) conn:on("receive",function(conn,payload)
print(node.heap()) print(adc.read(0)) door="open" if gpio.read(0)==1 then door="open" else door="closed" end
conn:send("<h1> Door Sensor. The door is " .. door ..".</h1>") end) conn:on("sent",function(conn) conn:close() end) end)
srv=net.createServer(net.TCP) srv:listen(80,function(conn)
conn:on("receive",function(conn,payload)
print(node.heap())
door="open"
if gpio.read(0)==1 then door="open" else door="closed" end
conn:send("<h1> Door Sensor. The door is " .. door ..".</h1>")
end)
conn:on("sent",function(conn) conn:close() end)
end)
port = 9999
hostip = "192.168.1.99"
sk=net.createConnection(net.TCP, false)
sk:on("receive", function(conn, pl) print(pl) end )
sk:connect(port, hostip)
file.remove("init.lua")
file.open("init.lua","w")
file.writeline([[print("Petes Tester 4")]])
file.writeline([[tmr.alarm(5000, 0, function() dofile("thelot.lua") end )]])
file.close()
file.remove("thelot.lua")
file.open("thelot.lua","w")
file.writeline([[tmr.stop()]])
file.writeline([[connecttoap = function (ssid,pw)]])
file.writeline([[print(wifi.sta.getip())]])
file.writeline([[wifi.setmode(wifi.STATION)]])
file.writeline([[tmr.delay(1000000)]])
file.writeline([[wifi.sta.config(ssid,pw)]])
file.writeline([[tmr.delay(5000000)]])
file.writeline([[print("Connected to ",ssid," as ",wifi.sta.getip())]])
file.writeline([[end]])
file.writeline([[connecttoap("MyHub","0011223344")]])
file.close()
s=net.createServer(net.UDP) s:listen(5683) s:on("receive",function(s,c) print(c) s:send("echo:"..c) end)
s:on("sent",function(s) print("echo donn") end)
sk=net.createConnection(net.UDP, 0) sk:on("receive", function(sck, c) print(c) end ) sk:connect(8080,"192.168.0.88")
sk:send("GET / HTTP/1.1\r\nHost: 192.168.0.88\r\nConnection: keep-alive\r\nAccept: */*\r\n\r\n")
srv=net.createServer(net.TCP, 5) srv:listen(80,function(conn) conn:on("receive",function(conn,payload)
print(node.heap()) print(adc.read(0)) door="open" if gpio.read(0)==1 then door="open" else door="closed" end
conn:send("<h1> Door Sensor. The door is " .. door ..".</h1>") end) end)
srv=net.createServer(net.TCP)
srv:listen(80,function(conn)
conn:on("receive",function(conn,payload)
print(payload) print(node.heap())
conn:send("<h1> Hello, NodeMcu.</h1>")
end)
conn:on("sent",function(conn) conn:close() end)
end)
function startServer()
print("WIFI AP connected. Wicon IP:")
print(wifi.sta.getip())
sv=net.createServer(net.TCP,180)
sv:listen(8080,function(conn)
print("Wifi console connected.")
function s_output(str)
if(conn~=nil) then
conn:send(str)
end
end
node.output(s_output,0)
conn:on("receive",function(conn,pl)
node.input(pl)
if (conn==nil) then
print("conn is nil")
end
print("hello")
mycounter=0 srv=net.createServer(net.TCP) srv:listen(80,function(conn) conn:on("receive",function(conn,payload)
if string.find(payload,"?myarg=") then mycounter=mycounter+1
m="<br/>Value= " .. string.sub(payload,string.find(payload,"?myarg=")+7,string.find(payload,"HTTP")-2) else m="" end
conn:send("<h1> Hello, this is Pete's web page.</h1>How are you today.<br/> Count=" .. mycounter .. m .. "Heap=".. node.heap())
end) conn:on("sent",function(conn) conn:close() conn = nil end) end)
srv=net.createServer(net.TCP) srv:listen(80,function(conn) conn:on("receive",function(conn,payload)
conn:send("HTTP/1.1 200 OK\r\n") conn:send("Connection: close\r\n\r\n") conn:send("<h1> Hello, NodeMcu.</h1>")
print(node.heap()) conn:close() end) end)
conn=net.createConnection(net.TCP)
conn:dns("www.nodemcu.com",function(conn,ip) print(ip) print("hell") end)
function connected(conn) conn:on("receive",function(conn,payload)
conn:send("HTTP/1.1 200 OK\r\n") conn:send("Connection: close\r\n\r\n") conn:send("<h1> Hello, NodeMcu.</h1>")
print(node.heap()) conn:close() end) end
srv=net.createServer(net.TCP)
srv:on("connection",function(conn) conn:on("receive",function(conn,payload)
conn:send("HTTP/1.1 200 OK\r\n") conn:send("Connection: close\r\n\r\n") conn:send("<h1> Hello, NodeMcu.</h1>")
print(node.heap()) conn:close() end) end)
srv:listen(80)
-- sieve.lua
-- the sieve of Eratosthenes programmed with coroutines
-- typical usage: lua -e N=500 sieve.lua | column
-- generate all the numbers from 2 to n
function gen (n) return coroutine.wrap(function () for i=2,n do coroutine.yield(i) end end) end
-- filter the numbers generated by `g', removing multiples of `p'
function filter (p, g) return coroutine.wrap(function () for n in g do if n%p ~= 0 then coroutine.yield(n) end end end) end
N=N or 500 -- from command line
x = gen(N) -- generate primes up to N
while 1 do
local n = x() -- pick a number until done
if n == nil then break end
print(n) -- must be a prime number
x = filter(n, x) -- now remove its multiples
end
file.remove("mylistener.lua")
file.open("mylistener.lua","w")
file.writeline([[gpio2 = 9]])
file.writeline([[gpio0 = 8]])
file.writeline([[gpio.mode(gpio2,gpio.OUTPUT)]])
file.writeline([[gpio.write(gpio2,gpio.LOW)]])
file.writeline([[gpio.mode(gpio0,gpio.OUTPUT)]])
file.writeline([[gpio.write(gpio0,gpio.LOW)]])
file.writeline([[l1="0\n"]])
file.writeline([[l2="0\n"]])
file.writeline([[l3="0\n"]])
file.writeline([[l4="0\n"]])
file.writeline([[sv=net.createServer(net.TCP, 5) ]])
file.writeline([[sv:listen(4000,function(c)]])
file.writeline([[c:on("disconnection", function(c) print("Bye") end )]])
file.writeline([[c:on("receive", function(sck, pl) ]])
-- file.writeline([[print(pl) ]])
file.writeline([[if (pl=="GO1\n") then c:send(l1) ]])
file.writeline([[elseif pl=="GO2\n" then c:send(l2) ]])
file.writeline([[elseif pl=="GO3\n" then c:send(l3) ]])
file.writeline([[elseif pl=="GO4\n" then c:send(l4) ]])
file.writeline([[elseif pl=="YES1\n" then l1="1\n" c:send("OK\n") gpio.write(gpio2,gpio.HIGH) ]])
file.writeline([[elseif pl=="NO1\n" then l1="0\n" c:send("OK\n") gpio.write(gpio2,gpio.LOW) ]])
file.writeline([[elseif pl=="YES2\n" then l2="1\n" c:send("OK\n") gpio.write(gpio0,gpio.HIGH) ]])
file.writeline([[elseif pl=="NO2\n" then l2="0\n" c:send("OK\n") gpio.write(gpio0,gpio.LOW) ]])
file.writeline([[elseif pl=="YES3\n" then l3="1\n" c:send("OK\n") print(node.heap()) ]])
file.writeline([[elseif pl=="NO3\n" then l3="0\n" c:send("OK\n") print(node.heap()) ]])
file.writeline([[elseif pl=="YES4\n" then l4="1\n" c:send("OK\n") print(node.heap()) ]])
file.writeline([[elseif pl=="NO4\n" then l4="0\n" c:send("OK\n") print(node.heap()) ]])
file.writeline([[else c:send("0\n") print(node.heap()) ]])
file.writeline([[end]])
file.writeline([[end)]])
file.writeline([[end)]])
file.close()
file.remove("myli.lua") file.open("myli.lua","w")
file.writeline([[sv=net.createServer(net.TCP, 5) ]])
file.writeline([[sv:listen(4000,function(c)]])
file.writeline([[c:on("disconnection", function(c) print("Bye") end )]])
--file.writeline([[c:on("sent", function(c) c:close() end )]])
file.writeline([[c:on("receive", function(sck, pl) ]])
file.writeline([[sck:send("0\n") print(node.heap()) ]])
file.writeline([[end)]]) file.writeline([[end)]]) file.close()
sv=net.createServer(net.TCP, 50) sv:listen(4000,function(c) c:on("disconnection",function(c) print("Bye") end)
c:on("receive", function(sck, pl) sck:send("0\n") print(node.heap()) end) end)
sv=net.createServer(net.TCP, 5) sv:listen(4000,function(c) c:on("disconnection",function(c) print("Bye") end)
c:on("receive", function(sck, pl) sck:send("0\n") print(node.heap()) end) c:on("sent", function(sck) sck:close() end) end)
s=net.createServer(net.UDP)
s:on("receive",function(s,c) print(c) end)
s:listen(8888)
print("This is a long long long line to test the memory limit of nodemcu firmware\n")
collectgarbage("setmemlimit",8)
print(collectgarbage("getmemlimit"))
tmr.alarm(1,5000,1,function() print("alarm 1") end)
tmr.stop(1)
tmr.alarm(0,1000,1,function() print("alarm 0") end)
tmr.stop(0)
tmr.alarm(2,2000,1,function() print("alarm 2") end)
tmr.stop(2)
tmr.alarm(6,2000,1,function() print("alarm 6") end)
tmr.stop(6)
for k,v in pairs(_G.package.loaded) do print(k) end
for k,v in pairs(_G) do print(k) end
for k,v in pairs(d) do print("n:"..k..", s:"..v) end
a="pin=9"
t={}
for k, v in string.gmatch(a, "(%w+)=(%w+)") do t[k]=v end
print(t["pin"])
function switch() gpio.mode(4,gpio.OUTPUT) gpio.mode(5,gpio.OUTPUT) tmr.delay(1000000) print("hello world") end
tmr.alarm(0,10000,0,function () uart.setup(0,9600,8,0,1) end) switch()
sk=net.createConnection(net.TCP, 0) sk:on("receive", function(sck, c) print(c) end ) sk:connect(80,"www.nodemcu.com") sk:send("GET / HTTP/1.1\r\nHost: www.nodemcu.com\r\nConnection: keep-alive\r\nAccept: */*\r\n\r\n")
sk=net.createConnection(net.TCP, 0) sk:on("receive", function(sck, c) print(c) end )
sk:on("connection", function(sck) sck:send("GET / HTTP/1.1\r\nHost: www.nodemcu.com\r\nConnection: keep-alive\r\nAccept: */*\r\n\r\n") end ) sk:connect(80,"www.nodemcu.com")
sk=net.createConnection(net.TCP, 0) sk:on("receive", function(sck, c) print(c) end ) sk:connect(80,"115.239.210.27")
sk:send("GET / HTTP/1.1\r\nHost: 115.239.210.27\r\nConnection: keep-alive\r\nAccept: */*\r\n\r\n")
sk=net.createConnection(net.TCP, 1) sk:on("receive", function(sck, c) print(c) end )
sk:on("connection", function(sck) sck:send("GET / HTTPS/1.1\r\nHost: www.google.com.hk\r\nConnection: keep-alive\r\nAccept: */*\r\n\r\n") end ) sk:connect(443,"173.194.72.199")
wifi.sta.setip({ip="192.168.18.119",netmask="255.255.255.0",gateway="192.168.18.1"})
uart.on("data","\r",function(input) if input=="quit\r" then uart.on("data") else print(input) end end, 0)
uart.on("data","\n",function(input) if input=="quit\n" then uart.on("data") else print(input) end end, 0)
uart.on("data", 5 ,function(input) if input=="quit\r" then uart.on("data") else print(input) end end, 0)
uart.on("data", 0 ,function(input) if input=="q" then uart.on("data") else print(input) end end, 0)
uart.on("data","\r",function(input) if input=="quit" then uart.on("data") else print(input) end end, 1)
for k, v in pairs(file.list()) do print('file:'..k..' len:'..v) end
m=mqtt.Client()
m:connect("192.168.18.101",1883)
m:subscribe("/topic",0,function(m) print("sub done") end)
m:on("message",function(m,t,pl) print(t..":") if pl~=nil then print(pl) end end )
m:publish("/topic","hello",0,0)
uart.setup(0,9600,8,0,1,0)
sv=net.createServer(net.TCP, 60)
global_c = nil
sv:listen(9999, function(c)
if global_c~=nil then
global_c:close()
end
global_c=c
c:on("receive",function(sck,pl) uart.write(0,pl) end)
end)
uart.on("data",4, function(data)
if global_c~=nil then
global_c:send(data)
end
end, 0)
file.open("hello.lua","w+")
file.writeline([[print("hello nodemcu")]])
file.writeline([[print(node.heap())]])
file.close()
node.compile("hello.lua")
dofile("hello.lua")
dofile("hello.lc")
-- use copper addon for firefox
cs=coap.Server()
cs:listen(5683)
myvar=1
cs:var("myvar") -- get coap://192.168.18.103:5683/v1/v/myvar will return the value of myvar: 1
-- function should tack one string, return one string.
function myfun(payload)
print("myfun called")
respond = "hello"
return respond
end
cs:func("myfun") -- post coap://192.168.18.103:5683/v1/f/myfun will call myfun
cc = coap.Client()
cc:get(coap.CON, "coap://192.168.18.100:5683/.well-known/core")
cc:post(coap.NON, "coap://192.168.18.100:5683/", "Hello")
file.open("test1.txt", "a+") for i = 1, 100*1000 do file.write("x") end file.close() print("Done.")
for n,s in pairs(file.list()) do print(n.." size: "..s) end
file.remove("test1.txt")
for n,s in pairs(file.list()) do print(n.." size: "..s) end
file.open("test2.txt", "a+") for i = 1, 1*1000 do file.write("x") end file.close() print("Done.")
function TestDNSLeak()
c=net.createConnection(net.TCP, 0)
c:connect(80, "bad-name.tlddfdf")
tmr.alarm(1, 3000, 0, function() print("hack socket close, MEM: "..node.heap()) c:close() end) -- socket timeout hack
print("MEM: "..node.heap())
end
v="abc%0D%0Adef"
print(string.gsub(v, "%%(%x%x)", function(x) return string.char(tonumber(x, 16)) end))
function ex(x) string.find("abc%0Ddef","bc") return 's' end
string.gsub("abc%0Ddef", "%%(%x%x)", ex)
function ex(x) string.char(35) return 's' end
string.gsub("abc%0Ddef", "%%(%x%x)", ex) print("hello")
function ex(x) string.lower('Ab') return 's' end
string.gsub("abc%0Ddef", "%%(%x%x)", ex) print("hello")
v="abc%0D%0Adef"
pcall(function() print(string.gsub(v, "%%(%x%x)", function(x) return string.char(tonumber(x, 16)) end)) end)
mosca -v | bunyan
m=mqtt.Client()
m:connect("192.168.18.88",1883)
topic={}
topic["/topic1"]=0
topic["/topic2"]=0
m:subscribe(topic,function(m) print("sub done") end)
m:on("message",function(m,t,pl) print(t..":") if pl~=nil then print(pl) end end )
m:publish("/topic1","hello",0,0)
m:publish("/topic3","hello",0,0) m:publish("/topic4","hello",0,0)
m=mqtt.Client()
m:connect("192.168.18.88",1883)
m:subscribe("/topic1",0,function(m) print("sub done") end)
m:subscribe("/topic2",0,function(m) print("sub done") end)
m:on("message",function(m,t,pl) print(t..":") if pl~=nil then print(pl) end end )
m:publish("/topic1","hello",0,0)
m:publish("/topic3","hello",0,0) m:publish("/topic4","hello",0,0)
m:publish("/topic1","hello1",0,0) m:publish("/topic2","hello2",0,0)
m:publish("/topic1","hello",1,0)
m:subscribe("/topic3",0,function(m) print("sub done") end)
m:publish("/topic3","hello3",2,0)
m=mqtt.Client()
m:connect("192.168.18.88",1883, function(con) print("connected hello") end)
m=mqtt.Client()
m:on("connect",function(m) print("connection") end )
m:connect("192.168.18.88",1883)
m:on("offline",function(m) print("disconnection") end )
m=mqtt.Client()
m:on("connect",function(m) print("connection "..node.heap()) end )
m:on("offline", function(conn)
if conn == nil then print("conn is nil") end
print("Reconnect to broker...")
print(node.heap())
conn:connect("192.168.18.88",1883,0,1)
end)
m:connect("192.168.18.88",1883,0,1)
m=mqtt.Client()
m:on("connect",function(m) print("connection "..node.heap()) end )
m:on("offline", function(conn)
if conn == nil then print("conn is nil") end
print("Reconnect to broker...")
print(node.heap())
conn:connect("192.168.18.88",1883)
end)
m:connect("192.168.18.88",1883)
m:close()
m=mqtt.Client()
m:connect("192.168.18.88",1883)
m:on("message",function(m,t,pl) print(t..":") if pl~=nil then print(pl) end end )
m:subscribe("/topic1",0,function(m) print("sub done") end)
m:publish("/topic1","hello3",2,0) m:publish("/topic1","hello2",2,0)
m:publish("/topic1","hello3",0,0) m:publish("/topic1","hello2",2,0)
m:subscribe("/topic2",2,function(m) print("sub done") end)
m:publish("/topic2","hello3",0,0) m:publish("/topic2","hello2",2,0)
m=mqtt.Client()
m:on("connect",function(m)
print("connection "..node.heap())
m:subscribe("/topic1",0,function(m) print("sub done") end)
m:publish("/topic1","hello3",0,0) m:publish("/topic1","hello2",2,0)
end )
m:on("offline", function(conn)
print("disconnect to broker...")
print(node.heap())
end)
m:connect("192.168.18.88",1883,0,1)
-- serout( pin, firstLevel, delay_table, [repeatNum] )
gpio.mode(1,gpio.OUTPUT,gpio.PULLUP)
gpio.serout(1,1,{30,30,60,60,30,30}) -- serial one byte, b10110010
gpio.serout(1,1,{30,70},8) -- serial 30% pwm 10k, lasts 8 cycles
gpio.serout(1,1,{3,7},8) -- serial 30% pwm 100k, lasts 8 cycles
gpio.serout(1,1,{0,0},8) -- serial 50% pwm as fast as possible, lasts 8 cycles
gpio.mode(1,gpio.OUTPUT,gpio.PULLUP)
gpio.serout(1,0,{20,10,10,20,10,10,10,100}) -- sim uart one byte 0x5A at about 100kbps
gpio.serout(1,1,{8,18},8) -- serial 30% pwm 38k, lasts 8 cycles
-- Lua: mqtt.Client(clientid, keepalive, user, pass)
-- test with cloudmqtt.com
m_dis={}
function dispatch(m,t,pl)
if pl~=nil and m_dis[t] then
m_dis[t](pl)
end
end
function topic1func(pl)
print("get1: "..pl)
end
function topic2func(pl)
print("get2: "..pl)
end
m_dis["/topic1"]=topic1func
m_dis["/topic2"]=topic2func
m=mqtt.Client("nodemcu1",60,"test","test123")
m:on("connect",function(m)
print("connection "..node.heap())
m:subscribe("/topic1",0,function(m) print("sub done") end)
m:subscribe("/topic2",0,function(m) print("sub done") end)
m:publish("/topic1","hello",0,0) m:publish("/topic2","world",0,0)
end )
m:on("offline", function(conn)
print("disconnect to broker...")
print(node.heap())
end)
m:on("message",dispatch )
m:connect("m11.cloudmqtt.com",11214,0,1)
-- Lua: mqtt:connect( host, port, secure, auto_reconnect, function(client) )
tmr.alarm(0,10000,1,function() local pl = "time: "..tmr.time()
m:publish("/topic1",pl,0,0)
end)

View File

@ -1,18 +0,0 @@
--init.lua, something like this
countdown = 3
tmr.alarm(0,1000,1,function()
print(countdown)
countdown = countdown-1
if countdown<1 then
tmr.stop(0)
countdown = nil
local s,err
if file.open("user.lc") then
file.close()
s,err = pcall(function() dofile("user.lc") end)
else
s,err = pcall(function() dofile("user.lua") end)
end
if not s then print(err) end
end
end)

View File

@ -1 +0,0 @@
print("hello NodeMCU")