zygalaxy 发表于 2024-10-31 20:29

【2024 DigiKey创意大赛】- 基于毫米波雷达的生命体征检测及健康监护系统-监护模块

本帖最后由 zygalaxy 于 2024-10-31 19:52 编辑

## 【2024 DigiKey创意大赛】- 基于毫米波雷达的生命体征检测及健康监护系统 - 健康监护模块开发

## 一、模块概述

本健康监护模块旨在为用户提供实时的心率、呼吸频率和睡眠质量监测功能,通过先进的毫米波雷达技术和传感器,准确获取用户的生命体征数据,并在异常情况下自动报警,通知家人或医疗服务机构。同时,该模块还能生成详细的睡眠质量报告,帮助用户改善睡眠。



## 二、功能需求

1. **心率监测**
   - 利用 MR60BHA1 毫米波雷达实时监测用户的心率。
   - 将心率数据通过 ESP32 模块传输至 LCD 触摸屏显示器和用户手机 APP,以便用户实时查看。
2. **呼吸频率监测**
   - 采用毫米波雷达技术精准监测用户的呼吸频率。
   - 当检测到呼吸频率异常时,自动报警并通知家人或医疗服务机构。
3. **睡眠质量监测**
   - 通过传感器监测用户的睡眠状态。
   - 生成详细的睡眠质量报告,包括入睡时间、睡眠时长、深度睡眠时间等信息。
   - 为用户提供改善睡眠的建议。
   


## 三、硬件需求

1. **MR60BHA1 毫米波非接触式心率传感器模块**:用于心率监测。
2. **毫米波雷达**:用于呼吸频率监测和睡眠质量监测。
3. **ESP32 评估板**:负责数据传输和处理。
4. **LCD 触摸屏显示器**:显示心率、呼吸频率和睡眠质量数据。





## 四、软件设计

1. **数据采集**
   - 利用传感器模块和毫米波雷达采集用户的心率、呼吸频率和睡眠状态数据。
   - 确保数据采集的准确性和稳定性。

2. **数据处理**
   - 对采集到的数据进行处理和分析,提取有用的信息。
   - 计算心率、呼吸频率的平均值、最大值和最小值等统计信息。
   - 分析睡眠状态数据,生成睡眠质量报告。
3. **数据传输**
   - 通过 ESP32 模块将处理后的数据传输至 LCD 触摸屏显示器和用户手机 APP。
   - 确保数据传输的实时性和可靠性。
4. **报警系统**
   - 当检测到心率、呼吸频率异常或睡眠质量较差时,自动触发报警。
   - 报警方式可以是声音、震动或推送通知等。

## 五、用户界面设计

1. **LCD 触摸屏显示器界面**
   - 显示用户的心率、呼吸频率和睡眠质量数据。
   - 提供简洁明了的图表和数字显示,方便用户查看。



2. **手机 APP 界面**
   - 实时显示用户的健康数据,包括心率、呼吸频率和睡眠质量报告。
   - 提供历史数据查询功能,用户可以查看过去一段时间的健康数据。
   - 推送报警通知,当检测到异常情况时及时提醒用户。
   
   
   
   
   
   

## 六、部分代码

硬件代码:
```c
#include <Arduino.h>
#include <WiFi.h>
#include <PubSubClient.h>
#include <60ghzbreathheart.h>

// WiFi network credentials
const char *ssid = "zygalaxy";
const char *password = "12345678";

// MQTT broker settings
const char *mqtt_server = "104.168.82.148";
const int mqtt_port = 1883;
const char *clientId = "heart_breath_1";
const char *mqtt_user = "zygalaxy";
const char *mqtt_password = "YOUR_MQTT_PASSWORD";


//定义心率呼吸信息topic
const char *heart_rate_topic = "t/heart_rate";

const char *breath_topic = "t/breath_rate";

//定义睡眠topic

// 进出床状态
//0:未检测到;1:上床;2:下床
const char *bed_topic = "t/bed";


// 睡眠状态
const char *sleep_awake_topic = "t/sleep_awake";
const char *sleep_light_topic = "t/sleep_light";
const char *sleep_deep_topic = "t/sleep_deep";
const char *sleep_none_topic = "t/sleep_none";

// 睡眠时间
const char *awake_time_topic = "t/awake_time";
const char *light_time_topic = "t/light_time";
const char *deep_time_topic = "t/deep_time";

// 睡眠评分
const char *sleep_score_topic = "t/sleep_score";

// 综合睡眠状态
const char *sleep_statue_existence_topic = "t/sleep_statue/existence";
const char *sleep_statue_state_topic = "t/sleep_statue/state";
const char *sleep_statue_breath_rate_topic = "t/sleep_statue/breath_rate";
const char *sleep_statue_heart_rate_topic = "t/sleep_statue/heart_rate";
const char *sleep_statue_turn_num_topic = "t/sleep_statue/turn_num";
const char *sleep_statue_substantial_move_ratio_topic = "t/sleep_statue/substantial_move_ratio";
const char *sleep_statue_small_move_ratio_topic = "t/sleep_statue/small_move_ratio";
const char *sleep_statue_apnea_num_topic = "t/sleep_statue/apnea_num";

// 睡眠质量信息
const char *sleep_quality_score_topic = "t/sleep_quality/score";
const char *sleep_quality_time_total_topic = "t/sleep_quality/time_total";
const char *sleep_quality_awake_time_radio_topic = "t/sleep_quality/awake_time_radio";
const char *sleep_quality_light_time_radio_topic = "t/sleep_quality/light_time_radio";
const char *sleep_quality_deep_time_radio_topic = "t/sleep_quality/deep_time_radio";
const char *sleep_quality_outbed_time_topic = "t/sleep_quality/outbed_time";
const char *sleep_quality_outbed_num_topic = "t/sleep_quality/outbed_num";
const char *sleep_quality_breath_rate_topic = "t/sleep_quality/breath_rate";
const char *sleep_quality_heart_rate_topic = "t/sleep_quality/heart_rate";
const char *sleep_quality_apnea_num_topic = "t/sleep_quality/apnea_num";

// 异常睡眠情况
const char *sleep_less4h_topic = "t/sleep_less4h";
const char *sleep_over12h_topic = "t/sleep_over12h";
const char *longtime_noone_topic = "t/longtime_noone";
const char *error_none_topic = "t/error_none";


WiFiClient wifiClient;
PubSubClient client(wifiClient);

BreathHeart_60GHz radar = BreathHeart_60GHz(&Serial1);


void callback(char *topic, byte *payload, unsigned int length) {
    Serial.print("Message arrived on topic: ");
    Serial.println(topic);
    Serial.print("Message:");
    for (int i = 0; i < length; i++) {
      Serial.print((char) payload);
    }
    Serial.println();
}

void reconnect() {
    while (!client.connected()) {
      Serial.print("Attempting MQTT connection...");
      if (client.connect(clientId, mqtt_user, mqtt_password)) {
            Serial.println(" connected");
      } else {
            Serial.print(" failed, rc=");
            Serial.print(client.state());
            Serial.println(" try again in 5 seconds");
            delay(5000);
      }
    }
}

void setup() {
    Serial.begin(115200);
    Serial1.begin(115200);
    while (!Serial);
    Serial.println("Ready");
    WiFi.begin(ssid, password);
    while (WiFi.status() != WL_CONNECTED) {
      delay(500);
      Serial.print(".");
    }
    Serial.println("\nConnected to the WiFi network");

    client.setServer(mqtt_server, mqtt_port);
    client.setCallback(callback);
}
int a=0;
void loop() {
    if (!client.connected()) {
      reconnect();
    }
    client.loop();

    radar.BreathHeart_Breath_Sleep_Decode_Heart();

    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);
                client.publish(heart_rate_topic, String(radar.heart_rate).c_str());
                Serial.println("----------------------------");
                break;
            case HEARTRATEWAVE:
                // Heart rate wave data can be published as well if needed.
                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.");
                client.publish(breath_topic, "Normal");
                Serial.println("----------------------------");
                break;
            case BREATHRAPID:
                Serial.println("Sensor detects current breath rate is too fast.");
                //client.publish(breath_topic, "Rapid");
                Serial.println("----------------------------");
                break;
            case BREATHSLOW:
                Serial.println("Sensor detects current breath rate is too slow.");
                //client.publish(breath_topic, "Slow");
                Serial.println("----------------------------");
                break;
            case BREATHNONE:
                Serial.println("There is no breathing information yet, please wait...");
                break;
            case BREATHVAL:
                Serial.print("Sensor monitored the current breath rate value is: ");
                Serial.println(radar.breath_rate);
                client.publish(breath_topic, String(radar.breath_rate).c_str());
                Serial.println("----------------------------");
                break;
            case BREATHWAVE:
                // Breath wave data can be published as well if needed.
                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;
                //睡眠信息
            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);
}
```
软件代码:

```python
# 心率呼吸查询
@app.route('/heart_rate_respiration', methods=['GET'])
def get_heart_rate_respiration():
    reply = {"result": "ok", "message": "success"}
    device_id = request.args.get('device_id')
    start_date = request.args.get('start_date')
    end_date = request.args.get('end_date')
    if device_id and start_date and end_date:
      # 先在心率查询,再在呼吸查询
      heart_rate_data = HeartRateData.query.filter(
            HeartRateData.device_id == device_id,
            HeartRateData.timestamp >= start_date,
            HeartRateData.timestamp <= end_date
      ).all()
      respiration_data = RespirationData.query.filter(
            RespirationData.device_id == device_id,
            RespirationData.timestamp >= start_date,
            RespirationData.timestamp <= end_date
      ).all()
      heart_rate_data = [
            {
                'device_id': heart_rate.device_id,
                'heart_rate': heart_rate.heart_rate,
                'timestamp': heart_rate.timestamp
            }
            for heart_rate in heart_rate_data
      ]
      respiration_data = [
            {
                'device_id': respiration.device_id,
                'breathing': respiration.breathing,
                'timestamp': respiration.timestamp
            }
            for respiration in respiration_data
      ]
      return json.dumps(heart_rate_data + respiration_data), 200


```

```python
@app.route('/heart_rate', methods=['POST'])
def heart_rate():
    reply = {"result": "ok", "message": "success"}
    """
    {'publish_received_at': 1723569671836, 'pub_props': {'User-Property': {}}, 'peerhost': '39.85.60.209', 'qos': 0, 'topic': 't/heart_rate', 'clientid': 'mqttx_7492d77a', 'payload': '{
    \n"msg": "hello HTTP Server"\n}', 'username': 'undefined', 'event': 'message.publish', 'metadata': {'rule_id': 'heart_rate_WH_D'}, 'timestamp': 1723569671836,
    """
    raw_data = request.get_json()
    print(raw_data)
    device_id = raw_data['clientid']
    device = DeviceInfo.query.filter_by(device_id=device_id).first()
    if device and raw_data['payload'] != '0':
      # payload转化为 json

      heart_rate_data = HeartRateData(
            device_id=device_id,
            timestamp=datetime.utcnow(),
            user_id=device.user_id,
            heart_rate=raw_data['payload']
      )
      db.session.add(heart_rate_data)
      db.session.commit()
      socketio.emit('message', '心率数据:' + device_id + ' ' + raw_data['payload'])

    return json.dumps(reply), 200

```


### 总结

通过开发健康监护模块可以将心率、呼吸、温湿度等重要的信息传输到服务器,以便于 APP 和 LCD 查看,为后面的数据分析打下了数据的基础。
页: [1]
查看完整版本: 【2024 DigiKey创意大赛】- 基于毫米波雷达的生命体征检测及健康监护系统-监护模块