|
【技术讨论】
ROC-RK3308-CC开发实例总结--HC-SR505人体红外感应传感器模块调试
发表于 2019-1-8 10:09:08
浏览:11284
|
回复:4
打印
只看该作者
[复制链接]
楼主
本帖最后由 lisd 于 2019-2-14 20:27 编辑
传感器介绍
HC-SR505小型人体感应模块是基于红外线技术的自动控制产品,灵敏度高,可靠性强,小体积,低电压工作模式。
全自动感应:人进入其感应范围则输出高点平,人离开感应范围则自动延时(8s左右)关闭高电平,输出低电平。
默认工作电压:DC4.5V-20V
三个引脚:电源正极、电源负极、OUT信号输出
实物图
编写驱动思路
通过简单了解HC-SR505传感器之后,我们发现要实现该功能模块并不复杂。因为该传感器只有一个输出引脚,我们只要获取到该引脚电平,就可以根据这个值来判断是否有人(1:有人 0:没人)
DTS设备注册
修改 kernel/arch/arm64/boot/dts/rockchip/rk3308-firefly.dtsi 该文件,增加以下资源描述:
- sr505_test {
- compatible = "sr505";
- sr505-gpio = <&gpio0 RK_PC4 IRQ_TYPE_EDGE_BOTH>;
- status = "okay";
- };
复制代码 其中 sr505-gpio 即为输出引脚,这里设置该引脚为中断模式,触发方式为双边沿触发
驱动程序编写
笔者在 kernel/drivers/misc 目录下新建了 infrared 目录,在该目录下完成驱动程序的编写,如下:
- static irqreturn_t irq_handler(int irq, void *dev_id)
- {
- val = gpio_get_value(sr505->irq_gpio);
- return IRQ_HANDLED;
- }
复制代码 中断处理函数中,完成获取gpio值的工作,并保存在全局变量val中。
- ssize_t sr505_read(struct file *filp, char __user *buf, size_t size, loff_t *f_pos)
- {
- int ret;
- if(val)
- ret = copy_to_user(buf,"have people",12);
- else
- ret = copy_to_user(buf,"no people",10);
- return ret;
- }
复制代码 在该函数中,根据全局变量val的值调用 copy_to_user() 函数拷贝不同的字符串到 buf 数组里面。该函数注册在 struct file_operations 结构体中,如下:- static struct file_operations <font color="Red">sr505_fops</font> = {
- .owner = THIS_MODULE,
- .open = sr505_open,
- .release = sr505_release,
- .read = sr505_read,
- };
复制代码 而 sr505_fpos 又注册在 struct miscdevice 结构体中,如下:- static struct miscdevice sr505_miscdev = {
- .minor = MISC_DYNAMIC_MINOR,
- .name = "infrared",
- .fops = &sr505_fops,
- };
复制代码 当驱动编译进内核之后,我们可以在串口中 /dev/ 下面看到名字为 “infrared”的字符设备文件。
编译方法见官方维基,链接:http://wiki.t-firefly.com/ROC-RK3308-CC/sdkbuilding.html
温馨提示:完整的驱动文件可见后面附件
测试程序编写
- #define path "/dev/infrared"
- int main(int argc, char **argv)
- {
- char buf[12] = {0};
- int fd = open(path,O_RDONLY);
- char flag = 1;
- if(fd < 0)
- {
- printf("open error!\n");
- return -1;
- }
- while(1)
- {
- read(fd, buf, sizeof(buf));
- if(strcmp(buf,"have people") == 0 && !flag)
- {
- printf("someone close to\n");
- flag = 1;
- }
- else if(strcmp(buf,"no people") == 0 && flag)
- {
- printf("anybody around here\n");
- flag = 0;
- }
- bzero(buf,sizeof(buf));
- }
- close(fd);
- return 0;
- }
复制代码 在应用层通过打开字符设备文件“infrared”,并不断轮询读取最新的buf,然后根据buf的内容判断是否有人,达到实时检测的效果。
测试程序编写完成后,将其加入到 Buildroot 编译系统内。
具体方法见http://wiki.t-firefly.com/ROC-RK3308-CC/buildroot_introduction.html#xin-zeng-ben-di-yuan-ma-bao
效果测试
将驱动程序、测试程序都烧录进板子以后,我们在 /usr/bin/ 目录下找到测试程序生成的可执行文件(笔者的名为demo),并执行它, 如下:- # /usr/bin/demo
- anybody around here
- someone close to
- anybody around here
- someone close to
- anybody around here
复制代码 可以看到,有人在感应范围内活动时会打印信息“someone close to”,当人离开感应范围8s左右后会打印信息“anybody around here”。大功告成!!
infrared.tar
(370 KB, 下载次数: 19)
|
|