人体红外感应模块使用的是热释电红外传感器,它是利用温度变化的特征来探测红外线的辐射,利用双灵敏元互补的方法抑制温度变化产生的干扰,提高了传感器的工作稳定性。产品应用广泛,例如:保险装置、防盗报警器、感应门、自动灯具、智能玩具等。
模块来源
规格参数
工作电压:4.5~20V
工作电流:< 50uA
电平输出:高3.3V/低0V
感应角度:< 100度锥角
输出方式: GPIO
管脚数量:3 Pin
以上信息见厂家资料文件
移植过程
我们的目标是将例程移植至开发板上【能够测量人体】。首先要获取资料,查看数据手册应如何实现读取数据,再移植至我们的工程。
查看资料
全自动感应:人进入其感应范围则输出高电平, 人离开感应范围则自动延时关闭高电平,输出低电平;
两种触发方式:(可跳线选择)
不可重复触发方式: 即感应输出高电平后,延时时间段一结束,输出将自动从高电平变成低电平;
可重复触发方式:即感应输出高电平后,在延时时间段内,如果有人体在其感应范围活动,其输出将一直保持高电平,直到人离开后才延时将高电平变为低电平。
HC-SR501人体感应模块使用说明
- 感应模块通电后有一分钟左右的初始化时间,在此期间模块会间隔地输出0-3 次,一分钟后进入待机状态。
- 避免灯光等干扰源近距离直射模块表面的透镜,以免引进干扰信号产生误动作;尽量避免流动的风,风也会对感应器造成干扰。
- 感应模块采用双元探头,探头的窗口为长方形,双元(A 元B 元)位于较长方向的两端,当人体从左到右或从右到左走过时,红外光谱到达双元的时间、距离有差值,差值越大,感应越灵敏,当人体从正面走向探头或从上到下或从下到上方向走过时,双元检测不到红外光谱距离的变化,无差值,因此感应不灵敏或不工作;所以安装感应器时应使探头双元的方向与人体活动最多的方向尽量相平行,保证人体经过时先后被探头双元所感应。为了增加感应角度范围,本模块采用圆形透镜,也使得探头四面都感应,但左右两侧仍然比上下两个方向感应范围大。
引脚选择
这里选择的引脚见引脚接线表
代码移植
下载为大家准备的驱动代码文件夹,复制到自己工程中\luban-lite\application\rt-thread\helloworld\user-bsp
文件夹下
提示
如果未找到 user-bsp
这个文件夹,说明你未进行模块移植的前置操作。请转移到手册使用必要操作(点击跳转)中进行必要的配置操作!!!
接下来打开自己的工程,开始修改Kconfig文件。
1、在 VSCode 中打开 application\rt-thread\helloworld\Kconfig 文件
2、在该文件的 #endif
前面添加该模块的 Kconfig路径语句
# 人体红外传感器
source "application/rt-thread/helloworld/user-bsp/human-body-infrared-sensor/Kconfig"
2
menuconfig操作
1、我们 双击 luban-lite
文件夹下的 win_env.bat
脚本打开env工具:
2、输入以下命令列出所有可用的默认配置:
scons --list-def
3、选择 d13x_JLC_rt-thread_helloworld
这个配置!这个是我们衡山派开发板的默认配置!输入以下命令即可:
scons --apply-def=7
或者
scons --apply-def=d13x_JLC_rt-thread_helloworld_defconfig
这两个命令作用是一样的,一个是 文件名 ,一个是 编号 !!!
4、输入以下命令进入menuconfig菜单
scons --menuconfig
进入以下界面:
5、选中 Porting code using the LCKFB module
按
Y
选中按
N
取消选中方向键
左右
调整 最下面菜单的选项方向键
上下
调整 列表的选项
回车
执行最下面菜单的选项
6、回车进入 Porting code using the LCKFB module
菜单
7、按方向键 上下
选中 Using human body infrared sensor
后按 Y
键,看到前面括号中出现一个 *
号,就可以下一步了。
8、按方向键 左右
选中 <Save>
然后一路回车
,然后 退出
即可
编译
我们 保存并退出menuconfig菜单 之后,输入以下命令进行编译:
scons
或
scons -j16
-j 用来选择参与编译的核心数: 我这里是选择16
大家可以根据自己的电脑来选择
核心越多编译越快
如果写的数量高于电脑本身,那么就自动按照最高可用的来运行!
镜像烧录
编译完成之后会在 \luban-lite\output\d13x_JLC_rt-thread_helloworld\images
文件夹下生成一个 d13x_JLC_v1.0.0.img
镜像文件!
然后我们烧录镜像,具体的教程请查看:镜像烧录(点击跳转🚀)
到这里完成了,请移步到 最后一节 进行移植验证。
工程代码解析
bsp_humanir.c
/*
* 立创开发板软硬件资料与相关扩展板软硬件资料官网全部开源
* 开发板官网:www.lckfb.com
* 文档网站:wiki.lckfb.com
* 技术支持常驻论坛,任何技术问题欢迎随时交流学习
* 嘉立创社区问答:https://www.jlc-bbs.com/lckfb
* 关注bilibili账号:【立创开发板】,掌握我们的最新动态!
* 不靠卖板赚钱,以培养中国工程师为己任
*/
#include <stdlib.h>
#include <string.h>
#include <getopt.h>
#include <sys/time.h>
#include <rtthread.h>
#include <inttypes.h>
#include <finsh.h>
#include "hal_adcim.h"
#include "rtdevice.h"
#include "aic_core.h"
#include "aic_log.h"
#include "hal_gpai.h"
#include "aic_hal_gpio.h"
#include "hal_i2c.h"
#include "bsp_humanir.h"
#define HUMANIR_PIN_NAME "PE.14"
static rt_base_t HumanIR_PIN;
//获取引脚的电平变化
#define HumanIR_PIN_GET() rt_pin_read(HumanIR_PIN)
/**********************************************************
* 函 数 名 称:HumanIR_State_Read
* 函 数 功 能:返回引脚电平状态
* 传 入 参 数:无
* 函 数 返 回:0:检测到人体 1:未检测到人体
* 作 者:LCKFB
* 备 注:
**********************************************************/
int HumanIR_State_Read(void)
{
return HumanIR_PIN_GET();
}
/**********************************************************
* 函 数 名 称:HumanIR_Init
* 函 数 功 能:初始化HumanIR
* 传 入 参 数:无
* 函 数 返 回:RT_OK:完成 -RT_ERROR:错误
* 作 者:LC
* 备 注:LP
**********************************************************/
int HumanIR_Init(void)
{
HumanIR_PIN = rt_pin_get(HUMANIR_PIN_NAME);
rt_pin_mode(HumanIR_PIN, PIN_MODE_INPUT_PULLUP);
return RT_EOK;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
bsp_humanir.h
/*
* 立创开发板软硬件资料与相关扩展板软硬件资料官网全部开源
* 开发板官网:www.lckfb.com
* 文档网站:wiki.lckfb.com
* 技术支持常驻论坛,任何技术问题欢迎随时交流学习
* 嘉立创社区问答:https://www.jlc-bbs.com/lckfb
* 关注bilibili账号:【立创开发板】,掌握我们的最新动态!
* 不靠卖板赚钱,以培养中国工程师为己任
*/
#ifndef __BSP_HUMANIR_H__
#define __BSP_HUMANIR_H__
#include "stdio.h"
int HumanIR_Init(void);
int HumanIR_State_Read(void);
#endif
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Kconfig
这个是一个menuconfig中的选项,如果在菜单中选中该选项,就会在rtconfig.h
中定义一个语句,用来if判断条件编译之类的。
config LCKFB_HUMAN_BODY_IR_SENSOR
bool "Using human body infrared sensor"
default n
help
More information is available at: https://wiki.lckfb.com/
2
3
4
5
6
SConscript
自动化构建文件,如果定义了 LCKFB_HUMAN_BODY_IR_SENSOR
和 USING_LCKFB_TRANSPLANT_CODE
就自动编译当前目录下的文件!!
Import('RTT_ROOT')
Import('rtconfig')
import rtconfig
from building import *
cwd = GetCurrentDir()
CPPPATH = [cwd]
src = []
if GetDepend('LCKFB_HUMAN_BODY_IR_SENSOR') and GetDepend('USING_LCKFB_TRANSPLANT_CODE'):
src = Glob(os.path.join(cwd, '*.c'))
group = DefineGroup('lckfb-human-body-infrared-sensor', src, depend = [''], CPPPATH = CPPPATH)
Return('group')
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
test_human_body_infrared_sensor.c
这个文件定义了一个人体红外传感器处理的线程,初始化了红外传感器的硬件抽象层,并设置了线程的优先级、栈大小和时间片。
线程的主要任务是检测人体红外传感器是否检测到人体存在,并进行延时处理。当传感器检测到人体时,相关信息会被打印到控制台。通过命令行接口,用户可以启动这个线程来测试人体红外传感器的功能,并且可以输入命令来退出这个线程。
线程入口函数逻辑
- 初始化人体红外传感器。
- 打印初始化成功的信息。
- 在一个无限循环中,首先读取人体红外传感器的状态。
- 如果检测到人体,打印相关信息,并延时1秒。
- 如果没有检测到人体,延时500毫秒。
- 控制循环次数,并在每100次循环后提示用户可以通过输入命令退出读取循环。
- 在每次循环结束时,根据不同条件进行相应的延时处理。
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <getopt.h>
#include <sys/time.h>
#include <rtthread.h>
#include "rtdevice.h"
#include "aic_core.h"
#include "aic_hal_gpio.h"
#include "bsp_humanir.h"
#define THREAD_PRIORITY 25 // 线程优先级
#define THREAD_STACK_SIZE 1024 // 线程大小
#define THREAD_TIMESLICE 10 // 时间片
static rt_thread_t humanir_thread = RT_NULL; // 线程控制块
// 线程入口函数
static void humanir_thread_entry(void *param)
{
int loop_counter = 1;
int ret = 0;
/* HUMANIR 初始化 */
HumanIR_Init();
rt_kprintf("HUMANIR initialized successfully!\n");
/* 主循环 */
while (1)
{
int humanir_state = HumanIR_State_Read();
if(!humanir_state)
{
rt_kprintf("\nDiscover the human body !!\n");
rt_thread_mdelay(1000); // 延时 1 秒
}
else
{
rt_thread_mdelay(500); // 延时 500ms
}
/* 控制循环次数和用户提示 */
if (loop_counter++ >= 100)
{
loop_counter = 1;
rt_kprintf("Type 'test_exit_human_body_ir_sensor' to exit HUMANIR read loop.\n");
rt_kprintf("Note: Press [TAB] for auto-completion of the command.\n");
aicos_mdelay(2000); // 延时 2 秒
}
}
}
/* HUMANIR启动函数 */
static void test_human_body_ir_sensor(int argc, char **argv)
{
/* 创建线程,名称是 humanir_thread,入口是 humanir_thread_entry */
humanir_thread = rt_thread_create("humanir_thread",
humanir_thread_entry, RT_NULL,
THREAD_STACK_SIZE,
THREAD_PRIORITY, THREAD_TIMESLICE);
/* 如果获得线程控制块,启动这个线程 */
if (humanir_thread != RT_NULL)
rt_thread_startup(humanir_thread);
}
// 导出函数为命令
MSH_CMD_EXPORT(test_human_body_ir_sensor, run human body infrared sensor);
/* HUMANIR退出函数 */
static void test_exit_human_body_ir_sensor(void)
{
int ret = rt_thread_delete(humanir_thread);
if(ret != RT_EOK)
{
LOG_E("failed to test_exit_human_body_ir_sensor !!");
}
else
{
rt_kprintf("\n========HUMANIR exit successful !!========\n");
}
}
// 导出函数为命令
MSH_CMD_EXPORT(test_exit_human_body_ir_sensor, quit HUMANIR);
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
移植验证
我们使用串口调试,将 USB转TTL模块 连接到衡山派开发板上面!!
具体的教程查看:串口调试(点击跳转🚀)
串口波特率默认为
115200
我们在输入下面的命令运行该模块的线程:
输入的时候按下
TAB键
会进行命令补全!!
test_human_body_ir_sensor