SR501人体红外模块

简介: SR501人体红外模块

前言

人体红外模块 是一种能够检测人或动物发射的红外线而输出电信号的传感器。广泛应用于各种自动化控制装置中。比如常见的楼道自动开关、防盗报警等。


一、SR501模块介绍

引脚 : VCC,OUT, GND

功能 :一种常见的人体红外传感器模块,用于检测人体的活动。

红外感应原理 :SR501 模块内部包含一个红外传感器探测单元,该单元可以检测环境中的红外辐射变化。即使在黑暗中,人体也会通过辐射红外能量来体现温度差异。

  • 静止状态(无人靠近)时,OUT 引脚通通常为电平。
  • 有人体靠近时,OUT 引脚通常会从低电平变为电平。

2 个电位器 : 可以通过电位器实现封锁时间和检测距离的调节 ( 延时控制,距离调节 )。

二、设备树添加节点

配置设备树需要对 GPIO 引脚 以及相关的 pincontrol 配置。由于本实验是使用 SR501 模块,所以不需要配置 pincontrol


通过 SR501人体红外模块 的原理图得到 该模块 高电平有效。我将其接到开发板的 gpio4-19 引脚。

compatible :用于 和 驱动程序进行匹配。

使用 gpio4 组的 19 号引脚。(每一组有 32 个引脚)

三、驱动程序

  1. 定义字符设备结构体。
    由于 使用 模块 SR501,只需要读出引脚电平即可。
static struct file_operations sr501_ops={
  .owner = THIS_MODULE,
    .read  = sr501_read,
};
  1. 实现 read 函数。

wait_event_interruptible(sr501_wq, sr501_data); : 这是一个等待队列的函数调用。当前执行的线程(或进程)进入睡眠状态,直到满足指定的条件。

sr501_wq :等待队列头对象。

sr501_data 是条件。如果 sr501_data 为真(非零),表示数据已经准备好,线程可以继续执行。否则,线程将进入睡眠状态,并被放入等待队列。

copy_to_user 函数的作用是将内核空间中的数据复制到用户空间的缓冲区(buf)中。

static wait_queue_head_t sr501_wq;    // 定义队列头
static ssize_t sr501_read (struct file *file, char __user *buf, size_t size, loff_t *oddset)
{
  int err;
  int len = (size < 4) ? size : 4;
  wait_event_interruptible(sr501_wq, sr501_data);   /* 无数据休眠,有数据唤醒 */
  err = copy_to_user(buf, &sr501_data, len);
  sr501_data = 0;
  return len;
}
  1. 定义一个platform_driver
    sr501_table 数组 用于和设备树里的 信息进行匹配。
    匹配成功后 直接调用 sr501_probe 函数。
static const struct of_device_id sr501_table[] = {
  { .compatible = "my,sr501"},
  {},
};
static struct platform_driver sr501_driver = {
  .driver = {
    .name   = "sr501",
    .of_match_table = sr501_table,
  },
  .probe      = sr501_probe,
  .remove     = sr501_remove,
};
  1. 注册一个 file_operations 结构体,platform_driver。
    在 入口函数里进行注册,在出口函数里进行 卸载。

init_waitqueue_head:这是个内核函数,用于初始化一个等待队列头对象。等待队列头用于管理等待队列。

&sr501_wq:这是等待队列头对象的地址

static int sr501_init(void)  
{
  int err;
  major = register_chrdev(0, "sr501", &sr501_ops);
  class = class_create(THIS_MODULE, "sr501_class");
  err = PTR_ERR(class);   
  if (IS_ERR(class)) {
    printk("%s %s line %d\n", __FILE__, __FUNCTION__, __LINE__);
    unregister_chrdev(major, "sr501");
    return -1;
  }
  platform_driver_register(&sr501_driver);
  init_waitqueue_head(&sr501_wq);           // 初始化等待队列头
  return 0;
}
static void sr501_exit(void)  
{
  platform_driver_unregister(&sr501_driver);
  class_destroy(class);
  unregister_chrdev(major, "sr501");
}
  1. 实现 probe 函数。
    当设备树 和 驱动和程序匹配成功后调用 probe 函数。

gpiod_get :从设备树里获取 GPIO 引脚信息。

==gpiod_direction_input ==: 设置引脚方向。()输入

gpiod_to_irq :获得中断号。

request_irq : 申请中断。第二个参数是 中断处理函数。

static int sr501_probe(struct platform_device *pdev)
{
  sr501_gpio = gpiod_get(&pdev->dev, NULL, 0);    //获取引脚信息
  gpiod_direction_input(sr501_gpio);    // 设置为 输入引脚
  irq = gpiod_to_irq(sr501_gpio);     // 获取中断号
  request_irq(irq, sr501_isr, IRQF_TRIGGER_RISING|IRQF_TRIGGER_FALLING, "sr501", NULL);   //请求中断
    device_create(class, NULL, MKDEV(major, 0), NULL, "sr501");     //创建设备节点
  return 0;
}
  1. 在 probe 里申请了,就需要在 remove 函数里进行卸载.
  device_destroy(class,MKDEV(major, 0));
  free_irq(irq, NULL);
  gpiod_put(sr501_gpio);
  1. 中断处理函数。
    wake_up 唤醒 在 read 函数里休眠的队列。将 sr501_data 赋值为 1 ,则 read 函数里条件为真,执行程序。
static irqreturn_t sr501_isr(int irq, void *dev_id)
{
  sr501_data = 1;
  wake_up(&sr501_wq);     /* 唤醒队列 */
  return IRQ_HANDLED;
}

四、测试程序

首先判断参数 argc 是否正确。

O_RDWR 可读可写的方式打开设备节点,获取设备句柄 fd

while 循环里读引脚电平,当 引脚为高电平 并且 正确读出时,打印有人靠近。

  if(argc != 2)
  {
    printf("Usage: %s <dev>\n",argv[0]);
    return -1;
  }
  //打开文件
  fd = open(argv[1], O_RDWR);
  if(-1 == fd)
  {
    printf("open %s error!\n",argv[1]);
    return -1;
  }
  while (1)
  {
    ret = read(fd, &val, 4);
    if((1 == val) && (ret == 4))
      printf("有人靠近!\n");
  }
  close(fd);

五、上机测试及效果

  1. 将 .ko 文件加载到内核。
    使用 insmod 命令可以将 KO 文件加载到内核中,使模块生效。而使用rmmod 命令可以卸载已加载的模块,lsmod 命令 可以观察已加载到内核的文件。

  1. 执行测试程序。 /dev/sr501 是在驱动程序中创建的设备节点 ( device_create )。
    当有人靠近时,通过读出引脚电平的变化判断是否有人靠近。

总结

相关文章
|
6月前
|
传感器
什么是振动电阻式传感器测量模块RM501/502
RM501/502是一种振动电阻式传感器测量模块,用于测量物理量。它采用了差动电阻式传感器,通过两个电阻的比值来反映被测物理量。该传感器可以抵消环境温度影响,采用五线制测量方式,可以消除传感器线缆电阻的影响。
什么是振动电阻式传感器测量模块RM501/502
|
传感器 Linux
Linux驱动基础(SR501人体感应模块)
Linux驱动基础(SR501人体感应模块)
130 0
|
7月前
|
传感器 机器人
SR04 超声波测距模块
SR04 超声波测距模块
98 0
|
传感器 数据采集
STM32 BMP280模块 获取气压温度高度传感器数据
STM32 BMP280模块 获取气压温度高度传感器数据 TFT显示
319 0
stm32cubeMX配置人体感应器SR505
stm32cubeMX配置人体感应器SR505
137 0
|
传感器 机器人
STM32 E18-D80NK红外检测
E18-D8ONK 这是一种 集发射与接收于一体 的光电传感器,发射光经过调制后发出,接收头对反射光进行解调输出。有效的避免了可见光的干扰。透镜的使用,也使得这款传感器最远可以检测80厘米距离的问题(由于红外光的特性,不同颜色的物体,能探测的最大距离也有不同;白色物体最远,黑色物体最近)。
437 0
基于STM32F1-C8T6无人机(一)——BF姿态展示(MPU6050(GYI-521))
基于STM32F1-C8T6无人机(一)——BF姿态展示(MPU6050(GYI-521))
202 0
基于STM32F1-C8T6无人机(一)——BF姿态展示(MPU6050(GYI-521))
|
传感器
红外热成像仪 红外图像伪彩色编码
什么是红外成像伪彩编码 红外成像的最终目的是用图像来表现温度变化,并且可以通过颜色来区分出不同热量的物体轮廓和形状。那么,到底用什么颜色来表示什么温度呢?是否有什么标准规范呢?
红外热成像仪  红外图像伪彩色编码