Firefly开源社区

标题: ROC-RK3308-CC开发实例总结--HC-SR505人体红外感应传感器模块调试 [打印本页]

作者: lisd    时间: 2019-1-8 10:09
标题: ROC-RK3308-CC开发实例总结--HC-SR505人体红外感应传感器模块调试
本帖最后由 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 该文件,增加以下资源描述:
  1. sr505_test {
  2.    compatible = "sr505";
  3.    sr505-gpio = <&gpio0 RK_PC4 IRQ_TYPE_EDGE_BOTH>;
  4.    status = "okay";
  5. };
复制代码
其中 sr505-gpio 即为输出引脚,这里设置该引脚为中断模式,触发方式为双边沿触发



驱动程序编写
笔者在 kernel/drivers/misc 目录下新建了 infrared 目录,在该目录下完成驱动程序的编写,如下:
  1. static irqreturn_t irq_handler(int irq, void *dev_id)
  2. {
  3.   val = gpio_get_value(sr505->irq_gpio);
  4.   return IRQ_HANDLED;
  5. }
复制代码
中断处理函数中,完成获取gpio值的工作,并保存在全局变量val中。

  1. ssize_t sr505_read(struct file *filp, char __user *buf, size_t size, loff_t *f_pos)
  2. {
  3.   int ret;
  4.   if(val)
  5.     ret = copy_to_user(buf,"have people",12);
  6.   else
  7.     ret = copy_to_user(buf,"no people",10);
  8.   return ret;
  9. }
复制代码
在该函数中,根据全局变量val的值调用 copy_to_user() 函数拷贝不同的字符串到 buf 数组里面。该函数注册在 struct file_operations 结构体中,如下:
  1. static struct file_operations <font color="Red">sr505_fops</font> = {
  2.   .owner = THIS_MODULE,
  3.   .open = sr505_open,
  4.   .release = sr505_release,
  5.   .read = sr505_read,
  6. };
复制代码
而 sr505_fpos
又注册在 struct miscdevice 结构体中,如下:
  1. static struct miscdevice sr505_miscdev = {
  2.   .minor = MISC_DYNAMIC_MINOR,
  3.   .name = "infrared",
  4.   .fops = &sr505_fops,
  5. };
复制代码
当驱动编译进内核之后,我们可以在串口中 /dev/ 下面看到名字为 “infrared”的字符设备文件。

编译方法见官方维基,链接:http://wiki.t-firefly.com/ROC-RK3308-CC/sdkbuilding.html



温馨提示:完整的驱动文件可见后面附件

测试程序编写
  1. #define path "/dev/infrared"

  2. int main(int argc, char **argv)
  3. {
  4.   char buf[12] = {0};
  5.   int fd = open(path,O_RDONLY);
  6.   char flag = 1;  
  7.   if(fd < 0)
  8.   {
  9.     printf("open error!\n");
  10.     return -1;
  11.   }

  12.   while(1)
  13.   {
  14.     read(fd, buf, sizeof(buf));
  15.     if(strcmp(buf,"have people") == 0 && !flag)
  16.     {
  17.       printf("someone close to\n");
  18.       flag = 1;
  19.     }

  20.     else if(strcmp(buf,"no people") == 0 && flag)
  21.     {
  22.       printf("anybody around here\n");
  23.       flag = 0;
  24.     }
  25.     bzero(buf,sizeof(buf));
  26.   }
  27.   close(fd);
  28.   return 0;
  29. }
复制代码
在应用层通过打开字符设备文件“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),并执行它, 如下:
  1. # /usr/bin/demo
  2. anybody around here
  3. someone close to
  4. anybody around here
  5. someone close to
  6. anybody around here
复制代码
可以看到,有人在感应范围内活动时会打印信息“someone close to”,当人离开感应范围8s左右后会打印信息“
anybody around here”。大功告成!!


infrared.tar (370 KB, 下载次数: 19)



作者: zhangyunqing    时间: 2019-1-9 19:45
谢谢楼主分享,抽空改一下错别字哈
作者: silver_mirror    时间: 2019-3-21 09:23
thanks for sharing! it,s greate!
作者: lovefish991    时间: 2019-9-5 10:50
谢谢楼主分享。。。。。!
作者: zcq    时间: 2019-9-22 22:53
谢谢楼主分享




欢迎光临 Firefly开源社区 (https://dev.t-firefly.com/) Powered by Discuz! X3.1