IR(Infrared Radiation,红外线),是一种无线通讯方式。通常遥控器作为发送端,电视或者机顶盒作为接收端。在接收过程中,红外波信号通过光学滤波器和光电二极管转换为电信号,此信号经过放大、检波、整形、解调、送到解码与接口电路,从而完成相应的遥控功能。
在RK平台上,底层的PWM驱动能够支持对红外数据进行解调,将其转换为指定的数据,通过input_event的方式将其上报到系统层。
对于不同的遥控器来说,它的每个usercode及键码对应关系是不一样的,这个对应关系通常可以由遥控器厂家那里获得,并且这个对应关系需要在设备树里面配置。底层的驱动会根据这个键码表来将解析的数据转换为指定的key值。
使用如下命令可以查看当前系统所有的INPUT设备
cat /proc/bus/input/devices
结果如下
第一个即为IR设备。
IR插槽上面需要插一个红外接收头,接线如下
此外,这类input设备虽然能够通过cat或者hexdump这类命令来读取,但是读取到的内容无法解析出来,因此我们只介绍使用C API来操作的方法
“/dev/input”下面的所有event节点需要root权限才能操作,使用C语言编译出来的程序操作input设备需要root权限。如果是ssh或者使用LX终端的,先执行如下命令获取root权限。
sudo su
通过连接 libperipheral_api.a 静态库,可以使用C语言调用以下接口来操作IR
/**
* @name: user_ir_open
* @description: 打开ir设备
* @return 大于等于0 - 成功,返回值为文件描述符 小于0 - 失败
*/
int user_ir_open(void);
/**
* @name: user_ir_get
* @description: 从ir设备读取数据
* @param fd: 文件描述符,user_ir_open 返回值
* @param code: 当前按键值
* @param value: 当前事件类型,1 - 按下 0 - 弹起
*
* @return 等于0 - 成功 小于0 - 失败,无数据或出错
*/
int user_ir_get(int fd, int *code, int *value);
/**
* @name: user_ir_close
* @description: 关闭ir设备
* @param fd: 文件描述符,user_ir_open 返回值
* @return 始终等于0,无意义
*/
int user_ir_close(int fd);
测试demo如下
#include "peripheral_api.h"
void ir_api_test(void)
{
int ret = 0;
int fd = -1;
int code = 0, value = 0;
fd = user_ir_open();
if (fd < 0) {
printf("user_ir_open fail \n");
return;
}
for (;;) {
ret = user_ir_get(fd, &code, &value);
if (ret == 0) {
printf("key %d %s\n", code, (value) ? "pressed" : "released");
} else {
usleep(10 * 1000);
}
}
user_ir_close(fd);
return;
}
int main()
{
ir_api_test();
return 0;
}
编译运行结果如下,依次按下 1 2 3 4 5 6按钮
注意这个键值和数值并不是对应的,二者之间的关系可以查看kernel里面的 include/uapi/linux/input-event-codes.h 头文件