--file.open("init.lua","w")
--file.write(print("Wifi connect timed out."))
--file.close()
print("WIFI control")
-- put module in AP mode
wifi.setmode(wifi.SOFTAP)
print("ESP8266 mode is: " .. wifi.getmode())
cfg={}
-- Set the SSID of the module in AP mode and access password
cfg.ssid="ESP_STATION"
cfg.pwd="password"
if ssid and password then
print("ESP8266 SSID is: " .. cfg.ssid .. " and PASSWORD is: " .. cfg.password)
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 or 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)
wifi.setmode(wifi.STATION);
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)
wifi.sta.connect()
file.open("init.lua","w")
file.write('dofile("wifi.lua")')
file.close()
node.restart()
for i = 1, 10 do -- count up
print(i..' banana')
print(wifi.sta.getip())
tmr.delay(1000000)
end
print("before timer")
--print("before timer" .. wifi_ip )
print("Setting up ESP8266 for station mode…Please wait.")
print(wifi.sta.getip())
--print("before timer" ..wifi.ap.getip() )
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
print("Made it here" ..wifi.sta.getip() )
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("<!DOCTYPE html> ")
c:send('<html lang="en">')
c:send("<body> ")
c:send("<h1>ESP8266 Wireless control setup</h1> ")
mac_mess1 = "The module MAC address is: " .. ap_mac
c:send("<h2>" .. mac_mess1 .. "</h2> ")
--c:send("<h2>" .. mac_mess2 .. "</h2> ")
c:send("<h2>Enter SSID and Password for your WIFI router</h2> ")
c:send("</form> </body> </html>")
c:send('<form action=" method="get">')
c:send("SSID:")
c:send('<input type="text" name="SSID" />')
c:send("<br />")
c:send("Password:")
c:send('<input type="text" name="Password" />')
c:send('<input type="submit" value="Submit" />')
end)
end)
-- file.close()
As I have tried to explain on other topics, (open-source) nodeMCU Lua is layered over the (closed source) ESP8266 firmware, but the ESP8266 SDK / API is intrinsically event driven, which means that you organise your applications code as a set of event-driven action routines very much the same way as you'd write jQuery code for a browser.
Lua on the ESP8266 works in exactly the same way. My suggestion is to keep your action routines short as practical and sequence the overall execution through some global variables to hold the context. There aren't any mutex issues because each Lua action function runs to completion before another action can fire.
So using a node.delay() to pulse an I/O pin high for 10μS is fine, but trying to use it delay for a second is just crazy as this will just block whatever you are waiting for from happening.
So I could start rewriting your code, but its better if you do this restructuring:
- To keep things readable, I suggest that you split out any action routes to the module top level (because that's where they run on the call stack anyway.
- Avoid using inheritance (upvalues) in your action routines because how these work in practice is counter intuitive and you could get burnt. Move this stuff into global context.
- Use local variables for everything else, as this generates tighter and more efficient code anyway.
- If you need to sequence stuff at a higher level then hang this all off a timer alarm loop. This lets other asynchronous system functions (e.g. wifi negotiation) in to do its stuff.
- The ESP8266 SDK doesn't seem to use Nagle's algorithm for TCP packet marshalling so it makes send to do this in your code; this generates less code and works more reliably anyway. For example:Code: Select allAnd BTW, writing this way made it clear enough to spot an error in your HTML as well.
c:send([[<!DOCTYPE html>
<html lang="en"><body>
<h1>ESP8266 Wireless control setup</h1>
<h2>The module MAC address is: ]] .. ap_mac .. [[</h2>
<h2>Enter SSID and Password for your WIFI router</h2>
<form action=" method="get">
SSID: <input type="text" name="SSID" /> <br />
Password: <input type="text" name="Password" />
<input type="submit" value="Submit" />
</form> </body> </html>
]]) - just because you've called send doesn't mean that the record has been sent; it means that the send has been scheduled. It hasn't been send until the corresponding on("send" fires.
This was something i copied and made some changes...
file.open("init.lua","w")
file.write('dofile("wifi.lua")')
file.close()
node.restart()
for i = 1, 10 do -- count up
print(i..' banana')
print(wifi.sta.getip())
tmr.delay(1000000)
endI can see watching the serial monitor it starts counting "banana" and it created a init file with dofile, but just not understanding why it skipped the restart code.
I'm running NodeMCU 0.9.6 build 20150406, Lua 5.1.4
--file.open("init.lua","w")
--file.write(print("Wifi connect timed out."))
--file.close()
function setup_AP()
print("WIFI control")
-- put module in AP mode
wifi.setmode(wifi.SOFTAP)
print("ESP8266 mode is: " .. wifi.getmode())
-- Set the SSID of the module in AP mode and access password
cfg = {sid="ESP_STATION", pwd="password"}
if ssid and password then
print("ESP8266 SSID is: " .. cfg.ssid .. " and PASSWORD is: " .. cfg.password)
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 or mobile device. So, find the SSID and connect using the password selected
wifi.ap.config(cfg)
do_next = connect_to_80
end
function connect_to_80()
ap_mac = wifi.ap.getmac()
if not ap_mac then return
-- 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", Receive_80)
do_next = sent_form
end)
end
function sent_form()
-- this is the web page that requests the SSID and password from the user
c:send([[<!DOCTYPE html>
<html lang="en"><body>
<h1>ESP8266 Wireless control setup</h1>
<h2>The module MAC address is: ]] .. ap_mac .. [[</h2>
<h2>Enter SSID and Password for your WIFI router</h2>
<form action=" method="get">
SSID: <input type="text" name="SSID" /> <br />
Password: <input type="text" name="Password" />
<input type="submit" value="Submit" />
</form> </body> </html>
]])
end
function Receive_80(c, pl)
-- print the payload pl received from the connection
print(#pl, pl)
if not pl:match( "GET ") return end
local _, ssid_end = pl:find("SSID=", 1, true)
local _, amper1_end = pl:find("&Password=", 1, true)
local _, http_end = pl:find("HTTP/1.1", 1, true
if ssid_end and amper1_end and http_end and
ssid_end < amper1_end < http_end then
_G.ssid = pl:sub(ssid_end+1, amper1_start-1)
_G.password = pl:sub(amper1_end+1, http_start-2)
print("ESP8266 connecting to SSID: " .. ssid .. " with PASSWORD: " .. password)
if ssid and password then
sv:close()
do_next = setup_station
end
end
end
function setup_station()
-- close the server and set the module to STATION mode
--wifi.setmode(wifi.STATIONAP)
wifi.setmode(wifi.STATION);
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)
wifi.sta.connect()
file.open("init.lua","w")
file.write('dofile("wifi.lua")')
file.close()
do_next = check_setup
end
function check_setup()
local ip = wifi.sta.getip()
if not ip then return end
print("before timer")
--print("before timer" .. wifi_ip )
print("Setting up ESP8266 for station mode…Please wait.")
print(wifi.sta.getip())
--print("before timer" ..wifi.ap.getip() )
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
print("Made it here" ..wifi.sta.getip() )
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", Receiver9999)
end)
tmr.stop(0); tmr.alarm( 0, 1000, 0, print); tmr.stop(0)
end
function Receive9999(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)
-- ????? The output is HTML. What is debug doing here ??????
c:send("Sequence finished")
-- ?????????????????????????????????????????????????????????
end
end
end
print("ESP8266 STATION IP now is: " .. new_ip)
-- ????? The output is HTML. What is debug doing here ??????
c:send("ESP8266 STATION IP now is: " .. new_ip .. "Action completed")
-- ?????????????????????????????????????????????????????????
end
do_next = setup_AP
tmr.alarm( 0, 1000, 1, function() do_next() end)
Hope this gets you in the right directiom. Terry