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 该文件,增加以下资源描述:

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”的字符设备文件。
编译方法见官方维基,链接:固件编译 — Firefly Wiki

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

测试程序编写

#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)

谢谢楼主分享,抽空改一下错别字哈{:4_90:}

thanks for sharing! it,s greate!

谢谢楼主分享。。。。。!

谢谢楼主分享