【ESP8266之LUA开发】二、GPIO映射以及串口的空闲中断初探

本文介绍ESP8266模块的GPIO与串口应用实践,包括通过GPIO控制LED及继电器,利用串口实现数据收发与控制。深入探讨串口通信中的数据处理技巧及常见问题解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、关于GPIO

从实战中开始吧,就让我们利用GPIO2点亮8266的一个板载小灯吧。

gpio.mode(4, gpio.OUTPUT)
gpio.write(4, 0)

原理图上是GPIO2,为什么对应程序要写4呢?

LUA固件里面是这样封装的!

IO - IndexEPS8266 pin对应关系一览表
这里写图片描述

2、关于串口

ESP8266有两个串口,UART0UART1

由ESP8266 - 12E 规格书<这里, yc6y>可以知道,
这里写图片描述

UART0-TXDGPIO1
UART1-RXDGPIO3
UART1只有TXD引脚,在GPIO2

print输出默认用UART0
uart.write输出则可以使用串口0也可以串口1,输出前指明即可!

实例:当8266收到数据,就让数据回显!

tmr.alarm(1, 2000, 1, function()
            uart.on("data", 0, function(Rec)
                                uart.write(0, Rec)
                               end, 0)
end)

实例:

注意,发送命令的时候不要勾选发送新行

1、H控制继电器开,L控制继电器关

继电器在GPIO4,对应IO-Index2

gpio.mode(2, gpio.OUTPUT) --设置GPIO模式

tmr.alarm(1, 2000, 0, function() --2s后启动
            
            uart.on("data", 0, function(Rec)

                    if Rec == 'H' then 
                        gpio.write(2, 1)
                        print("High")
                    end

                    if Rec == 'L' then
                        gpio.write(2, 0)
                        print("LOW")
                    end

                    uart.write(0, Rec) --回显接收的数据

                    end, 0)
                                
end)

上面的作为一个实例来控制继电器吸合,当然是没有问题的,接下来我们稍微改动下,把命令从H改为++H

2、++H控制继电器

gpio.mode(2, gpio.OUTPUT)

tmr.alarm(1, 2000, 0, function()
            
            uart.on("data", 0, function(Rec)

                    if Rec == '++H' then 
                        gpio.write(2, 1)
                        print("High")
                    end

                    if Rec == '++L' then
                        gpio.write(2, 0)
                        print("LOW")
                    end

                    uart.write(0, Rec)

                    end, 0)
                                
end)

理论上可行,但是当我实际真的发送++H的时候却不行
你这个时候可以再试一下+++H的命令,却发现可行

问题分析

问题出在哪了呢?

这一句uart.on("data", 0, ...will receive every char in buffer当接收到一接收到字符不管多少个,就直接触发回调函数,造成的结果呢,发送一个完整的++H指令,却被拆分为++H两个。
这个结论从串口助手打印的回显数据也不能看出。

看串口数据之前,先来了解下printuart.write打印的区别!

  • print默认UART0,不能更换!而uart.write可以使用UART0或者UART1
  • print打印数据后会自动加回车换行!而uart.write不会!

OK,带着上面这两条(主要是第二条)来分析下串口助手打印的信息!

发送++H
串口助手显示

++H

很容易分析出,就是uart.write把我们输入的命令原封不动的回显过来的!

大概过程+触发uart.on回调函数,都不满足然后用uart.write(不会自己加回车换行)回显+,然后接着的+H也都不满足,就直接回显了+H
都是用uart.write打印的,它们之间自然没有换行了!

也许你有一个问题,为什么第一次只有+一个字符触发,而第二次可以+H两个字符。你可以这样想,uart.on 是一接收到字符就触发,但是第一次触发肯定是一个字符就可以,然后触发要执行回调函数,这段时间完全够剩余数据写入缓冲区,然后再读缓冲区的时候,肯定是截断后的全部数据!

发送+++H
串口助手显示

+High
++H

注意,别自动忽略两条消息不在一行的信息!显然有print的功劳!

大概过程:+触发uart.on回调函数,都不满足然后用uart.write(不会自己加回车换行)回显出来+。随后截断剩余数据++H符合条件,然后执行条件判断print打印High(High后加了回车换行!),然后原封不动的数据回显,显然此时的数据是++H

问题解决

分析好了问题,自然解决问题相对有点思路了,比如我们这个++H的指令问题。

No.1

既然uart.on("data", 0, ... 0不行,那换成3不就OK了嘛!接收到三个数据再触发回调!

确实可以,但是程序每次都得事先指定好指令长度,局限性很大!那么有没有一种办法,还是uart.on("data", 0, ... ,然后随意规定指令都可以呢?
of Course

当当当,空闲中断隆重登场!

No.2

ReadCnt = 0
ReadCntCopy = 0
ReadData = nil
ReadDataCopy = nil

gpio.mode(2, gpio.OUTPUT)

tmr.alarm(1, 2000, 0, function() -- 初始化后2s串口进行监听数据
            uart.on("data", 0, function(Rec)
                ReadData = ReadData..Rec --把接收到的数据连接在一起
                ReadCnt = ReadCnt + 1 --记录进入回调函数的次数
            end, 0)                              
end)   

tmr.alarm(2, 5, 1, function()
        if ReadCnt ~= 0 then
            if ReadCnt == ReadCntCopy then
                ReadCnt = 0
                ReadCntCopy = 0
                ReadDataCopy = ReadData
                ReadData = ""

                if ReadDataCopy == "++H" then
                    gpio.write(2, 1)
                end

                if ReadDataCopy == "+L" then
                    gpio.write(2, 0)
                end
                
            else
                ReadCntCopy = ReadCnt//只要一赋值就变成了全局变量
            end
        end
        
end)
             

全局变量并未声明,而是直接使用,这个算是LUA的一个特点吧,但是为了程序的可读性,我们还是进行声明的好!

定时器1还是用来接收数据,但是并不直接处理数据,而是把接收到的数据连接在一起,并记录进入回调函数的次数。

定时器2每隔2S,判断ReadCntReadCntCopy是否相等,一旦相等,就可说明此时一帧数据已经接收完毕,可以进行处理!

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ReCclay

如果觉得不错,不妨请我喝杯咖啡

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值