nodeMCU Lua ESP8266第三课 内网控制LED

写在前面的话:个人学习笔记,抛砖引玉,希望有兴趣的人加入QQ群415469069一起讨论,欢迎有共同爱好的人。 

本教程以ESP-12N,CP2102开发板为例进行讲解。

  • 代码。

--wifi_light.lua

wifi.setmode(wifi.STATION)  

wifi.sta.config("YOUR_NETWORK_NAME","YOUR_NETWORK_PASSWORD")  

print(wifi.sta.getip())  

led1 = 0   

gpio.mode(led1, 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");  

        end  

        local _GET = {}  

        if (vars ~= nil)then  

            for k, v in string.gmatch(vars, "(%w+)=(%w+)&*") do  

                _GET[k] = v  

            end  

        end  

        buf = buf.."

ESP8266 Web Server

";  

        buf = buf.."

GPIO16

";  

        if(_GET.pin == "ON1")then  

              gpio.write(led1, gpio.LOW);  

        elseif(_GET.pin == "OFF1")then  

              gpio.write(led1, gpio.HIGH);  

        end  

        client:send(buf);  

        client:close();  

        collectgarbage();  

    end)  

end)  

 

二、说明:

  1. ,wifi模式为station,输入wifi名和密码进行配置。

句法:wifi.setmode(mode[, save])

作用:配置WiFi模式使用

参数:

mode 价值应该是其中之一

wifi.STATION:当设备连接到WiFi路由器时。这通常是为了让设备访问互联网。

wifi.SOFTAP: 因为当设备只作为一个接入点。这将允许您在WiFi网络列表中查看设备(当然,除非您隐藏SSID)。在这种模式下,您的计算机可以连接到设备,创建一个局域网。除非您更改该值,否则NodeMCU设备将被分配一个本地IP地址192.168.4.1,并为您的计算机分配下一个可用的IP地址,例如192.168.4.2。

wifi.STATIONAP:是的组合wifi.STATION和wifi.SOFTAP。它允许您创建本地WiFi连接并连接到另一个WiFi路由器。

wifi.NULLMODE:将WiFi模式更改为NULL_MODE将使wifi进入与MODEM_SLEEP类似的低功耗状态,但未提供wifi.nullmodesleep(false)。

save 选择是否将wifi模式保存到闪存

true:WiFi模式配置将在电源周期中保留。(默认)

false:WiFi模式配置将不会通过重新启动进行保留。

  1. led = 0,对应的是GPIO16,开发板上这个引脚外焊了个led,可以利用。
  2. 创建服务器,监听80端口。

句法:net.createServer([type[, timeout]])

作用:创建一个服务器。

参数:

type:   net.TCP (默认)或 net.UDP

Timeout: 对于TCP服务器,超时时间为1〜28'800秒,默认30秒(非活动客户端断开连接)

返回:

net.TCP 时返回: net.server子模块

net.UDP时返回: net.udpsocket子模块

句法:net.server:listen([port],[ip],function(net.socket))

作用:从IP地址侦听端口。

参数:

port: 端口号,可以省略(随机端口将被选中)

ip: IP地址字符串,可以省略

function(net.socket): 回调函数,如果连接成功创建,则传递给调用者函数

第一个参数:

回调的第一个参数是套接字(即socket)。

第二个参数:

如果事件是“接收”,则第二个参数是以字符串形式接收的数据。

如果事件是“断开”或“重新连接”,则第二个参数是错误代码。

如果指定了重新连接事件,则断开只接收“正常关闭”事件。

否则,所有连接错误(正常关闭)传递到断开连接事件。

句法:net.socket:on(event, function())

作用:注册特定事件的回调函数

参数:

event: 字符串,可以是“连接”,“重新连接”,“断开”,“接收”或“发送”

function(net.socket[, string]):回调函数。可以nil删除回调。

句法:net.socket:send(string[, function(sent)])

参数:

string:        字符串中的数据将被发送到服务器

function(sent): 用于发送字符串的回调函数

句法:net.socket:close()

作用:关闭嵌套字

  1. 处理接收的数据(即字符串request的内容)

关键字local:定义局部变量。

_,    指声明虚变量,说白了就是我不想要前两个返回值,给他个虚变量名,以后不会调用此数据。

string.find (str, substr, [init, [end]])
    在一个指定的目标字符串中搜索指定的内容(第三个参数为索引),返回其具体位置。不存在则返回 nil。

第一个返回值:起始位置。

第二个返回值:终止位置。

string.gmatch(s, pattern)

会返回一个迭代器函数,通过这个函数可以遍历到一个字符串中所有出现指定模式的地方。这个函数可以通过泛型for提取数据。

匹配模式

Lua 中的匹配模式直接用常规的字符串来描述。 它用于模式匹配函数 string.find, string.gmatch, string.gsub, string.match。

你还可以在模式串中使用字符类。

字符类指可以匹配一个特定字符集合内任何字符的模式项。比如,字符类%d匹配任意数字。所以你可以使用模式串 '%d%d/%d%d/%d%d%d%d' 搜索 dd/mm/yyyy 格式的日期:

s = "Deadline is 30/05/1999, firm"

date = "%d%d/%d%d/%d%d%d%d"print(string.sub(s, string.find(s, date)))    --> 30/05/1999

下面的表列出了Lua支持的所有字符类:

单个字符(除 ^$()%.[]*+-? 外): 与该字符自身配对。

当上述的字符类用大写书写时, 表示与非此字符类的任何字符配对. 例如, %S表示与任何非空白字符配对.例如,'%A'非字母的字符。

.

与任意字符配对

%a

与任意字母配对

%c

与任何控制符配对(例如\n)

%d

与任何数字配对

%l

与任何小写字母配对

%p

与任何标点(punctuation)配对

%s

与空白字符配对

%u

与任何大写字母配对

%w

与任何字母/数字配对

%x

与任何十六进制数配对

%z

与任何代表0的字符配对

%x(此处x是非字母非数字字符)

与字符x配对. 主要用来处理表达式中有功能的字符(^$()%.[]*+-?)的配对问题, 例如%%与%配对

[数个字符类]

与任何[]中包含的字符类配对. 例如[%w_]与任何字母/数字, 或下划线符号(_)配对

[^数个字符类]

与任何不包含在[]中的字符类配对. 例如[^%s]与任何非空白字符配对

在模式匹配中有一些特殊字符,他们有特殊的意义,Lua中的特殊字符如下:

( ) . % + - * ? [ ^ $

'%' 用作特殊字符的转义字符,因此 '%.' 匹配点;'%%' 匹配字符 '%'。转义字符 '%'不仅可以用来转义特殊字符,还可以用于所有的非字母的字符。

模式条目可以是

单个字符类

匹配该类别中任意单个字符

单个字符类跟一个 '*'

将匹配零或多个该类的字符。 这个条目总是匹配尽可能长的串

单个字符类跟一个 '+'

将匹配一或更多个该类的字符。 这个条目总是匹配尽可能长的串

单个字符类跟一个 '-'

将匹配零或更多个该类的字符。 和 '*' 不同, 这个条目总是匹配尽可能短的串

单个字符类跟一个 '?'

将匹配零或一个该类的字符。 只要有可能,它会匹配一个

%n

这里的 n 可以从 1 到 9; 这个条目匹配一个等于 n 号捕获物(后面有描述)的子串

%bxy

这里的 x 和 y 是两个明确的字符; 这个条目匹配以 x 开始 y 结束, 且其中 x 和 y 保持 平衡 的字符串。 意思是,如果从左到右读这个字符串,对每次读到一个 x 就 +1 ,读到一个 y 就 -1, 最终结束处的那个 y 是第一个记数到 0 的 y。 举个例子,条目 %b() 可以匹配到括号平衡的表达式

%f[set]

指 边境模式; 这个条目会匹配到一个位于 set 内某个字符之前的一个空串, 且这个位置的前一个字符不属于 set 。 集合 set 的含义如前面所述。 匹配出的那个空串之开始和结束点的计算就看成该处有个字符 '\0' 一样

模式 指一个模式条目的序列。 在模式最前面加上符号 '^' 将锚定从字符串的开始处做匹配。 在模式最后面加上符号 '$' 将使匹配过程锚定到字符串的结尾。 如果 '^' 和 '$' 出现在其它位置,它们均没有特殊含义,只表示自身。

捕获:模式可以在内部用小括号括起一个子模式; 这些子模式被称为 捕获物。 当匹配成功时,由 捕获物 匹配到的字符串中的子串被保存起来用于未来的用途。 捕获物以它们左括号的次序来编号。 例如,对于模式 "(a*(.)%w(%s*))" , 字符串中匹配到 "a*(.)%w(%s*)" 的部分保存在第一个捕获物中 (因此是编号 1 ); 由 "." 匹配到的字符是 2 号捕获物, 匹配到 "%s*" 的那部分是 3 号。

作为一个特例,空的捕获 () 将捕获到当前字符串的位置(它是一个数字)。 例如,如果将模式 "()aa()" 作用到字符串"flaaap" 上,将产生两个捕获物: 3 和 5 。

  1. 数据类型Table(表)

在 Lua 里,table 的创建是通过"构造表达式"来完成,最简单构造表达式是{},用来创建一个空表。也可以在表里添加一些数据,直接初始化表:

-- 直接初始表

local tbl = {"apple", "pear", "orange", "grape"}

--打印看效果

local tbl = {"apple", "pear", "orange", "grape"}

for k, v in pairs(a) do

    print(k .. " : " .. v)

end

打印结果:

1 : apple

2 : pear

3 : orange

4 : grape

--

不同于其他语言的数组把 0 作为数组的初始索引,在 Lua 里表的默认初始索引一般以 1 开始。

Lua 中的表(table)其实是一个"关联数组"(associative arrays),数组的索引可以是数字或者是字符串。

a = {}

a["key"] = "value"

key = 10

a[key] = 22

for k, v in pairs(a) do

    print(k .. " : " .. v)

end

打印结果:

key : value

10 : 22

 

--

泛型 for 迭代器:

泛型 for 在自己内部保存迭代函数,实际上它保存三个值:迭代函数、状态常量、控制变量。

泛型 for 迭代器提供了集合的 key/value 对,语法格式如下:

for k, v in pairs(t) do

print(k, v)

end

上面代码中,k, v为变量列表;pair(t)为表达式列表。

以上实例中我们使用了 Lua 默认提供的迭代函数 ipairs。

下面我们看看泛型 for 的执行过程:

首先,初始化,计算in后面表达式的值,表达式应该返回泛型 for 需要的三个值:迭代函数、状态常量、控制变量;与多值赋值一样,如果表达式返回的结果个数不足三个会自动用nil补足,多出部分会被忽略。

第二,将状态常量和控制变量作为参数调用迭代函数(注意:对于for结构来说,状态常量没有用处,仅仅在初始化时获取他的值并传递给迭代函数)。

第三,将迭代函数返回的值赋给变量列表。

第四,如果返回的第一个值为nil循环结束,否则执行循环体。

第五,回到第二步再次调用迭代函数。

三、Tips。

将代码保存为wifi_light.lua,下载到ESP中,如果想上电就运行这个程序,可以在第一课的init.lua文件中加上红色标注的代码:

--本程序为初始化程序init.lua,ESP8266上电后会默认从此程序开始运行。

--

--

--开发板上蓝色小灯闪烁3下,表明程序已经运行,调试收到信息“success”

gpio.mode(0,gpio.OUTPUT)

for i = 1, 3 ,1 do

    gpio.write(0,gpio.LOW)

    --tmr.delay(s)中s单位为微秒,1000000微秒=1秒

    tmr.delay(500000)

    gpio.write(0,gpio.HIGH)

    tmr.delay(500000)

end

print("success","\n")

--运行子程序

--内网控制LED程序。

dofile("wifi_light.lua")


  • 使用远程控制。

1、ESP上电后配置好wifi连接之后就调用print(wifi.sta.getip()),由于连接上路由器需要一定的时间,因此,在小灯闪过三次,控制台显示success后,print(wifi.sta.getip())会打印出字符串nil,意思是没有获取到ip的信息。这时,就需要我们重新获取了。

等待几秒钟,待ESP成功连接路由器后,在开发软件的右下角,向ESP发送单条命令print(wifi.sta.getip())。得到返回信息,如果是nil,过几秒后再尝试,直到看到需要的信息。

nodeMCU Lua ESP8266第三课 内网控制LED_第1张图片

 

返回的信息“192.168.100.130  255.255.255.0 192.168.100.1”中:

192.168.100.130为ESP的IP地址,255.255.255.0为子网掩码,

192.168.100.1为网关。

2、打开浏览器(手机浏览器、电脑浏览器均可),保证打开浏览器的设备与ESP连接的是同一个路由器。输入ESP的IP地址(即192.168.100.130),我们配置的简单服务器将显示出来。

3、点击按钮ON,开发板上的小灯将亮起。

   点击按钮OFF,开发板上的小灯将熄灭。

 

你可能感兴趣的:(nodeMCU)