NODEMCU调试心得2 - 关于LUA

时间:2021-05-21 13:43:07

关于LUA

和智能云平台相似,nodemcu就是esp12的核心板加一个USB转串口模块,芯片貌似比普通的USB转TTL模块上的靠谱,电路板上用了比较贵的钽电容,稳定性估计不错。

虽然号称是LUA专用平台,但是你刷好固件,用其它的SDK开发一点问题都没有。但是,LUA确实有它的优势。下面就简单介绍一下。

什么是LUA

  • LUA是一群巴西人在93年设计出来的。lua在葡萄牙语中是月亮的意思,发音就很像LUNA,我理解应该是替月行道的意思。
  • Lua是很轻量的脚本语言,只有1M。
  • 用C语言编写,和C++,C可以相互调用。
  • 没有自己的库函数,因为都用别人现成的。
  • 稳定性,速度,功能都不错。很多大型程序用来做嵌入式脚本,比如魔兽世界,伯德之门,和。。。三国杀
  • 当然最重要的是免费

如果想了解lua的更多,可以

本人并不打算介绍具体语法,因为我也不懂,我们先编程再说。

Step1

  • 首先,我们从停止运行的中文官网上搞一段代码,就是左上角的那段,先把路由器给连上。

    print(wifi.sta.getip())
    --nil
    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("Connecting...")
    else
    tmr.stop(1)
    print("Connected, IP is "..wifi.sta.getip())
    end
    end)
  • SSIDpassword要填自己路由器的名称和密码。下面逐段解释:

  • wifi.sta.getip()是在station模式下获取IP地址。
  • --是注释符号,nil是零的意思,在没有连接路由时,返回的IP地址是空的。
  • wifi.setmode(wifi.STATION)很好理解,一共有三种模式,这里设置成station模式,可以连接路由器,其他两种是APAP+station
  • wifi.sta.config("SSID","password"),就是设置路由器的密码和账号。
  • 然后连接wifi.sta.connect()
  • tmr.alarm()是一个定时器函数,一共有四个变量,分别是:
    • ID,选择片上定时器的ID,一共有7个0~6,这里选择了1
    • interval 定时时间(ms),这里选择了1000,就是1s
    • repeat 重复闹钟次数,这里选择1,在一次循环中只执行一次。
    • function do 到事件后执行的函数,就是后面的if...else...语句
  • if...then如果获得的IP还是空的,说明还在连接中
  • else 如果返回值不为空,说明连上了
  • tmr.stop(1),停止定时器1,
  • 然后print()打印IP地址wifi.sta.getip(),..是字符串的连接符,把两个字符串连成一体。
  • 结束if语句
  • 结束function

Step2

  • 打开ESPlor,在右侧窗口,点刷新(在open和速率选择之间),选9600,open
  • 右侧串口窗口会显示一堆无法接受正确信息之类,不用搭理。
    Can’t autodetect firmware, because proper answer not received (may be unknown firmware).
    Please, reset module or continue.
  • step1中的代码,复制到右侧窗口,然后save,保存一个文件名connect.lua
  • 代码编译自动上传,右侧串口窗口显示如下信息,表示连接上了。

    dofile(“connect.lua”);
    nil
    Connecting…
    Connecting…
    Connecting…
    Connecting…
    Connected, IP is 192.168.1.3

  • 注意不要忘记把ssid和passward改成自己路由器的。

wifi连上了,我们可以在电脑和nodemcu之间互发消息,

Step3

  • 首先整理一下思路,用过AT指令的朋友们知道,在station模式下,建立TCP连接的步骤是:

    Server模式,AT+CIPMUX=1开启多链接模式;AT+CIPSERVER=1,8080创建服务器;打开USR-TCP232-Test.exe设置为客户端并连接;AT+CIPSTO=2880设置服务器超时时间;AT+CIPSTATUS查看当前连接确保连接上。AT+CIPSEND=0,10向客户端发送数据,长度为10

  • Lua和AT指令都是在esp8266的原生API的基础上进行封装,所以步骤大同小异,打开官方lua固件里的nodemcu-firmware-master\lua_examples\tcp2uart.lua,把超时和端口改成2880和8080

    uart.setup(0,9600,8,0,1,0)
    sv=net.createServer(net.TCP, 2880)
    global_c = nil
    sv:listen(8080, 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)
  • tcp2uart.lua也是一个server服务器,通过uart输入数据发送客户端,和AT指令是很相似的,逐段解释程序:

    uart.setup()设置串口端口,变量的含义分别是:只支持一个串口(0),波特率(9600),奇偶校验(无),停止位(1),回显(0,关闭)

    net.createServer()建立服务器,类型可以选择net.TCPnet.UDP,超时设置为60ms

    global_c = nil是一个net.socket类型变量,赋值为空nil,用来监听客户端

    sv:listen()listennet.server子模块下的监听函数,(AT指令自动执行监听,不用设置),9999是端口号,function()是连接成功后的回调函数,c是回调参数,代表客户端口

    • if...end 如果全局变量gloabal_c不为空,则关闭close端口gloabal_c

    • global_c=c把回调参数c赋值给全局变量gloabal_c

    • on(event,function())net.socket子模块下的函数,返回值是nil(也是c的),如果envet事件发生,执行回调函数function()

    • 这里eventrecieve,接收信息,function的第一个变量sck是socket的意思,就是服务器连接的客户端,p1是从客户端接收到字符串。

    • uart.write()function()的内容,0只支持一个串口,把接收到的p1字符串写入串口
    • end结束function(sck,p1)

    • end结束listen()中的function(c)

    uart.on()设置UART事件的回调函数,第一个变量method只支持data,表示收到数据,4设置传输字符的长度,当收到第4个字符串,就回调函数。

    • function()就是回调函数,if...then...是函数内容
    • 如果gloabal_c不为空,就向客户端发送send数据data,也就是uart接收到的长度为4的字符串。
    • 两个end分别结束iffunction(data)

    几点说明

    代码的功能分四块,

    • 第一块net.createServer()设置服务器
    • 第二块listen()实现监听,如果已连接上,监听成功,用if...thengloabal_c清零,然后把USR-TCP232-Test客户端nec.socket类型的c赋给gloabal_c
    • 第三块on()实现从USR-TCP232-Test客户端接收数据,建立在监听成功的基础上
    • 第四块uart.on()实现向USR-TCP232-Test客户端发送数据,只有监听成功,gloabal_c被赋值后,才能向USR-TCP232-Test客户端发送数据

    关于net.socket子模块

    • gloabal_cc都是nec.socket类性子模块,代表USR-TCP232-Test客户端的连接,
    • nec.sockt(step2中保存的connect.lua文件)块包含on,clos,保存并运行e,send等方法,gloabal_cc`都有调用
    • sv是由net.createServer()创建的net.server服务器连接模块,包含listen,close,send等方法,使用上与 nec.socket模块类似。
    • nec.socket类型可以通过net.createConnection()创建,如果用nodemcu作为客户端,使用该命令。

step4

  • ESPlore左侧窗口中,将step3中的代码复制到step1中的代码之下(step2中保存的connect.lua文件),保存并上传运行
  • 右侧串口窗口显示连接成功,给出nodemcu的IP地址
  • 打开USR-TCP232-Test.exe,右侧窗口选择client,服务器地址输入nodemcu的IP地址,端口输入8080,点击连接
  • 通过ESPlore的串口界面可以和USR-TCP232-Test互发信息,USR-TCP232-Test接收到的貌似是ASCII码

写到这里,这一部分快结束了,如果你想尝试用nodemcu作为TCP client,可以参考:

  • ESP8266新手入门调试指导(补全)
  • nodemcu 的API说明,中文API说明英文API说明 以及官方lua固件文件夹下的\nodemcu-firmware-master\docs\en,打开这些.md文件你可能需要github出品的atom,非常好用的编辑器。中文说明有些错误,以.md文件为准
  • 官方lua固件文件夹里还有nodemcu的各个模块的示例nodemcu-firmware-master\lua_modulesnodemcu-firmware-master\lua_examples

关于LUA语言

  • 从lua的文风看,已经比较接近自然语言的感觉,这一点和python有点像,但是后者有成堆的库文件。语法结构比较简洁。
  • LUA是异步事件驱动,语言风格和现在很火的Node.js非常接近。比如本文代码中的PIlisten(),on()等API,回调函数嵌入到API中,一旦’event’事件发生就给予执行。对于有大量并发型事件的网络应用,执行效率应会提高不少。

下一篇准备写写各种网络协议:http,udp,telnet等。