5、nodeMCU学习笔记--uart(附透传例子)

闲言碎语

这回来了解一下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
  1. .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)
5、nodeMCU学习笔记--uart(附透传例子)_第1张图片
透传

这里加多个定时器来打印回调次数计数值,可以看到并不是每个字符都产生回调。所以,不必太担心频繁回调产生的性能问题。如果,我们把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

你可能感兴趣的:(5、nodeMCU学习笔记--uart(附透传例子))