基于STM32设计的蓝牙健康管理设备

2022-06-28 09:47:39 浏览数 (1)

1. 前言

随着移动通信技术的发展,移动互联网日益普及,传统互联网已经在向移动互联网迁移,智能穿戴设备近年来发展的非常迅速,成为一个热点行业,它通过借助传感器,与人体进行信息交互,是一种在新理念下诞生的智能设备,具有广泛的应用领域,并能够根据用户需求不断升级。智能穿戴设备在提高人们生活品质、促进生活方式智能化方面将会起到很重要的作用。

按照主要功能的不同,智能穿戴设备产品可以划分为以下几类:运动健康类、体感交互类、信息资讯类、医疗健康类和综合功能类等,每类设备针对不同的细分市场和消费人群。运动和医疗健康类的设备有运动、体侧腕带及智能手环,主要消费人群为大众消费者;体感控制和综合功能类的设备有智能眼镜等,消费人群以年轻人为主;信息咨询类的设备有智能手表,主要消费人群为大众消费者。从目前来看,医疗和运动健康类设备使用的用户较多。

随着智能穿戴产业竞争日趋激烈,同质化产品现象越来越严重,各类只具备单一功能的智能硬件纷纷开始与其他智能硬件寻求合作。在未来,随着单一领域的智能穿戴产品技术日渐成熟,不同领域和功能诉求的产品会根据用户实际需求在功能上实现互补,从而带来更符合用户需求的智能体验,发展方向也会日渐明确和多元化。

当前采用STM32加上各种外设传感器配合蓝牙 手机APP设计了一款个人健康监控管理设备,通过BLE低功耗蓝牙将采集的传感器数据上传到手机APP进行实时显示。

2. 功能总结

主要功能 (1)开发板选用STM32单片机做数据处理。

(2)开发一款Android手机APP,用来显示蓝牙上传的数据

(3)运用蓝牙来传输数据,将体温传感器、心率脉搏传感器、加速度传感器采集的数据上传到手机上显示。

一般情况下脉搏等于心率,心脏射血沿着血管壁向前流动,形成脉搏。正常人无论大人、小孩、老年人,正常状态下脉搏和心率是一致的。如果有心脏病,因为心脏本身的传导系统有保护作用,心室率不可能和心房率一样,在血管里传导的速度也不一样,脉搏会有时弱,有时强。弱的时候可能感知不到,这种状态下脉搏会少于心率,房颤时心率比脉搏要多一些,所以脉搏不一定完全代表心率。

(4)如果测量的体温值超过警戒值,本地设备上的蜂鸣器就会发出警示提示声音。

需要使用的硬件:

(1)STM32系统板

(2)体温传感器

(3)陀螺仪传感器

(4)心率脉搏传感器

3. 硬件选型

3.1 MPU6050陀螺仪

MPU6050特点:

(1)高性能三轴加速度 三轴陀螺仪的六轴传感器模块MPU6050芯片;

(2)可利用自带的数字运动处理器(DMP)硬件加速引擎,通过主IKC接口,向应用端输出姿态解算后的数据,使用InvenSense公司提供的运动处理资料库,实现姿态解算,降低了运动处理运算对操作系统的负荷同时大大降低了开发难度;

(3)体积小,自带温度传感器;

(4)支持IIC从机地址设置和中断;

(5)兼容3.3V/5V系统;

3.2 STM32开发板

3.3 母对母杜邦线

3.4 温度传感器

GY-MCU90615 是一款低成本红外温度模块。工作电压 3-5v 功耗小,体积小。其工作原理, 是通过单 片机读取红外温度度数据,串口(TTL 电平)通信方式输出。 串口的波特率有 9600bps 与 115200bps 有连续输出与询问输出两种方式,可适应不同的工作环境,与所 有的单片机及电脑连接。

代码语言:javascript复制
通信协议
串口发送命令字节:

(1)、串口通信参数(默认波特率值9600 bps,可通过软件设定)
波特率:9600 bps     校验位:N   数据位:8   停止位:1

波特率:115200 bps   校验位:N   数据位:8   停止位:1

(2)、模块输入命令,由外部控制器发送至GY-MCU90615模块(十六进制)

 1、帧头:0xa5

指令格式:帧头 指令 校验和(8bit)(如自动读取温度指令=0xA5 0x45 0xEA)

2、命令指令: 

连续输出指令:0xA5 0x45 0xEA----------------温度数据(模块返回数据类型为0x45)

查询输出指令:

0xA5 0x15 0xBA ---------------温度数据(模块返回数据类型为0x45)

配置指令:(掉电重启后生效)  

波特率配置:

0xA5 0xAE 0x53 ---------------9600(默认)

0xA5 0xAF 0x54 ---------------115200

上电是否自动发送温度数据配置:

0xA5 0x51 0xF6---------------上电后自动输出温度数据(默认)

0xA5 0x52 0xF7---------------上电后不自动输出温度数据

 

通信协议

串口接收:

(1)、串口通信参数(默认波特率值9600 bps,可通过软件设定)

          波特率:9600 bps     校验位:N   数据位:8   停止位:1

波特率:115200 bps   校验位:N   数据位:8   停止位:1

 

(2)、模块输出格式,每帧包含9个字节(十六进制):

 ①.Byte0:   0x5A        帧头标志 

 ②.Byte1:   0x5A        帧头标志 

③.Byte2:   0X45        本帧数据类型(0X45:温度数据)

 ④.Byte3:   0x04       数据量(以下4个数据2组为例)

 ⑤.Byte4:   0x00~0xFF   数据1高8位

 ⑥.Byte5:   0x00~0xFF   数据1低8位

 ⑦.Byte6:   0x00~0xFF   数据2高8位

⑧.Byte7:   0x00~0xFF   数据2低8位

⑨.Byte8:   0x00~0xFF   校验和(前面数据累加和,仅留低8位)       

(3)、数据计算方法

温度计算方法 :

温度= 高8位<<8 低8位(结果为实际角度乘以100)

   例:发送指令:A5 45 EA   ,接收到一帧数据:

<5A- 5A- 45- 04- 0C- 78- 0D- 19- A7 >

  表示TO(有符号16bit,表示目标温度):TO=0x0C78/100=31.92 ℃

  表示TA(有符号16bit,表示环境温度):TO=0x0D19/100=33.53 ℃

使用方法
该模块为串口输出数据,使用者通过串口连接后,发送输出指令,例如0xA5 0x45 0xEA给模块,模块将连续输出温度数据;如想通过查询输出可发送0xA5 0x15 0xBA给模块,每发送一次,模块将返回一次温度数据,查询频率应低于10hz,如需高于10hz请使用连续输出模式,即发送0xA5 0x45 0xEA指令;

3.5 脉搏传感器

PulseSensor 是一款用于脉搏心率测量的光电反射式模拟传感器。将其佩戴于手指、耳垂等处,通过导线连接可将采集到的模拟信号传输给 Arduino 等单片机用来转换为数字信号,再通过 arduino 等单片机简单计算后就可以得到心率数值,此外还可将脉搏波形通过串口上传到电脑显示波形。 PulseSensor 是一款开源硬件, 目前国外官网上已有其对应的 arduino 程序和上位机 Processing 程序, 其适用于心率方面的科学研究和教学演示,也非常适合用于二次开发。

特别提醒:传感器背面是电子元件,请不要用手指直接接触, 以免静电或汗液造成背面器件损坏。 可以在背面粘贴黑色粘扣, 正面粘贴透明膜来保护传感器。

传感器的接口一共 3 个, 如上图红框内所示。 请大家千万不要根据线的颜色来自行推测, 而要根据电路板的背面标识来分辨。 红框中的 3 根线,标有 S 的为模拟信号输出线(最左边) ; 标有 的为电源输入线(中间);标有-的为地线(最右边) 。 总结一下: S → 脉搏信号输出(要接单片机 AD 接口)

VCC→ 5v(或 3.3v)电源输入

GND→ GND 地

3.6 PCB洞洞板

3.7 BLE低功耗蓝牙模块

4. 上位机程序设计

4.1 开发环境

上位机软件采用Qt框架设计,Qt是一个跨平台的C 图形用户界面应用程序框架。Qt是一个1991年由Qt Company开发的跨平台C 图形用户界面应用程序开发框架。它既可以开发GUI程序,也可用于开发非GUI程序,比如控制台工具和服务器。简单来说,QT可以很轻松的帮你做带界面的软件,甚至不需要你投入很大精力。

QT官网: https://www.qt.io/

QT学习入门实战专栏文章: https://blog.csdn.net/xiaolong1126626497/category_11400392.html

QT5.12.6的下载地址: https://download.qt.io/archive/qt/5.12/5.12.6/

打开下载链接后选择下面的版本进行下载:

qt-opensource-windows-x86-5.12.6.exe 13-Nov-2019 07:28 3.7G Details

软件安装时断网安装,否则会提示输入账户。

安装的时候,第一个复选框里勾选一个mingw 32编译器即可,其他的不管默认就行,直接点击下一步继续安装。

选择MinGW 32-bit 编译器:

选择MinGW 32-bit 编译器:

4.2 设计效果

5. STM32开发

如果需要项目完整的工程、系统原理图、相关的硬件资料,可以在这里去下载: https://download.csdn.net/download/xiaolong1126626497/85793557

5.1 硬件接线

代码语言:javascript复制
本设计的硬件接线说明: 
(1)BLE低功耗蓝牙模块
PA2(TX)--RXD 模块接收脚
PA3(RX)--TXD 模块发送脚
GND---GND 地
VCC---VCC 电源(3.3V)

(2)红外测温模块
PB10(TX)--RXD 模块接收脚
PB11(RX)--TXD 模块发送脚
GND---GND 地
VCC---VCC 电源(3.3V)

(3)MPU6050陀螺仪
1 VCC 3.3V/5V 电源输入     ---->接3.3V
2 GND 地线                  --->接GND
3 IIC_SDA IIC 通信数据线     -->PB6
4 IIC_SCL IIC 通信时钟线		   -->PB7
5 MPU_INT 中断输出引脚			 ---->未接
6 MPU_AD0 IIC 从机地址设置引脚-->未接
			AD0引脚说明:ID=0X68(悬空/接 GND) ID=0X69(接 VCC)
            
 (4)心率检测模块
PA1---心率模块的DAT输出脚
GND---GND 地
VCC---VCC 电源(3.3V)


(--)板载LED灯:低电平亮
LED1--PC13  
BEEP2--PC14

(--)板载按键: 
KEY1--PA0  按下为高电平

5.2 程序下载

将开发板连接电脑,打开程序下载软件,照着下图的说明进行下载。

5.3 系统原理图

5.4 keil工程

5.5 功能代码

代码语言:javascript复制
#include "stm32f10x.h"
#include "delay.h"
#include "led.h"
#include "key.h"
#include "sys.h"
#include "usart.h"
#include <string.h>
#include <stdlib.h>
#include "timer.h"
#include "adc.h"
#include "mpu6050.h"

/*---------心率相关的数据值---------------*/
extern int IBI;          //相邻节拍时间
extern int BPM;          //心率值             
extern int Signal;       //原始信号值            
extern unsigned char QS; //发现心跳标志

short aacx,aacy,aacz;		  //加速度传感器原始数据
short gyrox,gyroy,gyroz;	//陀螺仪原始数据
float TO=0;  //红外测温温度-目标温度
float TA=0;  //红外测温温度-物体温度
 

//蓝牙发送缓冲区
u8 BLE_TX_BUFF[100];

/*
主函数: 程序执行的入口
*/
int main(void)
{
    u32 i=0;
    u8 key_val;
    u32 wifi_TimeCnt=0;
    JTAG_Set();
    USART1_Init(115200);    //串口1的初始化
    USART2_Init(9600);      //串口-蓝牙
    TIMER2_Init(72,20000);  //超时时间20ms
    USART3_Init(9600);      //串口-红外线测温模块
    TIMER3_Init(36,20000);  //超时时间20ms
    
    //板载按键初始化
    KEY_Init();
    //板载LED灯初始化
    LED_Init();
    
    //ADC初始化
    ADC_Init(); 
    //超时时间2ms    
    TIMER1_Init(72,2000);  
    //初始化MPU6050
    while(MPU6050_Init())					
    {
        printf("三轴加速度计、陀螺仪初始化失败!rn");
        DelayMs(1000);
    }

    printf("系统工作正常..rn");
    
    while(1)
	{	
        //板载按键检测
        key_val=KEY_GetValue();
        if(key_val)
        {
            printf("按键按下...rn");
        }
        
        //时间记录
        DelayMs(10);
        wifi_TimeCnt  ;
        if(wifi_TimeCnt>=100) //1000毫秒一次
        {
            wifi_TimeCnt=0;
            LED1=!LED1;
            MPU6050_Get_Gyroscope(&gyrox,&gyroy,&gyroz);		//得到陀螺仪原始数据
            MPU6050_Get_Accelerometer(&aacx,&aacy,&aacz);		 //得到加速度传感器数据
            printf("三轴陀螺仪:x=%d y=%d z=%drn",gyrox,gyroy,gyroz);
            printf("三轴加速度:x=%d y=%d z=%drn",aacx,aacy,aacz);
            printf("(心率)BPM=%drn",BPM);
            
            //向蓝牙发送数据,发送给上位机
            //例如: update,12,13,14,15,20.5
            //分别表示:加速度X轴,加速度Y轴,加速度Z轴,心率、体温
            sprintf((char*)BLE_TX_BUFF,"update,%d,%d,%d,%d,%f",aacx,aacy,aacz,BPM,TO);
            USARTx_StringSend(USART2,(char*)BLE_TX_BUFF);
        }

       // 接收蓝牙返回的数据
        if(USART2_RX_FLAG)
        {
            USART2_RX_BUFFER[USART2_RX_CNT]='';
            
            printf("蓝牙收到数据:rn");
            //向串口打印服务器返回的数据
            for(i=0;i<USART2_RX_CNT;i  )
            {
                printf("%c",USART2_RX_BUFFER[i]);
            }
            USART2_RX_CNT=0;
            USART2_RX_FLAG=0;
        }
        
         //实时接收红外测温模块收到的数据
         if(USART3_RX_FLAG)
         {
             printf("rn红外测温开始:");
            for(i=0;i<USART3_RX_CNT;i  )
            {
                printf("%#x ",USART3_RX_BUFFER[i]);
            }
            printf("红外测温结束.rn");
            
            u8 sum=0,i=0;
            for(sum=0,i=0;i<(USART3_RX_BUFFER[3] 4);i  )
            {
                sum =USART3_RX_BUFFER[i];  
            }
            
            /*
温度计算方法 :
温度=高 8 位<<8|低 8 位(结果为实际角度乘以 100)
例:发送指令: A5 45 EA ,接收到一帧数据: <5A- 5A- 45- 04- 0C- 78- 0D- 19- A7 >
表示 TO(有符号 16bit,表示目标温度): TO=0x0C78/100=31.92 ℃
表示 TA(有符号 16bit,表示环境温度): TO=0x0D19/100=33.53 ℃
            */
            if(sum==USART3_RX_BUFFER[i])//校验和判断
            {
                TO=(float)((USART3_RX_BUFFER[4]<<8)|USART3_RX_BUFFER[5])/100.0;  //得到真实温度
                TA=(float)((USART3_RX_BUFFER[6]<<8)|USART3_RX_BUFFER[7])/100.0;  //得到真实温度	
            }
            
            printf("TO: %frn",TO);
            printf("TA: %frn",TA);
        
            memset(USART3_RX_BUFFER,0,sizeof(USART3_RX_BUFFER));
            USART3_RX_CNT=0;
            USART3_RX_FLAG=0;
         } 
    }        
}

0 人点赞