在智能硬件项目中,人体感应是一类非常常见的输入能力。楼道感应灯、自动门、安防提醒、无人值守设备唤醒、展厅互动装置,都需要判断环境中是否有人移动。对于硬件编程入门来说,PIR 人体热释电传感器非常适合教学,因为它把复杂的人体红外变化封装成简单的高低电平输出,程序只需要读取 GPIO 输入状态,就能判断是否检测到人体移动。
本实验使用 CanMV K210 / MaixPy 开发板读取 PIR 人体热释电传感器状态,并通过 RGB LED 显示不同系统状态。程序启动后,RGB 灯会短暂闪烁白色表示初始化;未检测到人体移动时,RGB 灯显示蓝色;检测到人体移动时,RGB 灯切换为黄色;当状态发生变化时,RGB 灯会闪烁提示;程序被手动停止时,会自动关闭 RGB 灯。整个过程展示了“传感器输入 + 程序判断 + 灯光反馈”的完整硬件交互链路。
| 学习目标 | 说明 |
|---|---|
| 理解 PIR 输入 | 认识 PIR 人体热释电传感器如何通过 OUT 引脚输出检测状态 |
| 掌握 GPIO 输入读取 | 使用maix.GPIO创建输入对象,并通过value()读取传感器电平 |
| 掌握 RGB 状态反馈 | 使用 PWM 控制 RGB LED 的红、绿、蓝三路亮度 |
| 理解状态变化判断 | 使用last_state记录上一次状态,避免同一状态反复触发提示 |
| 建立交互控制思路 | 将人体移动检测结果转换成灯光颜色变化,为安防、感应灯和交互项目打基础 |
文章目录
- 理论基础
- 硬件设施
- 软件代码
- 扩展应用
- 总结
理论基础
PIR 人体热释电传感器是一种常见的人体移动检测模块。它并不是直接识别人脸或人体轮廓,而是通过感知人体红外辐射变化来判断是否有人经过。当检测到人体移动时,模块的 OUT 引脚会输出一个状态电平;未检测到移动时,OUT 引脚会回到另一种状态。对于程序来说,PIR 模块已经把复杂的感应过程简化成了一个可以读取的高低电平信号。
RGB LED 则承担状态反馈任务。普通单色 LED 只能表示亮或灭,而 RGB LED 可以通过红、绿、蓝三路亮度组合出不同颜色。本实验中,白色表示系统启动提示,蓝色表示无人待机,黄色表示检测到人体移动,红色预留为异常提示。这样一来,传感器输入状态就能通过颜色变化直观表现出来。
本实验的控制链路可以理解为:PIR 传感器负责感知人体移动,CanMV K210 通过 GPIO 读取 OUT 信号,程序根据读取结果判断状态变化,再通过 PWM 改变 RGB LED 的颜色。输入侧是 GPIO,输出侧是 PWM,中间由程序状态判断连接起来。
这张流程图展示的是从人体移动到灯光反馈的完整电路与控制过程。PIR 负责产生输入信号,GPIO 负责读取输入状态,程序负责判断状态是否变化,PWM 负责控制 RGB LED 的颜色。这个结构和很多智能硬件项目一致:传感器采集环境变化,程序进行判断,执行器或显示模块给出反馈。
PWM 是本实验中另一个重要概念。RGB LED 的三路颜色通道不是简单地只需要开或关,而是需要通过不同亮度组合出不同颜色。程序中的颜色值采用0xRRGGBB形式,例如0x0000FF表示蓝色,0xFFFF00表示黄色。set_color()会把 16 进制颜色拆成红、绿、蓝三个通道,再转换成 PWM 占空比输出到对应引脚。
硬件设施
本实验真正使用到的硬件包括 CanMV K210 开发板、PIR 人体热释电传感器和 RGB LED。PIR 传感器负责感知人体移动,RGB LED 负责显示系统状态,CanMV 开发板负责读取传感器输入并控制灯光输出。软件部分主要使用maix.GPIO、fpioa_manager.fm、machine.PWM和machine.Timer,分别承担 GPIO 输入、引脚映射、PWM 输出和定时器驱动等任务。
接线关系可以先通过下面这张图建立整体印象。PIR 模块的 OUT 接到 IO10,用于向 CanMV 输出人体移动检测结果;RGB LED 的红、绿、蓝三路分别接到 IO6、IO7、IO8,用于显示不同状态颜色。
| 硬件 / 软件 | 作用 | 说明 |
|---|---|---|
| CanMV K210 / MaixPy 开发板 | 实验运行平台 | 执行 Python 程序,读取 PIR 输入信号,并通过 PWM 控制 RGB LED |
| PIR 人体热释电传感器 | 人体移动检测模块 | OUT 引脚输出高低电平,程序读取该电平判断是否检测到人体移动 |
| RGB LED | 状态显示模块 | 通过红、绿、蓝三路 PWM 输出组合出不同颜色 |
| IO10 | PIR 信号输入引脚 | 代码中通过PIR_PIN = 10指定,用于读取 PIR OUT 信号 |
| IO6 / IO7 / IO8 | RGB 三色控制引脚 | 分别连接 RGB LED 的红、绿、蓝通道 |
maix.GPIO | GPIO 输入控制模块 | 创建 PIR 输入对象,并通过value()读取传感器状态 |
fpioa_manager.fm | 引脚功能映射模块 | 将物理引脚 IO10 映射为GPIOHS0 |
machine.PWM | PWM 输出模块 | 控制 RGB LED 各颜色通道的亮度 |
machine.Timer | PWM 定时器模块 | 为三路 RGB PWM 输出提供定时器通道 |
time | 延时控制模块 | 控制闪烁节奏、初始化等待和循环检测间隔 |
实验中使用的 PIR 传感器和 RGB LED 模块如下。PIR 负责输入,RGB LED 负责输出,二者组合起来就能形成一个简单的人体移动感应反馈系统。
根据代码和注释可知,PIR 模块的 VCC 接 5V,GND 接 GND,OUT 接 IO10。RGB LED 的红色通道接 IO6,绿色通道接 IO7,蓝色通道接 IO8。PIR 信号属于输入,RGB LED 属于输出,两者共同构成一个简单的人体移动感应反馈系统。
| 物理引脚 | 功能类型 | 代码变量 | 对应硬件 | 说明 |
|---|---|---|---|---|
| IO10 | GPIOHS0 输入 | pir_sensor | PIR OUT | 用于读取人体移动检测信号 |
| IO6 | PWM 输出 | rgb_red | RGB LED Red | 用于控制红色通道亮度 |
| IO7 | PWM 输出 | rgb_green | RGB LED Green | 用于控制绿色通道亮度 |
| IO8 | PWM 输出 | rgb_blue | RGB LED Blue | 用于控制蓝色通道亮度 |
| 5V | 电源 | PIR VCC | PIR 供电 | 给 PIR 模块供电 |
| GND | 地线 | PIR GND | PIR 接地 | 形成完整供电回路 |
| VCC / GND | RGB 供电参考 | 无 | RGB LED | 根据模块类型连接供电和公共地 |
IO10 在代码中被注册成GPIOHS0,用于读取 PIR 传感器的高低电平。IO6、IO7、IO8 没有通过普通 GPIO 控制,而是直接作为 PWM 输出引脚使用。PWM 可以理解成高速切换的电平控制方式,占空比越高,对应颜色通道越亮。RGB LED 通过三路不同亮度组合出白色、蓝色、黄色、红色和关闭状态。
完成接线后的整体状态如下。运行程序后,RGB LED 会在启动阶段短暂闪烁白色,随后进入检测状态。没有检测到人体移动时保持蓝色,检测到人体移动后切换为黄色,并在状态变化时闪烁提示。
| 实验现象 | 正常表现 | 异常提示 |
|---|---|---|
| 程序启动 | RGB 灯短暂闪烁白色 | 不闪烁时检查 RGB 接线、PWM 引脚和程序是否运行 |
| 传感器稳定等待 | 串口提示 PIR 模块需要等待稳定 | PIR 上电后短时间状态不稳定属于正常现象 |
| 未检测到人体移动 | RGB 灯显示蓝色 | 如果一直不是蓝色,检查 PIR OUT 信号状态 |
| 检测到人体移动 | RGB 灯切换为黄色 | 如果人体经过无变化,检查 PIR OUT 是否接到 IO10 |
| 状态变化 | RGB 灯会先闪烁,再保持对应颜色 | 频繁闪烁可能与环境干扰或 PIR 输出抖动有关 |
| 程序停止 | RGB 灯关闭 | 如果强制断开程序,灯可能停留在最后颜色状态 |
软件代码
本实验代码围绕 PIR 输入检测和 RGB 状态反馈展开。程序先定义 RGB 引脚、PIR 引脚和颜色常量,再封装颜色转换、PWM 占空比计算、RGB 设置、闪烁提示和 PIR 读取函数。setup()完成硬件初始化,loop()持续检测 PIR 状态,并在人体移动状态发生变化时切换 RGB 灯光。
| 软件环境 | 作用 | 检查重点 |
|---|---|---|
| CanMV IDE | 编辑、运行和调试 K210 程序 | 能识别开发板串口,并能运行基础print()测试 |
| CanMV / MaixPy 固件 | 提供 GPIO、PWM、Timer 等模块 | 固件环境需要支持当前代码中的maix.GPIO、machine.PWM和machine.Timer |
| USB 串口驱动 | 让电脑识别开发板串口 | 串口工具或 IDE 中能看到对应端口 |
maix.GPIO | GPIO 输入模块 | 能读取 PIR OUT 的高低电平 |
machine.PWM | PWM 输出模块 | 能控制 RGB LED 三路颜色亮度 |
machine.Timer | PWM 定时器模块 | 能为三路 PWM 提供定时器通道 |
time | 延时模块 | 控制初始化等待、闪烁节奏和检测间隔 |
#!/usr/bin/env python3# -*- coding: utf-8 -*-""" CanMV K210 / MaixPy PIR 人体热释电传感器实验 Demo 实验效果: 1. 程序启动后 RGB 灯短暂显示白色,表示系统初始化 2. PIR 未检测到人体移动时,RGB 灯显示蓝色 3. PIR 检测到人体移动时,RGB 灯显示黄色 4. 状态发生变化时,RGB 灯会闪烁提示 5. 程序停止时自动关闭 RGB 灯 接线说明: PIR VCC -> 5V PIR GND -> GND PIR OUT -> IO10 RGB LED Red -> IO6 RGB LED Green -> IO7 RGB LED Blue -> IO8 """importtimefrommaiximportGPIOfromfpioa_managerimportfmfrommachineimportPWM,Timer# =========================# 硬件引脚配置# =========================RGB_PINS={"red":6,"green":7,"blue":8}PIR_PIN=10# 如果使用的是共阳 RGB 模块,改成 True# 如果使用的是共阴 RGB 模块,保持 FalseRGB_COMMON_ANODE=False# =========================# 颜色配置# =========================COLOR_OFF=0x000000COLOR_BOOT=0xFFFFFFCOLOR_IDLE=0x0000FF# 蓝色:无人状态COLOR_MOTION=0xFFFF00# 黄色:检测到人体移动COLOR_ERROR=0xFF0000# 红色:异常提示# =========================# 全局硬件对象# =========================pir_sensor=Nonergb_red=Nonergb_green=Nonergb_blue=None# =========================# 工具函数# =========================defmap_value(x,in_min,in_max,out_min,out_max):""" 数值映射函数 将 0~255 的颜色亮度转换成 0~100 的 PWM 占空比 """return(x-in_min)*(out_max-out_min)/(in_max-in_min)+out_mindefto_duty(value):""" 将 0~255 的颜色值转换成 PWM 占空比 """duty=round(map_value(value,0,255,0,100))ifRGB_COMMON_ANODE:duty=100-dutyreturndutydefset_color(color):""" 设置 RGB LED 颜色 color 使用 16 进制颜色值,例如: 0xFF0000 表示红色 0x00FF00 表示绿色 0x0000FF 表示蓝色 0xFFFF00 表示黄色 """red_value=(color&0xFF0000)>>16green_value=(color&0x00FF00)>>8blue_value=color&0x0000FFrgb_red.duty(to_duty(red_value))rgb_green.duty(to_duty(green_value))rgb_blue.duty(to_duty(blue_value))defblink_color(color,times=2,on_ms=120,off_ms=120):""" 闪烁指定颜色,用于状态切换提示 """for_inrange(times):set_color(color)time.sleep_ms(on_ms)set_color(COLOR_OFF)time.sleep_ms(off_ms)defread_pir():""" 读取 PIR 人体热释电传感器状态 返回值: 1 表示检测到人体移动 0 表示未检测到人体移动 """returnpir_sensor.value()# =========================# 初始化函数# =========================defsetup():globalpir_sensorglobalrgb_red,rgb_green,rgb_blue# PIR 传感器输入引脚映射fm.register(PIR_PIN,fm.fpioa.GPIOHS0,force=True)pir_sensor=GPIO(GPIO.GPIOHS0,GPIO.IN,GPIO.PULL_UP)# RGB LED PWM 定时器配置timer_red=Timer(Timer.TIMER0,Timer.CHANNEL0,mode=Timer.MODE_PWM)timer_green=Timer(Timer.TIMER0,Timer.CHANNEL1,mode=Timer.MODE_PWM)timer_blue=Timer(Timer.TIMER0,Timer.CHANNEL2,mode=Timer.MODE_PWM)rgb_red=PWM(timer_red,freq=2000,duty=0,pin=RGB_PINS["red"])rgb_green=PWM(timer_green,freq=2000,duty=0,pin=RGB_PINS["green"])rgb_blue=PWM(timer_blue,freq=2000,duty=0,pin=RGB_PINS["blue"])set_color(COLOR_OFF)print("PIR 人体热释电实验启动")print("PIR 模块上电后需要短暂稳定,等待 3 秒")blink_color(COLOR_BOOT,times=3,on_ms=120,off_ms=120)time.sleep_ms(3000)print("初始化完成,开始检测人体移动")# =========================# 主循环# =========================defloop():last_state=-1whileTrue:current_state=read_pir()ifcurrent_state!=last_state:ifcurrent_state==1:print("检测到人体移动,切换为警戒提示状态")blink_color(COLOR_MOTION,times=3,on_ms=100,off_ms=100)set_color(COLOR_MOTION)else:print("未检测到人体移动,切换为待机状态")blink_color(COLOR_IDLE,times=2,on_ms=100,off_ms=100)set_color(COLOR_IDLE)last_state=current_state time.sleep_ms(200)# =========================# 程序入口# =========================if__name__=="__main__":try:setup()loop()exceptKeyboardInterrupt:set_color(COLOR_OFF)print("程序已停止,RGB LED 已关闭")这段代码可以分成硬件参数配置、颜色参数配置、工具函数封装、初始化函数、主循环和退出处理几个部分。RGB_PINS用字典保存三路 RGB 引脚,后续创建 PWM 对象时通过"red"、"green"、"blue"读取对应引脚编号。这样的写法比把数字散落在代码中更容易维护,后续更换接线时只需要修改字典中的引脚值。
PIR_PIN = 10表示 PIR 信号线连接在 IO10。setup()中通过fm.register(PIR_PIN, fm.fpioa.GPIOHS0, force=True)把 IO10 映射为GPIOHS0,再通过GPIO(GPIO.GPIOHS0, GPIO.IN, GPIO.PULL_UP)创建输入对象。PIR 模块本身输出高低电平,程序只需要调用pir_sensor.value()读取当前状态即可。
RGB LED 的颜色控制由set_color()完成。代码接收一个 16 进制颜色值,通过位运算拆出红、绿、蓝三个 0~255 的亮度值,再转换成 0~100 的 PWM 占空比。比如0xFFFF00会被拆成红色 255、绿色 255、蓝色 0,实际表现为黄色。RGB_COMMON_ANODE用于兼容共阳 RGB 模块,如果颜色亮灭逻辑相反,只需要把它改为True。
| 函数名 | 功能 | 对应现象 |
|---|---|---|
map_value() | 将一个数值从原范围映射到目标范围 | 把 0~255 颜色亮度换算成 PWM 可用范围 |
to_duty() | 将颜色通道值转换成 PWM 占空比 | 控制 RGB 单个颜色通道亮度 |
set_color() | 设置 RGB LED 颜色 | RGB 灯显示关闭、白色、蓝色、黄色等状态 |
blink_color() | 让指定颜色闪烁 | 状态切换时产生明显灯光提示 |
read_pir() | 读取 PIR 传感器电平 | 判断是否检测到人体移动 |
setup() | 初始化 PIR 输入和 RGB PWM 输出 | 程序启动,RGB 白色闪烁,等待传感器稳定 |
loop() | 持续检测 PIR 状态并切换灯光 | 无人时蓝色,有人移动时黄色 |
KeyboardInterrupt处理 | 捕获手动停止程序 | 程序停止时关闭 RGB LED |
主循环中的last_state = -1用于记录上一次 PIR 状态。程序每隔 200 毫秒读取一次current_state,只有当前状态和上一次状态不同时,才执行闪烁和颜色切换。这样的写法避免 RGB 灯在同一状态下反复闪烁,也让状态变化更加清晰。PIR 检测到人体移动时,程序打印提示信息,RGB 灯黄色闪烁三次后保持黄色;未检测到人体移动时,RGB 灯蓝色闪烁两次后保持蓝色。
扩展应用
PIR 人体热释电传感器实验经常遇到初始化等待、误触发、颜色反相、灯不亮等问题。排查时可以从供电、信号线、引脚映射、RGB 模块类型和传感器稳定时间几个方向判断。
| 问题现象 | 可能原因 | 处理思路 |
|---|---|---|
| 程序启动后 PIR 状态不稳定 | PIR 模块上电后需要预热稳定 | 保留代码中的time.sleep_ms(3000),必要时把等待时间适当加长 |
| RGB 灯颜色与预期相反 | RGB 模块可能是共阳类型 | 将RGB_COMMON_ANODE = False改成RGB_COMMON_ANODE = True |
| RGB 灯完全不亮 | RGB 三色引脚接线错误、PWM 引脚不匹配、供电异常 | 核对 IO6、IO7、IO8 与 RGB Red、Green、Blue 的连接,单独测试set_color(0xFF0000)等颜色 |
| PIR 一直显示检测到人体移动 | OUT 信号受环境干扰、传感器附近持续有人移动、模块灵敏度较高 | 保持传感器前方无遮挡,远离热源和强气流,等待稳定后再观察 |
| PIR 一直没有触发 | PIR OUT 未接到 IO10、供电不正确、人体移动幅度不足 | 核对 PIR VCC、GND、OUT 接线,确认 IO10 映射到GPIOHS0,在传感器前方进行明显移动 |
| 状态变化时 RGB 频繁闪烁 | PIR 输出信号抖动或环境变化明显 | 增加检测间隔,或在loop()中加入更严格的状态确认逻辑 |
| 程序停止后灯还亮 | 没有通过键盘中断正常退出,或异常未被捕获 | 使用当前代码的KeyboardInterrupt方式退出,必要时扩展通用异常处理并关闭 RGB |
| 只有一种颜色正常 | RGB 某一路接线错误或 PWM 通道异常 | 分别测试红、绿、蓝三种颜色,定位具体通道 |
PIR 实验的价值不只是读取一个高低电平,而是建立“环境变化触发程序响应”的硬件交互模式。PIR 传感器提供人体移动输入,程序负责判断状态变化,RGB LED 负责输出可见反馈。这个结构可以自然迁移到安防提醒、节能控制、无人值守设备、展厅互动和教学演示等场景中。
更多应用可以围绕“检测到人体移动”和“未检测到人体移动”两个状态继续扩展。当前 Demo 使用 RGB 灯作为反馈,后续也可以把状态变化连接到蜂鸣器、继电器、LCD、摄像头或网络消息模块。
| 应用场景 | 实现思路 | 可扩展能力 |
|---|---|---|
| 楼道感应灯 | PIR 检测到人体移动后切换为亮灯状态,无人时进入待机状态 | 后续可扩展继电器或大功率灯带控制 |
| 桌面安防提醒 | 人体移动触发黄色或红色提示灯,用于表示有人靠近设备 | 可扩展蜂鸣器或消息推送,实现声光提醒 |
| 无人值守设备唤醒 | 无人时保持低功耗提示状态,有人靠近时切换运行状态 | 可扩展屏幕显示或摄像头识别,形成完整交互流程 |
| 展厅互动装置 | 人体靠近时改变灯光颜色,增强装置反馈感 | 可扩展多组 RGB 灯效和动画切换 |
| 教学演示实验 | 使用 PIR 输入解释 GPIO 输入、状态判断和 PWM 输出 | 可把传感器输入、条件分支和灯光反馈放在同一实验中讲解 |
| 设备状态指示 | 蓝色表示待机,黄色表示检测到活动,红色可预留给异常状态 | 可扩展更多状态颜色和错误处理逻辑 |
| 智能家居联动 | PIR 作为人体存在变化入口,RGB LED 作为状态提示 | 后续可扩展网络通信和远程控制 |
从工程结构看,当前代码已经具备较好的扩展基础。颜色常量集中管理,RGB 引脚集中配置,PIR 读取被封装成read_pir(),状态变化逻辑集中在loop()中。新增状态时,可以增加新的颜色常量;更换 RGB 接线时,只需要修改RGB_PINS;接入更多反馈设备时,可以在状态变化分支中加入新的函数调用。这样的结构比把所有控制代码写在一个循环里更清晰,也更适合后续课程继续扩展。
总结
本实验通过 CanMV K210 / MaixPy 完成了 PIR 人体热释电传感器检测和 RGB LED 状态反馈,核心能力包括 FPIOA 引脚映射、GPIO 输入读取、PWM 输出控制、Timer 定时器通道配置、RGB 颜色拆分、占空比映射、函数封装和状态变化判断。PIR 传感器把人体移动转换成电平信号,程序读取电平后通过 RGB 灯显示不同状态,形成了一条完整的硬件感知与反馈链路。
这类实验很适合放在智能硬件入门阶段。GPIO 输入让程序能够感知外部环境,PWM 输出让硬件反馈不再只有简单亮灭,状态变量让系统只在变化时执行提示动作。后续课程可以在这个基础上继续扩展按键控制、蜂鸣器报警、LCD 状态显示、摄像头识别、传感器数据采集和网络消息推送。理解了“传感器输入、程序判断、硬件反馈”这条主线,更多 AI 硬件交互项目都可以围绕同一套思路继续搭建。