【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]