NodeMCU 的文档里面终于发现,ESP8266 的GPIO 2 确实是 PIN 4,GPIO 0 是 PIN 3。
https://github.com/nodemcu/nodemcu-firmware/wiki/nodemcu_api_cn
话说,这个 API 不是给地球人看的。按照说明,net.createServer 返回的是 Server,事实上,如果用 UDP,按照里面的代码你死活干不出来的。终于在 www.esp8266.com 论坛里面找到了答案,本篇的内容就是描述 UDP 在 NodeMCU 里面的正确姿势。
接线、BBB 开 UART,和 minicom 相关的,请看上几篇。首先我直接上代码。
LUA 代码
init.lua
print('init.lua ver 0.9')
wifi.setmode(wifi.STATION)
print('set mode=STATION (mode='..wifi.getmode()..')')
print('MAC: ',wifi.sta.getmac())
print('chip: ',node.chipid())
print('heap: ',node.heap())
wifi.sta.config('SSID','PWD')
dofile('main.lua')
init.lua 是启动后执行的用户程序代码,wifi 设成 station 模式(另外可以是 AP 模式的),然后设置 SSID 和密码,如果你想试,代码里面的 wifi.sta.config 需要改为正确值。代码的最后一句是让它执行另一个 lua 代码档。
main.lua
print('Connecting...')
tmr.alarm(0, 1000, 1, function()
if wifi.sta.getip() ~= nil then
print('IP: ',wifi.sta.getip())
tmr.stop(0)
dofile('udp.lua')
end
end)
这个没什么,每秒钟看一遍是否已经连上了无线路由,如果连上了,就执行另一个代码档。(又一个档案?有点多余是吧,这是我个人癖好,我每个单独测试的)
udp.lua
sv=net.createServer(net.UDP,0)
sv:on('receive', function(c,pl)
print(pl)
r=cjson.decode(pl)
if r.cmd == '0' then
print('I got a ZERO cmd.')
c:send('{"cmd":"2","GUID":"24F92","dType":"powerPlug"}')
end
end)
sv:listen(4000)
print('Server started')
关键就是这个 on 方法。你看官方 API,on 是 socket 的方法,不是 server 的。而 net.createServer 按照官方说明,是返回 server 的。就是说,如果按照官方说明,我这代码是错误的。我是看了 http://www.esp8266.com/viewtopic.php?f=24&t=645 这里才知道这“错误”做法…。
上传代码
我代码是用 vim 在 BBB 里面写的,保存在 BBB,然后用 luatool 写入。https://github.com/4refr0nt/luatool。python 而已,git clone 下来就能用,里面还有个 telnet 代码示范。这 luatool 其实是帮我操作 NodeMCU 命令并且转换代码而已。运行时加 –v 参数你就知道它是干嘛的了。
用法是 python luatool.py –p /dev/ttyO2 –b 9600 –f XXX.lua –v
-p 是串口端口,-b 是 baud,-f 是本机的代码档,-v 是显示过程。很明显它只不过调用 NodeMCU 的lua 命令而已,而它最不好的地方是,它会等待 NodeMCU 反应返回字符来判断操作有没有顺利执行。如果你像我一样,有东西在里面跑,有 print 的话,就会出现些错误,因为 print 和这 luatool 的响应混在一起了。
效果
不用 BBB,从 Windows,通过无线路由,直接发 UDP 给 ESP8266,开着 BBB 的 minicom 看看这些 debug (呃,print)信息。我首先发了 cmd: 1 和 2 字符过去,反应正常,也正确 print 了出来。然后 cmd:0,它正确的回传了自己的身份,powerPlug。没错,我准备玩智能插座。
广播一样 no problem(向广播地址 192.168.0.255 端口 4000发送):
今天到此为止。