limengdu / Seeed-Studio-MR60BHA1-Sensor

MIT License
26 stars 16 forks source link

name: 60GHz mmWave Radar Sensor - Breathing and Heartbeat Module category: bzurl: prodimagename: surveyurl: sku: 101990886 tags:

Introduction

The MR60BHA1 60GHz radar module applies FMCW detected theory to implement simultaneous personal breathing rate and heart rate detention in high accuracy, providing a fully total private and secure environment, independently from other noisy influences. It is a standard biotic radar system in consumer electronics, healthcare as well as industrial applications. In this wiki, we will introduce you how to utilize it.

Application

Feature

Specification

Parameter content Minimum Typical Maximum Unit
Performance
Detection distance (thoracic) 0.4 2 m
Respiratory measurement accuracy 90 %
Heartbeat measurement accuracy 85 %
Refresh time 1 30 S
Observation set-up time 20 S
Operating parameters
Operating voltage (VCC) 4.6 5 6 V
Operating current (ICC) 150 mA
Operating temperature (TOP) -20 60
Storage temperature (TST) -40 80
Launch parameters
Operating frequency (fTX) 58 60 63.5 GHz
Transmitted power (Pout) 6 dBm
Antenna parameters
Antenna gain (GANT) 4 dBi
Horizontal beam (-3dB) -40 40 o
Vertical beam (-3dB) -40 40 o

Hardware Overview

Before everything starts, it is quite essential to have some basic parameters of the product. The following table provides information about the characteristics of 60GHz mmWave Breathing and Heartbeat Module.

Getting Started

Firmware Version Updates

The mmwave sensor has undergone a long period of technical precipitation and valuable suggestions provided by users, and we have been iterating on the original product to provide more accurate and reliable monitoring results and a better experience for our users.

Newly shipped sensors are shipped with the latest firmware by default to ensure the latest product experience. However, for the sake of the old user experience, we hereby provide the latest firmware and update method to ensure that you can use our latest technology.

Download of the latest firmware

Firmware Version Download Address
Radar_MR60BHA1-V1125.bin Download

!!!Attention Please check the function of your product carefully, please do not mix with other mmwave sensors to brush this firmware, otherwise it may cause abnormal product function, the consequences need to be your own responsibility!

To update your radar to the latest version

Step1. You will need to have a Jlink and MR60BHA1 60GHz mmWave Sensor.

Connect the radar and Jlink together via Dupont wire as shown in the diagram below.

Step2. Download the necessary software and firmware.

File Download Address
JlinkV644e.rar Download
Pack_Segger_AT32F4xx_v1.3.3.zip Download

Step3. Unzip JlinkV644e.rar and open the JLink_Windows_V644e.exe file inside.

Just follow the default options to install. Once the installation is complete, start the J-Flash V6.44e software.

Step4. Install the chip package.

Unzip Pack_Segger_AT32F4xx_v1.3.3.zip and open Segger_AT32F4xx_AddOn.exe inside.

Step5. Create a new project.

Find and choose AT32F403ARGT7.

Step6. Drag and drop the radar firmware (.bin file) into this software and a window will pop up, we will just use its default starting address of 0x8000000.

Step7. Clink Target -> Connect

When the connection is successful it will show Connected successfully.

Erase firmware: Target -> manual Programming -> Erase Chip

Upgrade firmware: Target -> manual Programming -> Program & Verify

At this point, the firmware update is complete.

Use of the upper computer

Connect the sensor directly to the computer's usb port via a UART to USB device. The wiring is shown in the table below.

UART to USB MR60BHA1 Sensor
5V --> 5V
GND --> GND
RX --> TX
TX --> RX

In addition to the serial software mentioned above, you can also use the upper computer software designed for radar directly.

!!!Tip If you are using an older version of the OP and firmware, please upgrade to the latest version as soon as possible to ensure you can enjoy the software protocol and Wiki content.

The following five sections explain the role of each part of the software.

  1. Connection Setup

    Select the port to which the sensor is connected to the computer. It is usually necessary to refresh the port by clicking the Refresh Serial Port button before selecting it. Once the serial port is selected correctly, the data is automatically updated in circle 4 (if any data is available).

  2. Function Setting

    • Debugging: When this function is turned on, real-time raw data can be output in the software. This is the window in circle 3 in the figure.
    • Save Raw Data: When you click on it, you can choose to keep the original data to your local computer. Note, however, that this option does not save new data after the button is clicked, only the most recent historical data.
    • Save Sleep Data: When you click on it, you can choose the path to save the raw data information related to sleep, while other data will not be saved. Note, however, that this option does not save new data after the button is clicked, only the most recent historical data.
  3. Serial Monitor

    This window appears when the Debugging option in circle 2 is checked, at which point the area displays real-time sensor data frames. At the bottom you can send command frames to the sensor. The commands that can be sent or queried can be found in the user manual of the sensor.

  4. Graphic Display

    This shows the line graph in real time. The data content displayed is respiratory rate, heart rate, and physical parameters, respectively. The horizontal coordinate is the time and the vertical coordinate is the corresponding data.

  5. Status & Orientation

    This area allows you to observe the state of human presence and the orientation of the human body. The human body orientation data is for reference only.

Sensor development with Arduino

Arduino Library Overview

!!!Tip If this is your first time using Arduino, we highly recommend you to refer to Getting Started with Arduino.

The library code used in this example can be downloaded by clicking the icon below.

Function

Before we get started developing a sketch, let's look at the available functions of the library.

Default Variables

#define MESSAGE_HEAD1 0x53      //Data frame header1
#define MESSAGE_HEAD2 0x59      //Data frame header2

#define MESSAGE_END1  0x54      //End1 of data frame
#define MESSAGE_END2  0x43      //End2 of data frame

#define HUMAN_PSE_RADAR 0x80    //Human presence data

#define PRESENCE_INF 0x01       //Presence Information
#define SOMEONE_HERE 0x01       //Someone here
#define NOONE_HERE 0x00         //Noone here

#define MOVE_INF 0x02           //Campaign Information
#define PSE_NONE 0x00           //None
#define STATIONARY 0x01         //A person is stationary
#define MOVEMENT 0x02           //A person in motion

#define BODY_SIG 0x03           //Body movement information

#define DISTANCE 0x04           //Distance from the person being detected

#define DIRECTIONS 0x05         //Body orientation

#define HEART_INF 0x85          //Heart rate information

#define HEART_RATE 0x02         //Heart rate

#define HEART_RATE_WAVE 0x05    //Heart rate waveform (No analysis for now)

#define BREATH_RATE_RADAR 0x81  //Respiratory heart rate data

#define BREATH_INF 0x01         //Breathing data
#define BREATH_NORMAL 0x01      //Normal breathing
#define BREATH_RAPID 0x02       //Acute respiratory abnormalities
#define BREATH_SLOW 0x03        //Slow heartbeat
#define BREATH_NONE 0x04        //Radar detection nothing

#define BREATH_VAL 0x02         //Breathing values

#define BREATH_WAVE 0x05        //Respiratory waveform (No analysis for now)

#define SLEEP_INF 0x84          //Sleep information

#define INOUT_BED 0x01          //In bed or out of bed
#define OUT_BED 0x00            //Out of bed
#define IN_BED 0x01             //In bed
#define INOUT_NONE 0x02         //None (Display in real-time detection mode)

#define SLEEP_STATE 0x02        //Sleep state
#define DEEP_SLEEP 0x00         //Deep sleep
#define LIGHT_SLEEP 0x01        //Light sleep
#define AWAKE 0x02              //Awake
#define SLEEP_NONE 0x03         //None (Display in real-time detection mode)

#define AWAKE_TIME 0x03         //Awake time

#define LIGHTSLEEP_TIME 0x04    //Light sleep time

#define DEEPSLEEP_TIME 0x05     //Deep sleep time

#define SLEEP_SCORE 0x06        //Sleep quality score

#define SLEEP_STATUE 0x0C       //Sleep integrated status reporte

#define SLEEP_QUALITY 0x0D      //Comprehensive information reporting on sleep quality

#define SLEEP_ERROR 0x0E        //Abnormal sleep reporte

#define SLEEP_LESS4H 0x00        //Sleep less than 4 hours
#define SLEEP_OVER12H 0x01       //Sleep over 12 hours
#define SLEEP_LONGTIMENOONE 0x02 //Unusual situation, no one for a long time
#define SLEEP_ERRORNONE 0x03     //None

#define reset_frame_len 10      //Reset data frame length
//Reset data frame
const unsigned char breath_reset_frame[10] = {0x53, 0x59, 0x01, 0x02, 0x00, 0x01, 0x0F, 0xBF, 0x54, 0x43};

#define mode_frame_len 10       //Mode selection command frame length
//Mode selection command frame
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};

//Return status, Use in arduino
//Possible values for 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;

Installation

Step 1. You need to Install an Arduino Software.

Step 2. Launch the Arduino application.

Step 3. Select your development board model and add it to the Arduino IDE.

!!!Attention For XIAO nRF52840, please select Seeed nRF52 mbed-enabled Boards, otherwise an error may be reported when running programs.

Step 4. Install the Arduino code library.

Start by getting the code base from GitHub and downloading it to your local computer.

Since you have downloaded the zip Library, open your Arduino IDE, click on Sketch > Include Library > Add .ZIP Library. Choose the zip file you just downloaded,and if the library install correct, you will see Library added to your libraries in the notice window. Which means the library is installed successfully.

Arduino Example

Now that we have our library installed and we understand the basic functions, let's run some examples for our XIAO BLE to see how it behaves.

Materials Required

Before completing the following examples, you will need to prepare the following materials.

60GHz MR60BHA1 Sensor Seeed XIAO BLE nRF52840 Sense 2mm to 2.54mm Pitch Ribbon Cable

Step 1. Connect the device to the computer through the main board. The wiring diagram is shown in the table below.

Seeed Studio XIAO nRF52840 MR60BHA1 Sensor
5V --> 5V
GND --> GND
RX --> D6
TX --> D7

Step 2. In the menu bar in the upper left corner of the Arduino IDE, select tool, choose the type of development board you are using, and select the corresponding serial port.

!!!Tip If you are using MacOS, the serial port name of the device will often start with /dev/cu.usbmodem xxx, ending with the name of the device. If you are using Windows, the device's serial port name will often begin with COM, again ending with the device's name.

In this example, we will demonstrate how the radar works with our popular product XIAO BLE.

Demo1 Raw data export

This example will guide you through the process of printing out the raw data reported by the Sensor via the serial port.

The following example program is in the examples folder of the library called MR60BHA1_print_rawdata.

#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");
}

void loop()
{
  // put your main code here, to run repeatedly:
  radar.recvRadarBytes();           //Receive radar data and start processing
  radar.showData();                 //Serial port prints a set of received data frames
  delay(200);                       //Add time delay to avoid program jam
}

In this program, we are using the XIAO nRF52840's hardware Serial1 port to connect to the Sensor and use the hardware Serial port Serial to output data, so we need to initialise this serial port separately in the initialisation function Setup().

In the main loop() function we use the function recvRadarBytes() to receive data frames from the Sensor and then use the showData() function to print out the received data frames via the serial port.

In this program, it is important to note that there is an interval between the reception and output of every two data frames to avoid a jam on the main board. This time should be no less than 150ms.

This means that there is no way for the main board to receive all the data frames reported by the Sensor, but as the number of frames reported by the Sensor is very large and frequent, this does not affect the accuracy of using the Sensor to determine the environment.

Upload program. Opening your serial monitor to a baud rate of 115200 should show the result. The output should look something like the below image.

Demo2: Use of human presence detection function

In this example, we will explain how to use the function of human presence detection and print out all the values of this function in the function through the serial monitor.

The following example program is in the examples folder of the library called MR60BHA1_human_existence_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");
}

void loop()
{
  // put your main code here, to run repeatedly:
  radar.HumanExis_Func();           //Human existence information output
  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);                       //Add time delay to avoid program jam
}

In this example, the function to detect the presence of a human body is implemented by the HumanExis_Func() function. The basic logic of the program implementation is that the HumanExis_Func() function assigns the status information reported by the sensor to the sensor_report variable. Based on the value of sensor_report, we then print out all the values in that state through the serial port.

Note that the sensor_report corresponds to the data output from the serial port under indentation. For example, the bodysign_val variable representing the sign parameter is only valid when sensor_report is BODYVAL, and is not present in other sensor_reports reported by the sensor.

Upload program. Opening your serial monitor to a baud rate of 115200 should show the result. The output should look something like the below image.

Demo3: The use of respiratory and heartbeat functions in the resting people

In this example, we will use the Breath_Heart() function to detect the breathing and heart rate of a stationary human body.

!!!Tip Our emphasis is on detecting breathing and heart rate in a stationary human body. Please do not use the product while the human body is in motion, as we have limited the heart rate and breathing of the sensor. The maximum heart rate will not exceed 100 and the maximum respiratory rate will not exceed 25.

The following example program is in the examples folder of the library called 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("Sensor monitored the current heart rate value is: ");
        Serial.println(radar.heart_rate, DEC);
        Serial.println("----------------------------");
        break;
      case HEARTRATEWAVE:  //Valid only when real-time data transfer mode is on
        Serial.print("The heart rate waveform(Sine wave) -- point 1: ");
        Serial.print(radar.heart_point_1);
        Serial.print(", point 2 : ");
        Serial.print(radar.heart_point_2);
        Serial.print(", point 3 : ");
        Serial.print(radar.heart_point_3);
        Serial.print(", point 4 : ");
        Serial.print(radar.heart_point_4);
        Serial.print(", point 5 : ");
        Serial.println(radar.heart_point_5);
        Serial.println("----------------------------");
        break;
      case BREATHNOR:
        Serial.println("Sensor detects current breath rate is normal.");
        Serial.println("----------------------------");
        break;
      case BREATHRAPID:
        Serial.println("Sensor detects current breath rate is too fast.");
        Serial.println("----------------------------");
        break;
      case BREATHSLOW:
        Serial.println("Sensor detects current breath rate is too slow.");
        Serial.println("----------------------------");
        break;
      case BREATHNONE:
        Serial.println("There is no breathing information yet, please wait...");
        Serial.println("----------------------------");
        break;
      case BREATHVAL:
        Serial.print("Sensor monitored the current breath rate value is: ");
        Serial.println(radar.breath_rate, DEC);
        Serial.println("----------------------------");
        break;
      case BREATHWAVE:  //Valid only when real-time data transfer mode is on
        Serial.print("The breath rate waveform(Sine wave) -- point 1: ");
        Serial.print(radar.breath_point_1);
        Serial.print(", point 2 : ");
        Serial.print(radar.breath_point_2);
        Serial.print(", point 3 : ");
        Serial.print(radar.breath_point_3);
        Serial.print(", point 4 : ");
        Serial.print(radar.breath_point_4);
        Serial.print(", point 5 : ");
        Serial.println(radar.breath_point_5);
        Serial.println("----------------------------");
        break;
    }
  }
  delay(200);                       //Add time delay to avoid program jam
}

Upload program. Opening your serial monitor to a baud rate of 115200 should show the result. The output should look something like the below image.

!!!Attention If you want to see waveform data, switch the sensor to real-time data transmission mode. After switching modes, the sensor may need to be re-powered to take effect.

Demo4: Use of the sleep function

In this example, we will guide you how to get the information about sleep by using the SleepInf_Decode() function. Please make sure that you or the testing people is ready to go to bed before using this example.

!!!Note By default, the sensor is in sleep state transmission mode. In this mode, the sleep monitoring function is on. If you switch to real-time data transmission mode, then sleep data may not be available. If you want to change the transfer mode, you can use the ModeSelect_fuc() function to do so. Examples of use can also be found in the MR60BHA1_Transfer_mode_selection in the examples folder. After switching modes, the sensor may need to be re-powered to take effect. The data related to sleep needs to be reported when a person is in bed, and the current firmware defaults to judging that someone is in bed after a person state lasts 5 minutes.

The following example program is in the examples folder of the library called MR60BHA1_Sleep_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");
}

void loop()
{
  // put your main code here, to run repeatedly:
  radar.SleepInf_Decode();           //Sleep-related information output. Data output begins when the monitoring figure is in bed for five minutes.
  if(radar.sensor_report != 0x00){
    switch(radar.sensor_report){
      case OUTBED:
        Serial.println("Sensor detects someone currently leaving the bed.");
        Serial.println("----------------------------");
        break;
      case INBED:
        Serial.println("Sensor detects that someone is currently in bed.");
        Serial.println("----------------------------");
        break;
      case NOINOUT:
        Serial.println("No subject is detected leaving or going to bed.");
        Serial.println("----------------------------");
        break;
      case SLEEPAWAKE:
        Serial.println("Sensor detects that the monitoring people is awake.");
        Serial.println("----------------------------");
        break;
      case SLEEPLIGHT:
        Serial.println("Sensor detects that the monitoring people is in light sleeping.");
        Serial.println("----------------------------");
        break;
      case SLEEPDEEP:
        Serial.println("Sensor detects that the monitoring people is in deep sleeping.");
        Serial.println("----------------------------");
        break;
      case SLEEPNONE:
        Serial.println("Sleep state of the object is not detected.");
        Serial.println("----------------------------");
        break;
      case AWAKETIME:
        Serial.print("Sensor monitored the awake sleep time is: ");
        Serial.print(radar.awake_time);
        Serial.println(" min");
        Serial.println("----------------------------");
        break;
      case LIGHTTIME:
        Serial.print("Sensor monitored the light sleep time is: ");
        Serial.print(radar.light_time);
        Serial.println(" min");
        Serial.println("----------------------------");
        break;
      case DEEPTIME:
        Serial.print("Sensor monitored the deep sleep time is: ");
        Serial.print(radar.deep_time);
        Serial.println(" min");
        Serial.println("----------------------------");
        break;
      case SLEEPSCORE:
        Serial.print("Sensor judgment sleep score is: ");
        Serial.println(radar.sleep_score);
        Serial.println("----------------------------");
        break;
      case SLEEPSTATUE:
        Serial.println("Sleep integrated state information -- ");
        Serial.print("Human existence: ");
        if(radar.existence)Serial.println("human exis");
        else Serial.println("human non-existent");
        Serial.print("Sleep state: ");
        if(radar.sleep_status == SLEEPDEEP)Serial.println("sleeping soundly");
        else if(radar.sleep_status == SLEEPLIGHT)Serial.println("light sleep");
        else if(radar.sleep_status == SLEEPAWAKE)Serial.println("awake");
        else if(radar.sleep_status == SLEEPNONE)Serial.println("off the bed");
        Serial.print("Average breathing: ");
        Serial.println(radar.breath_rate);
        Serial.print("Average heart rate: ");
        Serial.println(radar.heart_rate);
        Serial.print("Number of turning over during sleep: ");
        Serial.println(radar.turn_num);
        Serial.print("Percentage of substantial exercise during sleep: ");
        Serial.println(radar.substantial_move_ratio);
        Serial.print("Percentage of small-amplitude movements during sleep: ");
        Serial.println(radar.samll_move_ratio);
        Serial.print("Number of apnea: ");
        Serial.println(radar.apnea_num);
        Serial.println("----------------------------");
        break;
      case SLEEPQUALITY:
        Serial.println("Quality of sleep information -- ");
        Serial.print("Sleep score: ");
        Serial.println(radar.sleep_score);
        Serial.print("Total time of sleep: ");
        Serial.print(radar.sleep_time);
        Serial.println(" min");
        Serial.print("Percentage of waking time: ");
        Serial.println(radar.awake_time_radio);
        Serial.print("Percentage of light sleep time: ");
        Serial.println(radar.light_time_radio);
        Serial.print("Percentage of deep sleep time: ");
        Serial.println(radar.deep_time_radio);
        Serial.print("Total time away from bed: ");
        Serial.print(radar.outbed_time);
        Serial.println(" min");
        Serial.print("Total number of times out of bed: ");
        Serial.println(radar.outbed_num);
        Serial.print("The number of turning over during sleep: ");
        Serial.println(radar.turn_num);
        Serial.print("Average breathing: ");
        Serial.println(radar.breath_rate);
        Serial.print("Average heart rate: ");
        Serial.println(radar.heart_rate);
        Serial.print("Number of apnea: ");
        Serial.println(radar.apnea_num);
        Serial.println("----------------------------");
        break;
      case SLEEPLESS4H:
        Serial.print("The monitored subjects slept for less than 4 hours.");
        Serial.println("----------------------------");
        break;
      case SLEEPOVER12H:
        Serial.print("The length of sleep of the monitored subjects exceeded 12 hours.");
        Serial.println("----------------------------");
        break;
      case LONGTIMENOONE:
        Serial.print("Abnormally unoccupied for long periods of time.");
        Serial.println("----------------------------");
        break;
      case ERRORNONE:
        Serial.print("No abnormal information.");
        Serial.println("----------------------------");
        break;
    }
  }
  delay(200);                       //Add time delay to avoid program jam
}

Upload program. Opening your serial monitor to a baud rate of 115200 should show the result. The output should look something like the below image.

Demo5: Send data to Sensor

Based on the details provided in the user manual, the user can send command frames to the sensor to query or set certain states or modes of the sensor according to the actual needs.

The .ino file named MR60BHA1_Send_frame in the examples folder of the sensor library shows us how to send a program that queries the device ID to the sensor.

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

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

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");
}

void loop()
{
  // put your main code here, to run repeatedly:
  radar.send_func(DevID_buff, 10, false);
  delay(50);                       //Do not set the delay time too long, as this may affect the reception of the data frames returned by the radar.
}

In the program of this example, you can see that an array DevID_buff[10] is defined, which stores the hexadecimal number of your query device ID, one location per byte.

And the sending is done by send_func(). The parameters passed in are the array of frames to be sent, the length of the array, and whether to send in a loop.

If you need to send your own command frames, then you need to define the correct array according to the frame format provided in the user manual.

!!!Tip Regarding the calculation of the check digit "sum". All data frames have a checksum bit to ensure that the data is sent or received accurately. The checksum bit is usually in the penultimate bit of the data frame. It is calculated by adding up all the bits preceding the check bit and taking the lower two bits in hexadecimal. Let's take the example of a data frame that queries the device ID.

It can be seen that the checksum bit is in the penultimate bit of the entire data frame. Then we start by adding all the previous hexadecimal numbers.

`0x53 + 0x59 + 0x02 + 0xA2 + 0x00 + 0x01 + 0x0F = 0x015F`

Then we need to take the lower two digits of it, which would be **5F**, so the checksum of this data frame is **5F**. If we want to look up the ID of the Sensor, then you can define the following array.

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

Upload program. Opening your serial monitor to a baud rate of 115200 should show the result. The output should look something like the below image.

At this point please check the data frames returned and if they match the data frames returned as described in the user manual.

Normally, our commands do not need to be repeated to the Sensor, but as the Sensor replies with messages so fast that we cannot be sure that we will receive the exact data message returned by the Sensor. There are two solutions to this problem.

Demo6: Reset Sensor

There may be times when you have problems with your Sensor detecting anomalies or when you want to clear all settings on your Sensor, then you can reset your Sensor according to this example.

The following example program is in the examples folder of the library called MR60BHA1_Reset_sensor.

#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.reset_func();
}

void loop()
{
  // put your main code here, to run repeatedly:
}

Resetting the Sensor is very simple, you just need to call reset_func(). The reset only needs to be executed once, so we use it in the Setup() function.

Demo7: Using Arduino/Seeeduino

Our library is Arduino compatible and you can also choose the Arduino you have on hand to develop your Sensor project.

The MR60BHA1 Sensor communicates using the UART serial port, you just need to connect the Sensor to your Arduino as wired below.

MR60BHA1 Sensor MCU
5V --> 5V
GND --> GND
RX --> soft serial port TX
TX --> soft serial port RX

All the functions are applied in the same way as in Demo1 to Demo6 above, so we will not repeat them in this example. In this example, we will give you an overview of how to use the Arduino's soft serial port to get data information from the Sensor.

!!!Tip For notes on the Arduino soft serial port, please refer to the official Arduino documentation.

To avoid data confusion caused by using Serial for both output and data transmission, on the Arduino side we usually use a soft serial port.

The import of the soft serial port library and the definition of the RX and TX pins need to be done earlier in the program. The following program defines the A2 and A3 pins as the RX and TX pins of the soft serial port.

#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
HumanStaticLite radar = HumanStaticLite(&mySerial);

Also, don't forget to set the baud rate for the soft serial port in the Setup() function.

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

  mySerial.begin(115200);

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

  Serial.println("Readly");
}

Using Demo1 as an example, if you want to use the Arduino to print the reported data frames from the Sensor, then the complete program is as follows.

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

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

  mySerial.begin(115200);

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

  Serial.println("Readly");
}

void loop()
{
  // put your main code here, to run repeatedly:
  radar.recvRadarBytes();           //Receive radar data and start processing
  radar.showData();                 //Serial port prints a set of received data frames
  delay(200);                       //Add time delay to avoid program jam
}

Demo8: Direct connection to PC for data

You can refer to this routine if you want to use an upper computer designed for Sensor, or if you want to use the serial software to get a complete data frame.

Connect the Sensor directly to the computer's usb port via a UART to USB device. The wiring is shown in the table below.

UART to USB MR60BHA1 Sensor
5V --> 5V
GND --> GND
RX --> TX
TX --> RX

Use a software like serial debugging assistant to select the serial port where the Sensor is located.

!!!Attention MR60BHA1 Sensor needs 5V power supply, otherwise the Sensor may not work properly.

After a successful connection, you will see the Sensor sending a steady stream of messages.

At the same time, you can also send data frames to the Sensor via the software's send function.

!!!Attention If you choose ASCII as the format for sending data, each data set needs to be prefixed with 0x. If you choose HEX, then each set of data does not need to be prefixed with 0x.

Troubleshooting

FAQ1: Can this Sensor detect more than one person at a time in the same environment?

A: Not available. This Sensor can only be used on a single living object. If more than one person or animal is in the monitoring range, this will have an effect on the results of the monitoring.

FAQ2: Why can't I see anything in the serial monitor with the XIAO ESP32C3?

XIAO ESP32C3 serial port function is not quite consistent with the general Arduino hardware, and using Serial1 directly may cause the USB serial port not to work. For related application cases, please go to the Serial chapter of XIAO ESP32C3 for details.

Resources

Tech Support

Please do not hesitate to submit the issue into our forum.