闲言碎语
这回来了解一下nodeMCU的串口模块。串口应该是我们用的最多的一个模块了,lua脚本都是通过串口传到mcu上面的。这部分的内容很少,只有4个函数。文档中提到了默认的波特率是115200,且在上电的前2分钟内启动了自动波特率功能。
模块函数
仅有4个函数,都很简单。
序号 | 函数名 | 参数 | 返回值 |
---|---|---|---|
1 | uart.alt() | on | nil |
2 | uart.on() | method, [number/end_char], [function], [run_input] | nil |
3 | uart.setup() | id, baud, databits, parity, stopbits, echo | number |
4 | uart.write() | id, data1 [, data2, ...] | nil |
- .alt可以重映射串口pin。传入1将pin映射到13、15。
- .on用来设置串口接收回调函数。第一个参数现在只能传入"data"。参数2可以传入数字或者仅有单个字符的字符串,例如传入6就收到6个字符串就产生回调,不能大于255;传入"s"就接收到s的时候就产生回调或者收完255个字符。参数3是回调函数,取消回调就只传入"data"参数。参数4,是否执行lua解析,如果传入0将不解析执行。
- .setup配置串口。id只能传入0。后面的分别是波特率(300, 600, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 74880, 115200, 230400, 256000, 460800, 921600, 1843200, 3686400)、数据位(5, 6, 7, 8)、校验(uart.PARITY_NONE, uart.PARITY_ODD, uart.PARITY_EVEN)、停止位(uart.STOPBITS_1, uart.STOPBITS_1_5, uart.STOPBITS_2)。echo表示回显,0不回显。
- .write是写函数。id只能传入0。
综合小例子
串口模块比较简单,直接来看看例子。把波特率设置38400 8-N-1 不带回显。回调不执行lua代码解析。这里使用1号pin来设别是否切换串口设置。
gpio.mode(1, gpio.INPUT, gpio.PULLUP)
gpio.mode(0, gpio.OUTPUT)
tmr.alarm(0, 10000, tmr.ALARM_SINGLE, function()
gpio.write(0, gpio.LOW)
if(gpio.read(1) == 0) then
print("38400 8-n-1")
uart.setup(0, 38400, 8, uart.PARITY_NONE, uart.STOPBITS_1, 0)
uart.on("data", 8, function(data)
uart.write(0, "rec: ", data)
end, 0)
else
print("115200 8-n-1")
uart.setup(0, 115200, 8, uart.PARITY_NONE, uart.STOPBITS_1, 1)
uart.on("data")
end
end)
这个例子有个问题,得满8个字符才会产生回调。其实,可以不用设置数量或者采用ascii格式传输,然后用"\n"来触发回调。下面是一个不设置数量的例子,直接透传数据。
gpio.mode(1, gpio.INPUT, gpio.PULLUP)
cnt = 0
tmr.alarm(0, 10000, tmr.ALARM_SINGLE, function()
if(gpio.read(1) == 0) then
uart.setup(0, 38400, 8, uart.PARITY_NONE, uart.STOPBITS_1, 0)
print("38400 8-n-1")
uart.on("data", function(data)
cnt = cnt + 1
tmr.stop(1)
tmr.interval(1, 1)
tmr.start(1)
uart.write(0, data)
end, 0)
else
uart.setup(0, 115200, 8, uart.PARITY_NONE, uart.STOPBITS_1, 1)
print("115200 8-n-1")
uart.on("data")
end
end)
tmr.register(1, 1, tmr.ALARM_SEMI, function()
print("\n")
print(cnt)
print("\n")
end)
这里加多个定时器来打印回调次数计数值,可以看到并不是每个字符都产生回调。所以,不必太担心频繁回调产生的性能问题。如果,我们把WiFi也加进来,那就可以变成WiFi转串口的透传模块了。如果想知道串口接收到多少字节,可以使用#data或者用string.len(data)
uart.on("data", function(data) print(#data) end, 0)
uart.on("data", function(data) print(string.len(data)) end, 0)
一点问题
以下这段代码和上面的例子基本没什么区别,不过会让nodeMCU重启。如果你把它保存为init.lua,然后传送到MCU。那么,你会看到MCU反复重启。所以,建议在init.lua中加个延时。
我也没搞懂这个代码会让机器重启,bug在哪儿呢?
gpio.mode(1, gpio.INPUT, gpio.PULLUP)
gpio.mode(0, gpio.OUTPUT)
function echoUart(data)
uart.write(0, "rec: ", data)
end
tmr.alarm(0, 10000, tmr.ALARM_SINGLE, function()
gpio.write(0, gpio.LOW)
if(gpio.read(1) == 0) then
print("38400 8-n-1")
uart.setup(0, 38400, 8, uart.PARITY_NONE, uart.STOPBITS_1, 0)
uart.on("data", 8, echoUart(data), 0)
else
print("115200 8-n-1")
uart.setup(0, 115200, 8, uart.PARITY_NONE, uart.STOPBITS_1, 1)
uart.on("data")
end
end)
评论不能贴图, 如有需要可以到我的GitHub上提issues