搜索
bottom↓
回复: 0

《ESP32-S3使用指南—MicroPython版 V1.0》第二十一章 红外遥控器实验

[复制链接]

出0入234汤圆

发表于 3 天前 | 显示全部楼层 |阅读模式
2.jpg
1)实验平台:正点原子ESP32S3开发板
2)购买链接:https://detail.tmall.com/item.htm?id=768499342659
3)全套实验源码+手册+视频下载地址:http://www.openedv.com/thread-347618-1-1.html
4)正点原子官方B站:https://space.bilibili.com/394620890
5)正点原子手把手教你学ESP32S3快速入门视频教程:https://www.bilibili.com/video/BV1sH4y1W7Tc
6)正点原子FPGA交流群:132780729
1.png
3.png

第二十一章 红外遥控器实验


       本章,我们将介绍MicroPython remote库对红外遥控器的信号解码。ESP32-S3板子上标配的红外接收头和一个小巧的红外遥控器。我们将利用管脚输入功能,解码开发板标配的红外遥控器的编码信号,并将编码后的键值在SPILCD模块中显示出来。
       本章分为如下几个小节:
       21.1 红外遥控简介
       21.2 remote类
       21.3 硬件设计
       21.4 程序设计
       21.5 下载验证

       21.1 红外遥控简介

       21.1.1 红外遥控技术介绍
       红外遥控是一种无线、非接触控制技术,具有抗干扰能力强,信息传输可靠,功耗低,成本低,易实现等显著优点,被诸多电子设备特别是家用电器广泛采用,并越来越多的应用到计算机系统中。 由于红外线遥控不具有像无线电遥控那样穿过障碍物去控制被控对象的能力,所以,在设计红外线遥控器时,不必要像无线电遥控器那样,每套(发射器和接收器)要有不同的遥控频率或编码(否则,就会隔墙控制或干扰邻居的家用电器),所以同类产品的红外线遥控器,可以有相同的遥控频率或编码,而不会出现遥控信号“串门”的情况。这对于大批量生产以及在家用电器上普及红外线遥控提供了极大的方便。由于红外线为不可见光,因此对环境影响很小,再由红外光波动波长远小于无线电波的波长,所以红外线遥控不会影响其他家用电器,也不会影响临近的无线电设备。

       21.1.2 红外器件特性
       红外遥控的情景中,必定会有一个红外发射端和红外接收端。在本实验中,正点原子的红外遥控器作为红外发射端,红外接收端就是板载的红外接收器,实物图可以查看21.2.3小节原理图部分。要使两者通信成功,收/发红外波长与载波频率需一致,在这里波长就是940nm,载波频率就是38kHz。
       红外发射管也是属于二极管类,红外发射电路通常使用三极管控制红外发射器的导通或者截至,在导通的时候,红外发射管会发射出红外光,反之,就不会发射出红外光。虽然我们用肉眼看不到红外光,但是我们借助手机摄像头就能看到红外光。但是红外接收管的特性是当接收到红外载波信号时,OUT引脚输出低电平;假如没有接收到红外载波信号时,OUT引脚输出高电平。
       红外载波信号其实就是由一个个红外载波周期组成。在频率为38KHz下,红外载波周期约等于26.3us(1s / 38KHz ≈ 26.3us)。在一个红外载波发射周期里,发射红外光时间8.77us和不发射红外光17.53us,发射红外光的占空比一般为1/3。相对的,整个周期内不发射红外光,就是载波不发射周期。在红外遥控器内已经把载波和不载波信号处理好,我们需要做的就是识别遥控器按键发射出的信号,信号也是遵循某种协议的。

       21.1.3 红外编解码协议介绍
       红外遥控的编码方式目前广泛使用的是:PWM(脉冲宽度调制)的NEC协议和Philips PPM(脉冲位置调制)的RC-5协议的。开发板配套的遥控器使用的是NEC协议,其特征如下:

       1,8 位地址和 8 位指令长度;

       2,地址和命令 2 次传输(确保可靠性);

       3,PWM 脉冲位置调制,以发射红外载波的占空比代表“0”和“1”;

       4,载波频率为 38Khz;

       5,位时间为 1.125ms 或 2.25ms;

       在NEC协议中,如何为协议中的数据‘0’或者‘1’?这里分开红外接收器和红外发射器。
       红外发射器:发送协议数据‘0’ = 发射载波信号560us + 不发射载波信号560us
                           发送协议数据‘1’ = 发射载波信号560us + 不发射载波信号1680us
       红外发射器的位定义如下图所示。

第二十一章 红外遥控器实验1487.png
图21.1.3.1 红外发射器位定义图

       红外接收器:接收到协议数据‘0’ = 560us低电平 + 560us高电平
                           接收到协议数据‘1’ = 560us低电平 + 1680us高电平
       红外接收器的位定义如下图所示。

第二十一章 红外遥控器实验1627.png
图21.1.3.2 红外接收器位定义图

       NEC遥控指令的数据格式为:同步码头、地址码、地址反码、控制码、控制反码。同步码由一个9ms的低电平和一个4.5ms的高电平组成,地址码、地址反码、控制码、控制反码均是8位数据格式。按照低位在前,高位在后的顺序发送。采用反码是为了增加传输的可靠性(可用于校验)。
       我们遥控器的按键▽按下时,从红外接收头端收到的波形如下图所示。

第二十一章 红外遥控器实验1814.png
图21.1.3.3 按键▽所对应的红外波形

       从上图中可以看到,其地址码为0,控制码为21(正确解码后00010101)。可以看到在100ms之后,我们还收到了几个脉冲,这是NEC码规定的连发码(由9ms低电平+2.25ms高电平+0.56ms低电平+97.94ms高电平组成),如果在一帧数据发送完毕之后,按键仍然没有放开,则发射重复码,即连发码可以通过统计连发码的次数来标记按键按下的长短/次数。

       21.2 remote类
       根据上小节的红外编码协议的原理解析,作者在工程中新建remote.py文件,用来接收和解析红外编码数据。红外解码如下。
  1. """
  2. * 定义红外接收类
  3. """
  4. class REMOTE_IR(object):

  5.     # 定义键值及内容
  6.     REMOTE_CODE = {
  7.         0: "ERROR", 162: "POWER", 98: "UP",
  8.         2: "PLAY", 226: "ALIENTEK", 194: "RIGHT",
  9.         34: "LEFT", 224: "VOL-", 168: "DOWN",
  10.         144: "VOL+", 104: "1", 152: "2",
  11.         176: "3", 48: "4", 24: "5",
  12.         122: "6", 16: "7", 56: "8",
  13.         90: "9", 66: "0", 82: "DELETE"
  14.     }

  15.     # 红外接收初始化
  16.     def __init__(self, gpio_num):
  17.         self.irRecv = Pin(gpio_num, Pin.IN, Pin.PULL_UP)
  18.         self.irRecv.irq(trigger = Pin.IRQ_RISING | Pin.IRQ_FALLING,
  19. handler = self.ex_handler)  # 配置中断信息
  20.         # 声明变量
  21.         self.ir_step = 0
  22.         self.ir_count = 0
  23.         self.rx_buf = [0 for i in range(64)]
  24.         self.rx_ok = False
  25.         self.cmd = None
  26.         self.repeat = 0
  27.         self.t_ok = None
  28.         self.start = 0
  29.         self.start_last = 0

  30.     # 红外接收回调函数
  31.     def ex_handler(self, source):
  32.         """
  33.         中断回调函数
  34.         """
  35.         thisComeInTime = time.ticks_us()

  36.         # 更新时间
  37.         curtime = time.ticks_diff(thisComeInTime, self.start)
  38.         self.start = thisComeInTime
  39.         

  40.         if curtime >= 8500 and curtime <= 9500:
  41.             self.ir_step = 1
  42.             return

  43.         if self.ir_step == 1:
  44.             if curtime >= 4000 and curtime <= 5000:
  45.                 self.ir_step = 2
  46.                 self.rx_ok = False
  47.                 self.ir_count = 0
  48.             elif curtime >= 2000 and curtime <= 3000:    # 长按重复接收
  49.                 self.ir_step = 3
  50.                 self.repeat += 1

  51.         elif self.ir_step == 2:                          # 接收4个字节
  52.             self.rx_buf[self.ir_count] = curtime
  53.             self.ir_count += 1
  54.             if self.ir_count >= 64:
  55.                 self.rx_ok = True
  56.                 self.t_ok = self.start                  # 记录最后ok的时间
  57.                 self.ir_step = 0

  58.         elif self.ir_step == 3:                         # 重复
  59.             if curtime >= 500 and curtime <= 650:
  60.                 self.repeat += 1

  61.     # 检测命令
  62.     def check_cmd(self):
  63.         one_byte = 0
  64.         for i in range(32):
  65.             x = i * 2
  66.             t = self.rx_buf[x] + self.rx_buf[x + 1]
  67.             one_byte <<= 1
  68.             if t >= 1800 and t <= 2800:
  69.                 one_byte += 1
  70.         cmd_data = (one_byte & 0x0000ff00) >> 8
  71.         self.cmd = cmd_data
  72.     # 红外解码
  73.     def remote_scan(self):
  74.         # 接收到数据
  75.         if self.rx_ok:
  76.             self.check_cmd()
  77.             self.rx_ok = False
  78.         # 获取对应按钮字符
  79.         s = self.REMOTE_CODE.get(self.cmd)
  80.         return self.cmd,s
复制代码
       在Python脚本中,作者定义了一个名为REMOTE_IR的类,用于创建红外解码对象的实例。该类中,作者使用字典定义了正点原子红外遥控器的按键值(控制码)和按键名称。
       类中接着定义了红外接收初始化方法,用于实例化对象、初始化GPIO引脚、设置中断模式(上升沿和下降沿)以及声明变量。此外,还定义了红外接收回调方法,用于计算逻辑1和逻辑0的时间(请参考图21.1.3.2 红外接收器位定义图)。
       除此之外,还定义了检测命令方法,用于检测接收的按键值(控制码)。最后,作者还定义了红外解码方法,该方法根据按键值(控制码)查询REMOTE_CODE字典的对应内容,并将结果返回给用户。

       1,remote类的构造方法
       remote的构造对象方法如下:
  1. class remote.init(gpio_num)
  2. 使用示例:remote = remote.init(gpio_num)
复制代码
       该构造方法的参数描述,如下表所示。

1.png
表21.2.1 remote.init构造方法参数描述

       返回值: remote对象。

       2,remote类的方法

       ①:获取红外解码的数据。
       其函数原型如下:
  1. remote.remote_scan()
复制代码
       返回值:红外命令和数值。

       21.3 硬件设计

       1. 例程功能
       本章实验功能简介:本实验开机在LCD上显示一些信息之后,即进入等待红外触发,如果接收到正确的红外信号,则解码,并在LCD上显示键值和所代表的意义,以及按键次数等信息。LED闪烁用于提示程序正在运行。

       2. 硬件资源
       1)XL9555
              IIC_INT-IO0(需在P5连接IO0)
              IIC_SDA-IO41
              IIC_SCL-IO42

       2)SPILCD
              CS-IO21
              SCK-IO12
              SDA-IO11
              DC-IO40(在P5端口,使用跳线帽将IO_SET和LCD_DC相连)
              PWR- IO1_3(XL9555)
              RST- IO1_2(XL9555)

       3)红外接收头
              REMOTE_IN-IO2

       4)正点原子红外遥控器

       3. 原理图
       红外遥控接收头与ESP32-S3的连接关系,如下图所示。

第二十一章 红外遥控器实验5546.png
图21.3.1 红外遥控接收头与ESP32-S3的连接电路图

       红外遥控接收头连接在ESP32-S3的IO2上。硬件上不需要变动,只要程序将IO2设计为输入模式且开启外部中断,然后将收到的脉冲信号解码就可以了。不过需要注意:REMOTE_IN和SD卡片选共用了IO2,所以它们不可以同时使用。
       开发板配套的红外遥控器外观如图21.3.2所示:

第二十一章 红外遥控器实验5720.png
图21.3.2 红外遥控器

       开发板上接收红外遥控器信号的红外管外观如图21.3.2所示。使用时需要遥控器有红外管的一端对准开发板上的红外管才能正确收到信号。

       21.4 程序设计

       21.4.1 程序流程图
       程序流程图能帮助我们更好的理解一个工程的功能和实现的过程,对学习和设计工程有很好的主导作用。下面看看本实验的程序流程图。

第二十一章 红外遥控器实验5911.png
图21.4.1.1 程序流程图

       21.4.2 程序解析
       本书籍的代码都在main.py脚本下编写的,读者可在光盘资料下找到对应的源码。红外遥控器实验main.py源码如下:
  1. from machine import Pin,SPI,I2C
  2. import atk_xl9555 as io_ex
  3. import atk_lcd as lcd
  4. import remote
  5. import time


  6. """
  7. * @brief       程序入口
  8. * @param       无
  9. * @retval      无
  10. """
  11. if __name__ == "__main__":
  12.    
  13.     # 初始化LED
  14.     led = Pin(1,Pin.OUT, value = 1)
  15.     # IIC初始化
  16.     i2c0 = I2C(0, scl = Pin(42), sda = Pin(41), freq = 400000)
  17.     # XL9555初始化
  18.     xl9555 = io_ex.init(i2c0)
  19.    
  20.     # 复位LCD
  21.     xl9555.write_bit(io_ex.SLCD_RST,0)
  22.     time.sleep_ms(100)
  23.     xl9555.write_bit(io_ex.SLCD_RST,1)
  24.     time.sleep_ms(100)
  25.    
  26.     # 初始化SPI
  27.     spi = SPI(2,baudrate = 80000000, sck = Pin(12), mosi=Pin(11), miso=Pin(13))
  28.     # 初始化LCD,lcd = 0为正点原子2.4寸屏幕;lcd = 1为正点原子1.3寸SPILCD屏幕;
  29. display = lcd.init(spi,dc = Pin(40,Pin.OUT,Pin.PULL_UP,value=1),
  30. cs=Pin(21,Pin.OUT,Pin.PULL_UP,value = 1),dir = 1,lcd = 0)
  31.     xl9555.write_bit(io_ex.SLCD_PWR,1)
  32.     time.sleep_ms(100)
  33.     # 实验信息
  34.     display.string(30, 50, 240, 16, 16, "ESP32-S3",lcd.RED)
  35.     display.string(30, 70, 240, 16, 16, "REMOTE TEST",lcd.RED)
  36.     display.string(30, 90, 240, 16, 16, "ATOM@ALIENTEK",lcd.RED)
  37.     display.string(30, 120, 200, 16, 16, "CMD:", lcd.RED)
  38.     display.string(30, 150, 200, 16, 16, "DATA:", lcd.RED)
  39.     # 初始化红外接收
  40.     ir = remote.REMOTE_IR(2)
  41.     while True :
  42.         
  43.         cmd,key_str = ir.remote_scan()
  44.         display.fill(30 + 11 * 8 - 2,120,30 + 11 * 8 + 100,200,lcd.WHITE)
  45.         display.string(30 + 11 * 8, 120, 200, 16, 16, str(cmd), lcd.BLUE)
  46.         display.string(30 + 11 * 8, 150, 200, 16, 16, str(key_str), lcd.BLUE)
  47.         led_state = led.value()
  48.         led.value(not led_state)
  49.         time.sleep_ms(500)         # 延时500ms
复制代码
       main函数代码比较简单,主要是通过ir.remote_scan函数获得红外遥控输入的数据(控制码),然后显示在LCD上面。正点原子红外遥控器按键对应的控制码图如下图所示。

第二十一章 红外遥控器实验7707.png
图21.4.2.1 红外遥控器按键对应的控制码图(十六进制数)

       特别注意:上图中的控制码数值是十六进制的,而我们代码中使用的是十进制的表示方式。
       此外,正点原子红外遥控器的地址码是0。

       21.5 下载验证
       将程序下载到开发板后,可以看到LED不停的闪烁,提示程序已经在运行了。LCD显示的内容如下图所示:

第二十一章 红外遥控器实验7888.png
图21.5.1 程序运行效果图

       此时我们通过遥控器按下不同的按键,则可以看到LCD上显示了不同按键的键值以及按键次数和对应的遥控器上的符号。如下图所示:

第二十一章 红外遥控器实验7994.png
图25.5.2 解码成功

阿莫论坛20周年了!感谢大家的支持与爱护!!

曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-8-25 06:19

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表