Skip to main content

60GHz 毫米波传感器 - 人体静态睡眠呼吸监测 (MR60BHA1)

介绍

MR60BHA1 60GHz 雷达模块采用 FMCW 检测理论,实现高精度的个人呼吸频率和心率同时检测,提供完全私密和安全的环境,不受其他噪声干扰的影响。它是消费电子、医疗保健以及工业应用中的标准生物雷达系统。在本 wiki 中,我们将向您介绍如何使用它。

应用

  • 智能家居
  • 医疗保健
  • 呼吸频率检测
  • 心跳频率检测
  • 智能酒店
  • 医疗助手

特性

  • 使能理论:基于 FMCW FM 连续波信号实现雷达检测
  • 标准算法:在自适应环境中感知并同时输出人体呼吸频率和心律
  • 完美的隐私保护:应用 FMCW 监测技术提供无需身份识别的监控能力
  • 健康友好的工作状态:输出功率低至对人体无害
  • 高稳定性:不受温度、湿度、噪声、气流、灰尘、光线和其他环境因素影响
  • 高测量精度:心跳精度达到 85%,呼吸精度达到 90%
  • 高灵活性硬件设计雷达:支持二次开发,适应各种场景应用

规格

参数内容最小值典型值最大值单位
性能
检测距离(胸部)0.41.5m
呼吸测量精度90%
心跳测量精度95%
刷新时间130S
观测建立时间20S
工作参数
工作电压 (VCC)4.656V
工作电流 (ICC)150mA
工作温度 (TOP)-2060
存储温度 (TST)-4080
发射参数
工作频率 (fTX)586063.5GHz
发射功率 (Pout)6dBm
天线参数
天线增益 (GANT)4dBi
水平波束 (-3dB)-2020o
垂直波束 (-3dB)-2020o

硬件概述

在一切开始之前,了解产品的一些基本参数是非常重要的。下表提供了60GHz毫米波呼吸心跳模块特性的信息。

  • 接口1:
    • 5V引脚是传感器的电源接口。
    • RX和TX是传感器的数据传输接口。RX表示串行接收,TX表示串行发送。
    • 人体存在状态输出接口。您可以使用这两个引脚的电平来判断环境中当前的人体运动状态。
      • GP2输出:高电平 - 有人,低电平 - 无人。
      • GP1输出:高电平 - 活动,低电平 - 静止。
  • 接口2:
    • 烧录固件引脚:GND/3.3V/SWD/SWC。
    • 预留输入/输出引脚:GP3~GP6。

入门指南

固件版本更新

毫米波传感器经过了长期的技术沉淀和用户提供的宝贵建议,我们一直在对原有产品进行迭代,以提供更准确可靠的监测结果和更好的用户体验。

新出货的传感器默认搭载最新固件,以确保最新的产品体验。但是,为了老用户的体验,我们在此提供最新固件和更新方法,确保您能够使用我们的最新技术。

通用方法 - 使用J-link烧录固件

如果您遇到固件错误或雷达异常、固件故障等问题,使用此方法重新烧录固件是最有效的方式。

最新固件下载

固件版本下载地址
Jlink_MR60BHA1-V230104.bin下载
Jlink_MR60BHA1-V230904.bin下载
caution
  1. 请仔细检查您产品的功能,请不要与其他毫米波传感器混用来烧录此固件,否则可能导致产品功能异常,后果需要您自行承担!

  2. 还请注意,不同的固件更新方式使用不同的固件内容,您下载的是通过J-link烧录的固件。

将您的雷达更新到最新版本

步骤1. 您需要准备一个JlinkMR60BHA1 60GHz毫米波传感器。

通过杜邦线将雷达和Jlink连接在一起,如下图所示。

步骤2. 下载必要的软件和固件。

文件下载地址
JlinkV644e.rar下载
Pack_Segger_AT32F4xx_v1.3.3.zip下载

步骤3. 解压JlinkV644e.rar并打开其中的JLink_Windows_V644e.exe文件。

按照默认选项安装即可。安装完成后,启动J-Flash V6.44e软件。

步骤4. 安装芯片包。

解压Pack_Segger_AT32F4xx_v1.3.3.zip并打开其中的Segger_AT32F4xx_AddOn.exe

步骤5. 创建新项目。

找到并选择AT32F403ARGT7

步骤6. 将雷达固件(.bin文件)拖拽到此软件中,会弹出一个窗口,我们使用其默认起始地址0x8000000即可。

步骤7. 点击Target -> Connect

连接成功时会显示Connected successfully。

擦除固件:Target -> manual Programming -> Erase Chip

升级固件:Target -> manual Programming -> Program & Verify

至此,固件更新完成。

通过UART更新固件

考虑到J-link价格昂贵,对于绝大多数只需要更新雷达固件的用户来说,购买J-link过于奢侈,因此我们提供通过UART的更新方法。

最新固件下载

固件版本下载地址
UART_MR60BHA1-230104.bin下载
UART_MR60BHA1-230904.bin下载
caution
  1. 请仔细检查您产品的功能,请不要与其他毫米波传感器混用来烧录此固件,否则可能导致产品功能异常,后果需要您自行承担!

  2. 还请注意,不同的固件更新方式使用不同的固件内容,您下载的是通过UART烧录的固件。

  3. 确保您的雷达固件版本至少为 G60SM1SYv010003 版本,然后再使用 UART 升级固件,否则可能会导致雷达失效,此时您必须使用 J-link 烧录固件才能使用!

您可以通过向雷达发送命令 0x53 0x59 0x02 0xA4 0x00 0x01 0x0F 0x62 0x54 0x43 来查询固件版本号信息。然后雷达上报的数据以字符串形式显示,您将看到类似下图所示的效果。

G60SM1SYv010009 是雷达上报的型号,其中 10009 是版本号。这意味着该传感器支持 UART 升级。

将您的雷达更新到最新版本

步骤 1. 您需要准备一个 UART 转 USBMR60BHA1 60GHz 毫米波传感器。

通过杜邦线将雷达和 UART 转 USB 连接在一起,如下图所示。

步骤 2. 下载必要的软件和固件。

文件下载地址
PackageMake-v1.1.1.zip下载

步骤 3. 解压 PackageMake-v1.1.1.zip 包并打开其中的 PackageMake-v1.1.1.exe 文件。

将连接传感器的 UART 转 USB 连接到计算机,点击软件左上角的齿轮图案,选择端口号,将波特率设置为 115200,然后点击右下角确认。(如果找不到端口号,请检查连接,然后点击左下角的刷新按钮重试)

步骤 4. 连接传感器

按照上述方法完成串口设置后,点击右上角的第二个图标,如果端口选择正确,您将看到雷达的原始数据被打印出来。

步骤 5. 更新固件

左键点击右上角的最后一个图标,这将弹出一个选择固件的窗口。请选择您已下载的固件版本。

选择完成后,所选文件路径将出现在软件下方,请仔细检查所选固件版本和型号是否与您使用的传感器一致。

要升级固件,请左键双击软件左上角的最后一个图像,然后固件将开始下载到传感器。

等待进度条完成,固件更新即完成。

上位机的使用

通过 UART 转 USB 设备将传感器直接连接到计算机的 USB 端口。接线如下表所示。

UART 转 USBMR60BHA1 传感器
5V-->5V
GND-->GND
RX-->TX
TX-->RX

除了上述串口软件外,您还可以直接使用专为雷达设计的上位机软件

tip

如果您使用的是较旧版本的上位机和固件,请尽快升级到最新版本,以确保您能够享受软件协议和 Wiki 内容。

以下五个部分解释了软件各部分的作用。

  1. 连接设置

    选择传感器连接到计算机的端口。通常需要先点击刷新串口按钮刷新端口,然后再选择。一旦串口选择正确,数据会自动在圆圈 4 中更新(如果有可用数据)。

  2. 功能设置

    • 调试:当此功能开启时,可以在软件中输出实时原始数据。这是图中圆圈 3 的窗口。
    • 保存原始数据:当您点击它时,可以选择将原始数据保存到本地计算机。但是请注意,此选项不会在点击按钮后保存新数据,只保存最近的历史数据。
    • 保存睡眠数据:当您点击它时,可以选择保存与睡眠相关的原始数据信息的路径,而其他数据不会被保存。但是请注意,此选项不会在点击按钮后保存新数据,只保存最近的历史数据。
  3. 串口监视器

    当在圆圈2中勾选调试选项时,会出现此窗口,此时该区域显示实时传感器数据帧。在底部您可以向传感器发送命令帧。可以发送或查询的命令可以在传感器的用户手册中找到。

  4. 图形显示

    这里实时显示折线图。显示的数据内容分别是呼吸频率、心率和身体参数。横坐标是时间,纵坐标是对应的数据。

  5. 状态和方向

    此区域允许您观察人体存在状态和人体方向。人体方向数据仅供参考。

使用Arduino进行传感器开发

Arduino库概述

tip

如果这是您第一次使用Arduino,我们强烈建议您参考Arduino入门指南

本示例中使用的库代码可以通过点击下面的图标下载。

功能

在我们开始开发草图之前,让我们看看库的可用功能。

  • void recvRadarBytes() —— 此函数根据传感器数据协议中的帧头和帧尾,通过UART收集传感器报告的数据帧。与showData()函数结合使用,可以通过串口打印出收集的数据信息。

    • 输入参数:

    • 返回值:

  • void showData() —— 此函数用于通过串口一次性打印出传感器报告的完整数据帧,需要与recvRadarBytes()函数结合使用。

    • 输入参数:

    • 返回值:

  • void HumanExis_Func() —— 此函数负责解析传感器的数据帧,并输出有关人体存在状态的相关数据。

    • 输入参数:

    • 返回值:

      • unsigned int sensor_report —— 返回值表示解析的数据帧属于哪个状态类别。具体类别可以在默认变量部分找到。人体运动信息仅在发生变化时报告。

      • int bodysign_val —— 返回值表示人体运动参数的值。此值每秒报告一次。

      • float distance —— 传感器确定当前到人体的距离,值以米为单位。此值每2秒报告一次。

      • float Dir_x, Dir_y, Dir_z —— 表示传感器检测到的身体位置信息。人体位置信息有正负值,单位为米。此值每2秒报告一次。

  • void Breath_Heart() —— 此函数负责解析来自传感器的呼吸和心跳数据,并返回相关值。

    • 输入参数:

    • 返回值:

      • unsigned int sensor_report —— 返回值表示解析的数据帧属于哪个状态类别。具体类别可以在默认变量部分找到。

      • unsigned int heart_rate —— 心率值。每3秒报告一次。值范围0~100。

      • unsigned int heart_point_1, heart_point_2, heart_point_3, heart_point_4, heart_point_5 —— 心率波形数据。5个字节实时表示1秒内的5个值,波形是正弦波数据,中心轴是128,这意味着当心率强度为0时,将显示为128。此值每秒报告一次。

      • unsigned int breath_rate —— 呼吸值。每3秒报告一次。值范围0~20。

      • unsigned int breath_point_1, breath_point_2, breath_point_3, breath_point_4, breath_point_5 —— 呼吸频率波形数据。5个字节实时表示1秒内的5个值,波形是正弦波数据,中心轴是128,这意味着当心率强度为0时,将显示为128。此值每秒报告一次。

  • void SleepInf_Decode() —— 此函数负责解析传感器报告的睡眠数据信息。仅在被监测人员已进入床上并已睡眠超过五分钟时有效。使用此函数时请确保启用睡眠状态转换模式。

    • 输入参数:

    • 返回值:

      • unsigned int sensor_report —— 返回值表示解析的数据帧属于哪个状态类别。具体类别可以在默认变量部分找到。

      • unsigned int awake_time —— 如果被监测人员已上床,此值表示被监测人员的清醒时间。此值将每十分钟与其他睡眠状态数据一起报告。

      • unsigned int light_time —— 如果被监测人员已在床上,此值表示被监测人员的浅睡眠时间。此值将每十分钟与其他睡眠状态数据一起报告。

      • unsigned int deep_time —— 如果被监测人员已在床上,此值表示被监测人员的深睡眠时间。此值将每十分钟与其他睡眠状态数据一起报告。

      • unsigned int sleep_score —— 此值表示睡眠质量评分。此信息在睡眠过程结束时报告。

  • boolean existence —— 该值表示人体存在信息。返回结果为 True 表示有人存在,返回结果为 False 表示无人存在。该值将每十分钟与其他睡眠状态数据一起上报。

    • unsigned int sleep_status —— 该值表示睡眠状态。有四种睡眠状态,即离床、清醒、浅睡和深睡。该值将每十分钟与其他睡眠状态数据一起上报。

    • unsigned int breath_rate —— 10分钟内的平均心跳。该值将每十分钟与其他睡眠状态数据一起上报。

    • unsigned int heart_rate —— 十分钟内的平均呼吸。该值将每十分钟与其他睡眠状态数据一起上报。

    • unsigned int turn_num —— 十分钟内的翻身次数。该值将每十分钟与其他睡眠状态数据一起上报。

    • unsigned int substantial_move_ratio —— 十分钟内人物大幅度运动所占比例。该值将每十分钟与其他睡眠状态数据一起上报。

    • unsigned int samll_move_ratio —— 十分钟内人物小幅度运动的百分比。该值将每十分钟与其他睡眠状态数据一起上报。

    • unsigned int apnea_num —— 十分钟内的呼吸暂停次数。该值将每十分钟与其他睡眠状态数据一起上报。

    • unsigned int sleep_time —— 总睡眠时长。当传感器判断睡眠过程结束时上报。

    • unsigned int awake_time_radio —— 人处于清醒状态的时间百分比。当传感器判断睡眠过程结束时上报。

    • unsigned int light_time_radio —— 浅睡时间的百分比。当传感器判断睡眠过程结束时上报。

    • unsigned int deep_time_radio —— 深睡时间的百分比。当传感器判断睡眠过程结束时上报。

    • unsigned int outbed_time —— 人离床的时间长度。当传感器判断睡眠过程结束时上报。

    • unsigned int outbed_num —— 人离床的次数。当传感器判断睡眠过程结束时上报。

  • void send_func(const unsigned char* buff, int len, bool cyclic /*=false*/) —— 该函数用于发送查询帧和命令帧。

    • 输入参数:

      • buff —— 您想要发送给传感器的数据帧。

      • len —— 您想要发送给传感器的数据帧长度。

      • cyclic —— 循环发送开关。默认为 false,如果您希望循环发送此数据帧,可以设置为 true

    • 返回值:

  • void ModeSelect_fuc(int mode) —— 该函数用于选择传感器的工作模式。有两种工作模式,睡眠状态传输模式和实时数据传输模式。在睡眠状态传输模式下,睡眠监测功能开启(SleepInf_Decode() 有效)。在实时数据传输模式下,睡眠监测功能关闭(SleepInf_Decode() 无效),但会上报波形数据。

    • 输入参数:

      • mode —— 选择的模式编号。1 表示实时数据传输模式,2 表示睡眠状态传输模式。
    • 返回值:

  • void reset_func() —— 该函数用于重置传感器。

    • 输入参数:

    • 返回值:

默认变量

#define MESSAGE_HEAD1 0x53      //数据帧头1
#define MESSAGE_HEAD2 0x59 //数据帧头2

#define MESSAGE_END1 0x54 //数据帧结束1
#define MESSAGE_END2 0x43 //数据帧结束2

#define HUMAN_PSE_RADAR 0x80 //人体存在数据

#define PRESENCE_INF 0x01 //存在信息
#define SOMEONE_HERE 0x01 //有人在这里
#define NOONE_HERE 0x00 //没有人在这里

#define MOVE_INF 0x02 //运动信息
#define PSE_NONE 0x00 //无
#define STATIONARY 0x01 //人处于静止状态
#define MOVEMENT 0x02 //人处于运动状态

#define BODY_SIG 0x03 //身体运动信息

#define DISTANCE 0x04 //被检测人员的距离

#define DIRECTIONS 0x05 //身体方向

#define HEART_INF 0x85 //心率信息

#define HEART_RATE 0x02 //心率

#define HEART_RATE_WAVE 0x05 //心率波形(暂不分析)

#define BREATH_RATE_RADAR 0x81 //呼吸心率数据

#define BREATH_INF 0x01 //呼吸数据
#define BREATH_NORMAL 0x01 //正常呼吸
#define BREATH_RAPID 0x02 //急性呼吸异常
#define BREATH_SLOW 0x03 //心跳缓慢
#define BREATH_NONE 0x04 //雷达检测无

#define BREATH_VAL 0x02 //呼吸值

#define BREATH_WAVE 0x05 //呼吸波形(暂不分析)

#define SLEEP_INF 0x84 //睡眠信息

#define INOUT_BED 0x01 //在床或离床
#define OUT_BED 0x00 //离床
#define IN_BED 0x01 //在床
#define INOUT_NONE 0x02 //无(实时检测模式下显示)

#define SLEEP_STATE 0x02 //睡眠状态
#define DEEP_SLEEP 0x00 //深度睡眠
#define LIGHT_SLEEP 0x01 //浅度睡眠
#define AWAKE 0x02 //清醒
#define SLEEP_NONE 0x03 //无(实时检测模式下显示)

#define AWAKE_TIME 0x03 //清醒时间

#define LIGHTSLEEP_TIME 0x04 //浅睡眠时间

#define DEEPSLEEP_TIME 0x05 //深睡眠时间

#define SLEEP_SCORE 0x06 //睡眠质量评分

#define SLEEP_STATUE 0x0C //睡眠综合状态报告

#define SLEEP_QUALITY 0x0D //睡眠质量综合信息报告

#define SLEEP_ERROR 0x0E //异常睡眠报告

#define SLEEP_LESS4H 0x00 //睡眠少于4小时
#define SLEEP_OVER12H 0x01 //睡眠超过12小时
#define SLEEP_LONGTIMENOONE 0x02 //异常情况,长时间无人
#define SLEEP_ERRORNONE 0x03 //无

#define reset_frame_len 10 //重置数据帧长度
//重置数据帧
const unsigned char breath_reset_frame[10] = {0x53, 0x59, 0x01, 0x02, 0x00, 0x01, 0x0F, 0xBF, 0x54, 0x43};

#define mode_frame_len 10 //模式选择命令帧长度
//模式选择命令帧
const unsigned char realtime_mode_frame[10] = {0x53, 0x59, 0x84, 0x0F, 0x00, 0x01, 0x00, 0x40, 0x54, 0x43};
const unsigned char sleepstatus_mode_frame[10] = {0x53, 0x59, 0x84, 0x0F, 0x00, 0x01, 0x01, 0x41, 0x54, 0x43};

//返回状态,在arduino中使用
//sensor_report的可能值
#define NOONE 0x01
#define SOMEONE 0x02
#define NONEPSE 0x03
#define STATION 0x04
#define MOVE 0x05
#define BODYVAL 0x06
#define DISVAL 0x07
#define DIREVAL 0x08

#define HEARTRATEVAL 0x09
#define HEARTRATEWAVE 0x10
#define BREATHNOR 0x11
#define BREATHRAPID 0x12
#define BREATHSLOW 0x13
#define BREATHNONE 0x14
#define BREATHVAL 0x15
#define BREATHWAVE 0x16

#define OUTBED 0x17
#define INBED 0x18
#define NOINOUT 0x19
#define SLEEPAWAKE 0x20
#define SLEEPLIGHT 0x21
#define SLEEPDEEP 0x22
#define SLEEPNONE 0x23
#define AWAKETIME 0x24
#define LIGHTTIME 0x25
#define DEEPTIME 0x26
#define SLEEPSCORE 0x27
#define SLEEPSTATUE 0x28
#define SLEEPQUALITY 0x29
#define SLEEPLESS4H 0x30
#define SLEEPOVER12H 0x31
#define LONGTIMENOONE 0x32
#define ERRORNONE 0x33


unsigned int sensor_report = 0, bodysign_val = 0, awake_time = 0, light_time = 0, deep_time = 0, sleep_score = 0, turn_num = 0;
unsigned int heart_rate = 0, heart_point_1 = 0, heart_point_2 = 0, heart_point_3 = 0, heart_point_4 = 0, heart_point_5 = 0;
unsigned int breath_rate = 0, breath_point_1 = 0, breath_point_2 = 0, breath_point_3 = 0, breath_point_4 = 0, breath_point_5 = 0;
unsigned int substantial_move_ratio = 0, samll_move_ratio = 0, apnea_num = 0, sleep_status = 0, sleep_time = 0;
unsigned int awake_time_radio = 0, light_time_radio = 0, deep_time_radio = 0;
unsigned int outbed_time = 0, outbed_num = 0;
float distance = 0;
float Dir_x = 0, Dir_y = 0, Dir_z = 0;
boolean existence;

安装

步骤 1. 您需要安装 Arduino 软件。

步骤 2. 启动 Arduino 应用程序。

步骤 3. 选择您的开发板型号并将其添加到 Arduino IDE 中。

  • 如果您想在后续教程中使用 Seeeduino V4.2,请参考此教程完成添加。

  • 如果您想在后续教程中使用 Seeeduino XIAO,请参考此教程完成添加。

  • 如果您想在后续教程中使用 XIAO RP2040,请参考此教程完成添加。

  • 如果您想在后续教程中使用 XIAO BLE,请参考此教程完成添加。

  • 如果您想在后续教程中使用 XIAO ESP32C3,请参考此教程完成添加。

caution

对于 XIAO nRF52840,请选择 Seeed nRF52 mbed-enabled Boards,否则运行程序时可能会报错。

步骤 4. 安装 Arduino 代码库。

首先从 GitHub 获取代码库并下载到您的本地计算机。

由于您已经下载了 zip 库文件,请打开您的 Arduino IDE,点击 Sketch > Include Library > Add .ZIP Library。选择您刚刚下载的 zip 文件,如果库安装正确,您将在通知窗口中看到 Library added to your libraries。这意味着库已成功安装。

Arduino 示例

现在我们已经安装了库并了解了基本功能,让我们为 XIAO BLE 运行一些示例,看看它的表现如何。

所需材料

在完成以下示例之前,您需要准备以下材料。

60GHz MR60BHA1 传感器Seeed XIAO BLE nRF52840 Sense2mm 到 2.54mm 间距排线

步骤 1. 通过主板将设备连接到计算机。接线图如下表所示。

Seeed Studio XIAO nRF52840MR60BHA1 传感器
5V-->5V
GND-->GND
RX-->D6
TX-->D7

步骤 2. 在 Arduino IDE 左上角的菜单栏中,选择 tool,选择您正在使用的开发板类型,并选择相应的串口。

tip

如果您使用的是 MacOS,设备的串口名称通常以 /dev/cu.usbmodem xxx 开头,以设备名称结尾。如果您使用的是 Windows,设备的串口名称通常以 COM 开头,同样以设备名称结尾。

在此示例中,我们将演示雷达如何与我们的热门产品 XIAO BLE 配合工作。

演示1 原始数据导出

此示例将指导您完成通过串口打印传感器报告的原始数据的过程。

以下示例程序位于库的 examples 文件夹中,名为 MR60BHA1_print_rawdata

#include "Arduino.h"
#include <60ghzbreathheart.h>

//#include <SoftwareSerial.h>
// 选择任意两个可以与SoftwareSerial一起用于RX和TX的引脚
//#define RX_Pin A2
//#define TX_Pin A3

//SoftwareSerial mySerial = SoftwareSerial(RX_Pin, TX_Pin);

// 我们将使用软件串口
//BreathHeart_60GHz radar = BreathHeart_60GHz(&mySerial);

// 也可以尝试硬件串口
BreathHeart_60GHz radar = BreathHeart_60GHz(&Serial1);

void setup() {
// 将你的设置代码放在这里,只运行一次:
Serial.begin(115200);
Serial1.begin(115200);

// mySerial.begin(115200);

while(!Serial); //当串口打开时,程序开始执行。

Serial.println("Readly");
}

void loop()
{
// 将你的主要代码放在这里,重复运行:
radar.recvRadarBytes(); //接收雷达数据并开始处理
radar.showData(); //串口打印一组接收到的数据帧
delay(200); //添加时间延迟以避免程序卡死
}
tip

如果您使用的是 XIAO ESP32 系列,并且毫米波雷达没有数据反馈。您可以尝试将上面的代码从

Serial1.begin(115200); 改为 Serial1.begin(115200, SERIAL_8N1, D7, D6);

在这个程序中,我们使用 XIAO nRF52840 的硬件 Serial1 端口连接到传感器,并使用硬件 Serial 端口 Serial 输出数据,因此我们需要在初始化函数 Setup() 中单独初始化这个串口。

在主 loop() 函数中,我们使用函数 recvRadarBytes() 从传感器接收数据帧,然后使用 showData() 函数通过串口打印出接收到的数据帧。

在这个程序中,需要注意的是,每两个数据帧的接收和输出之间都有一个间隔,以避免主板出现阻塞。这个时间应该不少于 150ms

这意味着主板无法接收传感器报告的所有数据帧,但由于传感器报告的帧数非常大且频繁,这不会影响使用传感器判断环境的准确性。

上传程序。将串口监视器的波特率设置为 115200 应该会显示结果。输出应该类似于下图。

Demo2: 人体存在检测功能的使用

在这个示例中,我们将解释如何使用人体存在检测功能,并通过串口监视器打印出该功能中所有值的信息。

以下示例程序位于库的 examples 文件夹中,名为 MR60BHA1_human_existence_inf_output

#include "Arduino.h"
#include <60ghzbreathheart.h>

//#include <SoftwareSerial.h>
// 选择任意两个可以与SoftwareSerial一起使用的引脚作为RX和TX
//#define RX_Pin A2
//#define TX_Pin A3

//SoftwareSerial mySerial = SoftwareSerial(RX_Pin, TX_Pin);

// 我们将使用软件串口
//BreathHeart_60GHz radar = BreathHeart_60GHz(&mySerial);

// 也可以尝试硬件串口
BreathHeart_60GHz radar = BreathHeart_60GHz(&Serial1);

void setup() {
// 在这里放置您的设置代码,只运行一次:
Serial.begin(115200);
Serial1.begin(115200);

// mySerial.begin(115200);

while(!Serial); //当串口打开时,程序开始执行。

Serial.println("Readly");
}

void loop()
{
// 在这里放置您的主要代码,重复运行:
radar.HumanExis_Func(); //人体存在信息输出
if(radar.sensor_report != 0x00){
switch(radar.sensor_report){
case NOONE:
Serial.println("Nobody here.");
Serial.println("----------------------------");
break;
case SOMEONE:
Serial.println("Someone is here.");
Serial.println("----------------------------");
break;
case NONEPSE:
Serial.println("No human activity messages.");
Serial.println("----------------------------");
break;
case STATION:
Serial.println("Someone stop");
Serial.println("----------------------------");
break;
case MOVE:
Serial.println("Someone moving");
Serial.println("----------------------------");
break;
case BODYVAL:
Serial.print("The parameters of human body signs are: ");
Serial.println(radar.bodysign_val, DEC);
Serial.println("----------------------------");
break;
case DISVAL:
Serial.print("The sensor judges the distance to the human body to be: ");
Serial.print(radar.distance, DEC);
Serial.println(" m");
Serial.println("----------------------------");
break;
case DIREVAL:
Serial.print("The sensor judges the orientation data with the human body as -- x: ");
Serial.print(radar.Dir_x);
Serial.print(" m, y: ");
Serial.print(radar.Dir_y);
Serial.print(" m, z: ");
Serial.print(radar.Dir_z);
Serial.println(" m");
Serial.println("----------------------------");
break;
}
}
delay(200); //添加时间延迟以避免程序卡死
}

tip

如果您使用的是XIAO ESP32系列,并且毫米波雷达没有数据反馈。您可以尝试将上面的代码从Serial1.begin(115200);更改为Serial1.begin(115200, SERIAL_8N1, D7, D6);

在这个示例中,检测人体存在的功能是通过HumanExis_Func()函数实现的。程序实现的基本逻辑是HumanExis_Func()函数将传感器报告的状态信息分配给sensor_report变量。基于sensor_report的值,我们然后通过串口打印出该状态下的所有值。

请注意,sensor_report对应于缩进下串口的数据输出。例如,表示体征参数的bodysign_val变量仅在sensor_reportBODYVAL时有效,在传感器报告的其他sensor_reports中不存在。

上传程序。将串口监视器的波特率设置为115200应该会显示结果。输出应该类似于下图。

演示3:静止人员呼吸和心跳功能的使用

在这个示例中,我们将使用Breath_Heart()函数来检测静止人体的呼吸和心率。

tip

我们的重点是检测静止人体的呼吸和心率。请不要在人体运动时使用该产品,因为我们对传感器的心率和呼吸进行了限制。最大心率不会超过100,最大呼吸频率不会超过25

以下示例程序位于库的examples文件夹中,名为MR60BHA1_Breath_heartbeat_inf_output

#include "Arduino.h"
#include <60ghzbreathheart.h>

//#include <SoftwareSerial.h>
// Choose any two pins that can be used with SoftwareSerial to RX & TX
//#define RX_Pin A2
//#define TX_Pin A3

//SoftwareSerial mySerial = SoftwareSerial(RX_Pin, TX_Pin);

// we'll be using software serial
//BreathHeart_60GHz radar = BreathHeart_60GHz(&mySerial);

// can also try hardware serial with
BreathHeart_60GHz radar = BreathHeart_60GHz(&Serial1);

void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
Serial1.begin(115200);

// mySerial.begin(115200);

while(!Serial); //When the serial port is opened, the program starts to execute.

Serial.println("Readly");

// radar.ModeSelect_fuc(1); //1: indicates real-time transmission mode, 2: indicates sleep state mode.
//After setting the mode, if you do not see data returned, you may need to re-power the sensor.
}

void loop()
{
// put your main code here, to run repeatedly:
radar.Breath_Heart(); //Breath and heartbeat information output
if(radar.sensor_report != 0x00){
switch(radar.sensor_report){
case HEARTRATEVAL:
Serial.print("传感器监测到的当前心率值为: ");
Serial.println(radar.heart_rate, DEC);
Serial.println("----------------------------");
break;
case HEARTRATEWAVE: //Valid only when real-time data transfer mode is on
Serial.print("心率波形(正弦波) -- 点 1: ");
Serial.print(radar.heart_point_1);
Serial.print(", 点 2 : ");
Serial.print(radar.heart_point_2);
Serial.print(", 点 3 : ");
Serial.print(radar.heart_point_3);
Serial.print(", 点 4 : ");
Serial.print(radar.heart_point_4);
Serial.print(", 点 5 : ");
Serial.println(radar.heart_point_5);
Serial.println("----------------------------");
break;
case BREATHNOR:
Serial.println("传感器检测到当前呼吸频率正常。");
Serial.println("----------------------------");
break;
case BREATHRAPID:
Serial.println("传感器检测到当前呼吸频率过快。");
Serial.println("----------------------------");
break;
case BREATHSLOW:
Serial.println("传感器检测到当前呼吸频率过慢。");
Serial.println("----------------------------");
break;
case BREATHNONE:
Serial.println("暂无呼吸信息,请等待...");
Serial.println("----------------------------");
break;
case BREATHVAL:
Serial.print("传感器监测到的当前呼吸频率值为: ");
Serial.println(radar.breath_rate, DEC);
Serial.println("----------------------------");
break;
case BREATHWAVE: //Valid only when real-time data transfer mode is on
Serial.print("呼吸频率波形(正弦波) -- 点 1: ");
Serial.print(radar.breath_point_1);
Serial.print(", 点 2 : ");
Serial.print(radar.breath_point_2);
Serial.print(", 点 3 : ");
Serial.print(radar.breath_point_3);
Serial.print(", 点 4 : ");
Serial.print(radar.breath_point_4);
Serial.print(", 点 5 : ");
Serial.println(radar.breath_point_5);
Serial.println("----------------------------");
break;
}
}
delay(200); //Add time delay to avoid program jam
}

tip

如果您使用的是 XIAO ESP32 系列,并且毫米波雷达没有数据反馈。您可以尝试将上面的代码从 Serial1.begin(115200); 更改为 Serial1.begin(115200, SERIAL_8N1, D7, D6);

上传程序。将串口监视器的波特率设置为 115200 应该会显示结果。输出应该类似于下面的图像。

caution

如果您想查看波形数据,请将传感器切换到实时数据传输模式。切换模式后,传感器可能需要重新上电才能生效。

演示4:睡眠功能的使用

在这个示例中,我们将指导您如何使用 SleepInf_Decode() 函数获取睡眠信息。在使用此示例之前,请确保您或测试人员已准备好睡觉。

note

默认情况下,传感器处于睡眠状态传输模式。在此模式下,睡眠监测功能已开启。如果您切换到实时数据传输模式,则可能无法获得睡眠数据。如果您想更改传输模式,可以使用 ModeSelect_fuc() 函数来实现。使用示例也可以在示例文件夹中的 MR60BHA1_Transfer_mode_selection 中找到。切换模式后,传感器可能需要重新上电才能生效。 与睡眠相关的数据需要在人在床上时才会报告,当前固件默认在人员状态持续5分钟后判断有人在床上。

以下示例程序位于库的示例文件夹中,名为 MR60BHA1_Sleep_inf_output

#include "Arduino.h"
#include <60ghzbreathheart.h>

//#include <SoftwareSerial.h>
// 选择任意两个可以与SoftwareSerial一起用于RX和TX的引脚
//#define RX_Pin A2
//#define TX_Pin A3

//SoftwareSerial mySerial = SoftwareSerial(RX_Pin, TX_Pin);

// 我们将使用软件串口
//BreathHeart_60GHz radar = BreathHeart_60GHz(&mySerial);

// 也可以尝试硬件串口
BreathHeart_60GHz radar = BreathHeart_60GHz(&Serial1);

void setup() {
// 将您的设置代码放在这里,运行一次:
Serial.begin(115200);
Serial1.begin(115200);

// mySerial.begin(115200);

while(!Serial); //当串口打开时,程序开始执行。

Serial.println("Readly");
}

void loop()
{
// 将您的主要代码放在这里,重复运行:
radar.SleepInf_Decode(); //睡眠相关信息输出。当监测对象在床上五分钟后开始数据输出。
if(radar.sensor_report != 0x00){
switch(radar.sensor_report){
case OUTBED:
Serial.println("传感器检测到有人正在离开床铺。");
Serial.println("----------------------------");
break;
case INBED:
Serial.println("传感器检测到有人目前在床上。");
Serial.println("----------------------------");
break;
case NOINOUT:
Serial.println("未检测到对象离开或上床。");
Serial.println("----------------------------");
break;
case SLEEPAWAKE:
Serial.println("传感器检测到监测对象处于清醒状态。");
Serial.println("----------------------------");
break;
case SLEEPLIGHT:
Serial.println("传感器检测到监测对象处于浅睡眠状态。");
Serial.println("----------------------------");
break;
case SLEEPDEEP:
Serial.println("传感器检测到监测对象处于深睡眠状态。");
Serial.println("----------------------------");
break;
case SLEEPNONE:
Serial.println("未检测到对象的睡眠状态。");
Serial.println("----------------------------");
break;
case AWAKETIME:
Serial.print("传感器监测到的清醒睡眠时间为:");
Serial.print(radar.awake_time);
Serial.println(" 分钟");
Serial.println("----------------------------");
break;
case LIGHTTIME:
Serial.print("传感器监测到的浅睡眠时间为:");
Serial.print(radar.light_time);
Serial.println(" 分钟");
Serial.println("----------------------------");
break;
case DEEPTIME:
Serial.print("传感器监测到的深睡眠时间为:");
Serial.print(radar.deep_time);
Serial.println(" 分钟");
Serial.println("----------------------------");
break;
case SLEEPSCORE:
Serial.print("传感器判断的睡眠评分为:");
Serial.println(radar.sleep_score);
Serial.println("----------------------------");
break;
case SLEEPSTATUE:
Serial.println("睡眠综合状态信息 -- ");
Serial.print("人体存在:");
if(radar.existence)Serial.println("人体存在");
else Serial.println("人体不存在");
Serial.print("睡眠状态:");
if(radar.sleep_status == SLEEPDEEP)Serial.println("熟睡");
else if(radar.sleep_status == SLEEPLIGHT)Serial.println("浅睡眠");
else if(radar.sleep_status == SLEEPAWAKE)Serial.println("清醒");
else if(radar.sleep_status == SLEEPNONE)Serial.println("离床");
Serial.print("平均呼吸:");
Serial.println(radar.breath_rate);
Serial.print("平均心率:");
Serial.println(radar.heart_rate);
Serial.print("睡眠期间翻身次数:");
Serial.println(radar.turn_num);
Serial.print("睡眠期间大幅运动百分比:");
Serial.println(radar.substantial_move_ratio);
Serial.print("睡眠期间小幅运动百分比:");
Serial.println(radar.samll_move_ratio);
Serial.print("呼吸暂停次数:");
Serial.println(radar.apnea_num);
Serial.println("----------------------------");
break;
case SLEEPQUALITY:
Serial.println("睡眠质量信息 -- ");
Serial.print("睡眠评分:");
Serial.println(radar.sleep_score);
Serial.print("总睡眠时间:");
Serial.print(radar.sleep_time);
Serial.println(" 分钟");
Serial.print("清醒时间百分比:");
Serial.println(radar.awake_time_radio);
Serial.print("浅睡眠时间百分比:");
Serial.println(radar.light_time_radio);
Serial.print("深睡眠时间百分比:");
Serial.println(radar.deep_time_radio);
Serial.print("离床总时间:");
Serial.print(radar.outbed_time);
Serial.println(" 分钟");
Serial.print("离床总次数:");
Serial.println(radar.outbed_num);
Serial.print("睡眠期间翻身次数:");
Serial.println(radar.turn_num);
Serial.print("平均呼吸:");
Serial.println(radar.breath_rate);
Serial.print("平均心率:");
Serial.println(radar.heart_rate);
Serial.print("呼吸暂停次数:");
Serial.println(radar.apnea_num);
Serial.println("----------------------------");
break;
case SLEEPLESS4H:
Serial.print("监测对象睡眠时间少于4小时。");
Serial.println("----------------------------");
break;
case SLEEPOVER12H:
Serial.print("监测对象的睡眠时间超过12小时。");
Serial.println("----------------------------");
break;
case LONGTIMENOONE:
Serial.print("长时间异常无人。");
Serial.println("----------------------------");
break;
case ERRORNONE:
Serial.print("无异常信息。");
Serial.println("----------------------------");
break;
}
}
delay(200); //添加时间延迟以避免程序卡死
}
tip

如果您使用的是 XIAO ESP32 系列,并且毫米波雷达没有数据反馈。您可以尝试将上面的代码从 Serial1.begin(115200); 更改为 Serial1.begin(115200, SERIAL_8N1, D7, D6);

上传程序。将串口监视器的波特率设置为 115200 应该会显示结果。输出应该类似于下面的图像。

Demo5: 向传感器发送数据

根据用户手册中提供的详细信息,用户可以根据实际需要向传感器发送命令帧,以查询或设置传感器的某些状态或模式。

传感器库示例文件夹中名为 MR60BHA1_Send_frame 的 .ino 文件向我们展示了如何发送查询设备 ID 的程序到传感器。

#include "Arduino.h"
#include <60ghzbreathheart.h>

//#include <SoftwareSerial.h>
// 选择任意两个可以与SoftwareSerial一起用于RX和TX的引脚
//#define RX_Pin A2
//#define TX_Pin A3

//SoftwareSerial mySerial = SoftwareSerial(RX_Pin, TX_Pin);

// 我们将使用软件串口
//BreathHeart_60GHz radar = BreathHeart_60GHz(&mySerial);

// 也可以尝试硬件串口
BreathHeart_60GHz radar = BreathHeart_60GHz(&Serial1);

const unsigned char DevID_buff[10] = {0x53, 0x59, 0x02, 0xA1, 0x00, 0x01, 0x0F, 0x5F, 0x54, 0x43};

void setup() {
// 将你的设置代码放在这里,只运行一次:
Serial.begin(115200);
Serial1.begin(115200);

// mySerial.begin(115200);

while(!Serial); //当串口打开时,程序开始执行。

Serial.println("Readly");
}

void loop()
{
// 将你的主要代码放在这里,重复运行:
radar.send_func(DevID_buff, 10, false);
delay(50); //不要将延迟时间设置得太长,因为这可能会影响雷达返回的数据帧的接收。
}
tip

如果您使用的是 XIAO ESP32 系列,并且毫米波雷达没有数据反馈。您可以尝试将上面的代码从 Serial1.begin(115200); 改为 Serial1.begin(115200, SERIAL_8N1, D7, D6);

在这个示例的程序中,您可以看到定义了一个数组 DevID_buff[10],它存储了您查询设备 ID 的十六进制数字,每个位置一个字节。

发送是通过 send_func() 完成的。传入的参数是要发送的帧数组、数组的长度,以及是否循环发送。

如果您需要发送自己的命令帧,那么您需要根据用户手册中提供的帧格式定义正确的数组。

tip

关于校验位"sum"的计算。

所有数据帧都有一个校验位,以确保数据准确发送或接收。校验位通常在数据帧的倒数第二位。它是通过将校验位之前的所有位相加并取十六进制的低两位来计算的。 让我们以查询设备 ID 的数据帧为例。

可以看到校验位在整个数据帧的倒数第二位。然后我们开始将之前的所有十六进制数字相加。

0x53 + 0x59 + 0x02 + 0xA2 + 0x00 + 0x01 + 0x0F = 0x0160

然后我们需要取它的低两位,即 60,所以这个数据帧的校验和是 60。如果我们想查询传感器的 ID,那么您可以定义以下数组。

const unsigned char DevID_buff[10] = {0x53, 0x59, 0x02, 0xA1, 0x00, 0x01, 0x0F, 0x60, 0x54, 0x43};

上传程序。将串行监视器打开并设置波特率为 115200,应该会显示结果。输出应该类似于下面的图像。

此时请检查返回的数据帧,看它们是否与用户手册中描述的返回数据帧匹配。

通常,我们的命令不需要重复发送给传感器,但由于传感器回复消息的速度非常快,我们无法确保能够接收到传感器返回的确切数据消息。这个问题有两种解决方案。

  • 多次重新上传上述程序。
  • send_func() 函数的第三个参数(循环发送)设置为 true。但是请注意,重复发送设置类型的数据帧可能会导致传感器卡死,所以请谨慎使用此功能。如果传感器卡死,请断开传感器的 5V 供电引脚,等待片刻后功能即可恢复。

Demo6: 重置传感器

有时您的传感器可能出现检测异常问题,或者当您想清除传感器上的所有设置时,您可以根据此示例重置传感器。

以下示例程序位于库的示例文件夹中,名为 MR60BHA1_Reset_sensor

#include "Arduino.h"
#include <60ghzbreathheart.h>

//#include <SoftwareSerial.h>
// 选择任意两个可以与SoftwareSerial一起用于RX和TX的引脚
//#define RX_Pin A2
//#define TX_Pin A3

//SoftwareSerial mySerial = SoftwareSerial(RX_Pin, TX_Pin);

// 我们将使用软件串口
//BreathHeart_60GHz radar = BreathHeart_60GHz(&mySerial);

// 也可以尝试硬件串口
BreathHeart_60GHz radar = BreathHeart_60GHz(&Serial1);

void setup() {
// 将您的设置代码放在这里,只运行一次:
Serial.begin(115200);
Serial1.begin(115200);

// mySerial.begin(115200);

while(!Serial); //当串口打开时,程序开始执行。

Serial.println("Readly");

radar.reset_func();
}

void loop()
{
// 将您的主要代码放在这里,重复运行:
}
tip

如果您使用的是 XIAO ESP32 系列,并且毫米波雷达没有数据反馈。您可以尝试将上面的代码从 Serial1.begin(115200); 改为 Serial1.begin(115200, SERIAL_8N1, D7, D6);

重置传感器非常简单,您只需要调用 reset_func()。重置只需要执行一次,所以我们在 Setup() 函数中使用它。

Demo7: 使用 Arduino/Seeeduino

我们的库兼容 Arduino,您也可以选择手头的 Arduino 来开发您的传感器项目。

MR60BHA1 传感器使用 UART 串口通信,您只需要按照下面的接线将传感器连接到您的 Arduino。

MR60BHA1 传感器MCU
5V-->5V
GND-->GND
RX-->软串口 TX
TX-->软串口 RX

所有功能的应用方式与上面的 Demo1 到 Demo6 相同,因此我们不会在此示例中重复它们。在此示例中,我们将为您概述如何使用 Arduino 的软串口从传感器获取数据信息。

tip

有关 Arduino 软串口的说明,请参考 Arduino 官方文档

为了避免同时使用 Serial 进行输出和数据传输而导致的数据混乱,在 Arduino 端我们通常使用软串口。

软串口库的导入和 RX、TX 引脚的定义需要在程序的早期完成。以下程序将 A2A3 引脚定义为软串口的 RXTX 引脚。

#include <SoftwareSerial.h>
//选择任意两个可以与SoftwareSerial一起使用的引脚作为RX和TX
#define RX_Pin A2
#define TX_Pin A3

SoftwareSerial mySerial = SoftwareSerial(RX_Pin, TX_Pin);

//我们将使用软件串口
BreathHeart_60GHz radar = BreathHeart_60GHz(&mySerial);

另外,不要忘记在 Setup() 函数中设置软件串口的波特率。

void setup() {
// put your setup code here, to run once:
Serial.begin(115200);

mySerial.begin(115200);

while(!Serial); //当串口打开时,程序开始执行。

Serial.println("Readly");
}

Demo1为例,如果您想使用Arduino打印传感器上报的数据帧,那么完整的程序如下。

#include "Arduino.h"
#include <60ghzbreathheart.h>

#include <SoftwareSerial.h>
// 选择任意两个可用于SoftwareSerial的RX和TX引脚
#define RX_Pin A2
#define TX_Pin A3

SoftwareSerial mySerial = SoftwareSerial(RX_Pin, TX_Pin);

// 我们将使用软件串口
BreathHeart_60GHz radar = BreathHeart_60GHz(&mySerial);

void setup() {
// put your setup code here, to run once:
Serial.begin(115200);

mySerial.begin(115200);

while(!Serial); //当串口打开时,程序开始执行。

Serial.println("Readly");
}

void loop()
{
// put your main code here, to run repeatedly:
radar.recvRadarBytes(); //接收雷达数据并开始处理
radar.showData(); //串口打印一组接收到的数据帧
delay(200); //添加时间延迟以避免程序卡死
}

Demo8: 直接连接PC获取数据

如果您想使用为传感器设计的上位机,或者想使用串口软件获取完整的数据帧,可以参考此例程。

通过UART转USB设备将传感器直接连接到计算机的USB端口。接线如下表所示。

UART转USBMR60BHA1传感器
5V-->5V
GND-->GND
RX-->TX
TX-->RX

使用串口调试助手等软件选择传感器所在的串口。

caution

MR60BHA1传感器需要5V电源供电,否则传感器可能无法正常工作。

连接成功后,您将看到传感器持续发送消息。

同时,您也可以通过软件的发送功能向传感器发送数据帧。

caution

如果您选择ASCII作为发送数据的格式,每组数据都需要加上0x前缀。如果您选择HEX,那么每组数据不需要加上0x前缀。

故障排除

FAQ1: 这个传感器能否在同一环境中同时检测多个人?

答:不可以。此传感器只能用于单个生物体。如果监测范围内有多个人或动物,这将对监测结果产生影响。

FAQ2: 为什么我在XIAO ESP32C3的串口监视器中看不到任何内容?

XIAO ESP32C3的串口功能与一般Arduino硬件不太一致,直接使用Serial1可能会导致USB串口无法工作。相关应用案例请参考XIAO ESP32C3的串口章节了解详情。

资源

技术支持与产品讨论

感谢您选择我们的产品!我们在这里为您提供不同的支持,以确保您使用我们产品的体验尽可能顺畅。我们提供多种沟通渠道,以满足不同的偏好和需求。

Loading Comments...