随着科技进步,手机逐渐融入了我们的日常生活。通过在手机中内置红外发射器,手机可以模拟各种遥控器的操作,实现对不同家电设备的控制。在电视精灵的Android版本中,也支持了红外遥控器功能,实现对移动高清机顶盒的遥控操作,提升了用户手机控制大屏的体验。电视精灵红外遥控器的样式,如下图1所示,基本涵盖了用户日常操作指令。
红外遥控是一种古老而实用的技术,它是利用红外线的特性来传递信息。红外线是一种不可见光,具有较强的穿透力和方向性。在红外遥控中,发射器会将控制指令编码成特定的红外信号,并通过发射二极管将其发射出去。当这些红外信号到达接收设备时,接收设备中的红外接收器会将其接收并解码,从而执行相应的操作。接下来,本文将详细介绍红外系统的实现原理,并以电视精灵红外遥控为例,介绍如何在Android系统上开发红外遥控功能。
图1 电视精灵红外遥控
红外遥控系统通常由红外发射器和红外接收器组成。红外发射器将控制信号转换为红外光信号发射出去,而红外接收器则接收这些红外光信号,并将其转换回电信号,从而实现对设备的控制。红外遥控系统发送和接收的主要组成结构,如下图所示。
图2 红外系统组成结构
红外遥控器发射的信号由一串“0”和“1”的二进制代码组成,不同的芯片对“0”和“1”的编码有所不同,通常有曼彻斯特 (Manchester) 编码和脉冲宽度编码 (PWM)。
家用电器使用的红外遥控器绝大部分都是脉冲宽度编码,例如常用的电视遥控器使用NEC upd6121芯片,其“0”为载波发射0.56ms,不发射0.56ms;其“1”为载波发射0.56ms,不发射1.68ms。一个简单的编码例子,如下图所示:
图3 脉冲电平
图4 红外编码
在红外通信中,将编码后的二进制信号调制成特定频率(如38kHz)的间断脉冲串是一个常见的做法。这种调制方式通常被称为脉冲调制或载波调制。在这个过程中,原始的二进制信号(由“0”和“1”组成)被用来控制一个高频载波信号(如38kHz的脉冲信号)的开关状态。
具体实现时,二进制信号中的“1”和“0”,分别由不同38kHz载波和低电平组成。如“0”为由 0.56ms 的 38kHz 载波和 0.56ms 的无载波低电平组合而成;“1”由 0.56ms 的 38kHz 载波和 1.69ms 的无载波低电平组合而成。这样,原始的二进制信号就被转换成了一个间断的脉冲串,其中每个脉冲都对应于原始信号中的一个位。
如下图所示,以下是一个简化的描述,说明如何使用高低电平来控制红外信号的调制:
图5 载波调制
解调是调制的逆过程,是通过红外接收管进行信号接收的。其基本工作过程为:当接收到调制信号时,输出高电平,否则输出为低电平。
图6 红外解调
解码是将解调输出的脉冲,还原为二进制的“0”和“1”,得到二进制的“0”,“1”序列,进而通过编码协议分析传输内容所含的用户码和数据码。
图7 红外解码
截止目前,iphone手机还没有配置红外发射硬件,因此在iphone手机上是不支持红外指令发射的。文中后续的开发介绍,也是基于Android系统进行介绍的。
在App工程的AndroidManifest.xml中补充红外权限配置。
红外遥控功能从Android4.4之后才开始支持,对应的管理类名叫ConsumerIrManager,常用的三个方法分别是:
红外编码由“引导码 + 用户编码(高八位)+ 用户编码(低八位)+ 键数据码 + 键数据反码 + 结束码”组成,然后按照一定的编码规则,合成数组的形式。以NEC6122协议举例,引导码固定为(9000 + 4500),结束码固定为(560,20000)。不同遥控器差别主要在于用户码和数据码,同一个遥控器的用户码是一样的,不同按键有不同的码值,码值可以转换出对应的数据码和数据反码。
名称 | 协议 | 用户码 | 键值 |
Power | NEC | 0x08E6 | 0x47 |
1 | NEC | 0x08E6 | 0x42 |
2 | NEC | 0x08E6 | 0x41 |
3 | NEC | 0x08E6 | 0x40 |
上述表格中列了NEC协议的几个指令,下面以按键数字2进行举例。
数据码
原码:01000001(表示41)
反码:10111110(41的反码)
由于手机与遥控器的信号编码有区别,需要逆序编码。
用户码
高八位: 00010000
低八位: 01100111
数据码
原码:10000010
反码:01111101
编码转换完成,通过transmit方法进行发送。但是参数要传递整型数组形式的信号,并不是二进制数而是电平信号数据。电平是电路中某一点电压的高低状态,在数字电路中常用高电平表示“1”,用低电平表示“0”。根据上文可以看出,遥控器发射红外信号之时,通过“560us高电平+1690us低电平”代表“1”,通过“560us高电平+565us低电平”代表“0”。于是编写Android代码的时候,使用“560,1690”表示二进制的1,使用“560,565”表示二进制的0,具体数组值如下所示:
当我们做好指令和数组值的映射,并选定信号频率。在需要发射红外信号处调用如下:
红外遥控功能,已经在电视精灵的Android版本中落地。为了保证用户体验和功能的有效性,在开发过程中,我们考虑并解决了以下两个问题:
针对如上两个问题,对应解决方案分别是:
红外遥控为了兼容不同设备,采用了红外码值动态下发的方式。主要流程如下图所示:
图8 红外码值动态下发
当用户快速点击红外遥控时,可能会导致部分指令丢失。为了确保每个指令在手机端都能得到处理,我们基于线程池框架,实现红外操作指令的控制队列,具体实现如下所示。
2. 单线程发码保证先后顺序,确保每次只有一个指令在执行
红外遥控是一项非常实用的技术,它让我们能够轻松地操控各种家电设备。红外遥控具有操作简单、成本相对较低等优点,在家庭和日常生活中得到了广泛应用。但它也存在一些不足之处,比如信号容易被阻挡、对角度有一定要求,且不同设备之间可能存在兼容性问题。尽管如此,红外遥控依然是我们生活中不可或缺的一部分,它为我们带来了便利,也见证了科技的发展与进步。