一.系统概述
蓝牙手环健康监测系统,具备以下功能:
1. 核心控制器:使用STM32单片机作为系统的核心控制器,负责数据处理和系统控制。
2. 传感器数据采集:通过DS18B20传感器监测体温,通过Max3102传感器监测心率和血氧水平,通过血压传感器监测血压。使用ADXL345传感器统计步数,并检测大幅度的角度变化。
3. 跌倒报警:当ADXL345传感器检测到显著的角度变化(如跌倒)时,系统会触发远程报警,提醒用户跌倒。
4. 数据上传与远程监控:通过蓝牙将采集到的健康数据(体温、心率、血氧、血压)上传到APP端。当检测到体温、心率、血氧或血压异常时,系统会发送报警信息到APP端。
二.电路设计
电路图采用Altium Designer进行设计:
1. 通过STM32F103C8T6单片机作为系统主控,最小系统电路是整个电路的核心;
2. 使用MAX30102进行心率血氧检测,该模块通过IIC总线与单片机进行通信;
3. 通过DS18B20进行温度检测,并通过单总线与单片机完成数据通信;
4. 使用XGZP6847气压检测模块进行血压检测,将模块的模拟输出口接单片机的ADC输入口;
5. 通过0.96寸的OLED12864进行数据显示,采用IIC总线的形式与单片机进行通信;
6. 使用JDY-31蓝牙模块进行无线通信,通过UART串口与单片机进行通信;
7. 使用独立按键进行阈值设定,按键的一端接地,一端接单片机的GPIO口。
三.程序设计
#include "delay.h" //包含需要的头文件
#include "myiic.h"
#include "max30102.h"
#include "algorithm.h"
#include "sys.h"
#include "usart.h"
#define SIZE sizeof(TEXT_Buffer)
#define FLASH_SAVE_ADDR 0X0800f400
uint32_t aun_ir_buffer[500]; //IR LED sensor data
int32_t n_ir_buffer_length; //data length
uint32_t aun_red_buffer[500]; //Red LED sensor data
int32_t n_sp02; //SPO2 value
int8_t ch_spo2_valid; //indicator to show if the SP02 calculation is valid
int32_t n_heart_rate; //heart rate value
int8_t ch_hr_valid; //indicator to show if the heart rate calculation is valid
uint8_t uch_dummy;
#define MAX_BRIGHTNESS 255
int main(void)
{
u8 dis_hr=0,dis_spo2=0;
uint32_t un_min, un_max, un_prev_data;
int i;
int32_t n_brightness;
float f_temp;
u8 temp[6],str[15];
delay_init(); //延时功能初始化
Usart1_Init(9600);
max30102_init();
n_ir_buffer_length=100;
un_min=0x3FFFF;
un_max=0;
for(i=0;i<n_ir_buffer_length;i++)
{
while(MAX30102_INT==1); //wait until the interrupt pin asserts
max30102_FIFO_ReadBytes(REG_FIFO_DATA,temp);
aun_red_buffer[i] = (long)((long)((long)temp[0]&0x03)<<16) | (long)temp[1]<<8 | (long)temp[2]; // Combine values to get the actual number
aun_ir_buffer[i] = (long)((long)((long)temp[3] & 0x03)<<16) |(long)temp[4]<<8 | (long)temp[5]; // Combine values to get the actual number
if(un_min>aun_red_buffer[i])
un_min=aun_red_buffer[i]; //update signal min
if(un_max<aun_red_buffer[i])
un_max=aun_red_buffer[i]; //update signal max
}
un_prev_data=aun_red_buffer[i];
maxim_heart_rate_and_oxygen_saturation(aun_ir_buffer, n_ir_buffer_length, aun_red_buffer, &n_sp02, &ch_spo2_valid, &n_heart_rate, &ch_hr_valid);
while(1)
{
un_min=0x3FFFF;
un_max=0;
i=0;
for(i=100;i<500;i++)
{
aun_red_buffer[i-100]=aun_red_buffer[i];
aun_ir_buffer[i-100]=aun_ir_buffer[i];
if(un_min>aun_red_buffer[i])
un_min=aun_red_buffer[i];
if(un_max<aun_red_buffer[i])
un_max=aun_red_buffer[i];
}
for(i=400;i<500;i++)
{
un_prev_data=aun_red_buffer[i-1];
while(MAX30102_INT==1);
max30102_FIFO_ReadBytes(REG_FIFO_DATA,temp);
aun_red_buffer[i] = (long)((long)((long)temp[0]&0x03)<<16) | (long)temp[1]<<8 | (long)temp[2]; // Combine values to get the actual number
aun_ir_buffer[i] = (long)((long)((long)temp[3] & 0x03)<<16) |(long)temp[4]<<8 | (long)temp[5]; // Combine values to get the actual number
}
maxim_heart_rate_and_oxygen_saturation(aun_ir_buffer, n_ir_buffer_length, aun_red_buffer, &n_sp02, &ch_spo2_valid, &n_heart_rate, &ch_hr_valid);
sprintf((char *)str,"S:%d%d%d,h:%d%d%d",dis_spo2/100,dis_spo2%100/10,dis_spo2%10,dis_hr/100,dis_hr%100/10,dis_hr%10);//**HR:%3d SpO2:%3d /1000,adcx%1000/100,adcx%100/10,adcx%10
UART1Write(str);
}
}