单片机课程设计:基于STM32的心率血氧检测报警系统

2023-10-19 00:59

本文主要是介绍单片机课程设计:基于STM32的心率血氧检测报警系统,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

基于STM32的血氧仪控制系统

  • 前言
  • 一、设计任务
  • 二、系统硬件设计
    • 1.元器件选用
    • 2.系统模型设计
    • 3.硬件连接
  • 三、系统程序设计
    • 1.程序流程
    • 2.主程序
  • 总结
  • 下载


前言

  本文使用搭载STM32F103VET6主控芯片的野火指南者、野火3.2寸LCD屏幕和MAX30102心率血氧传感器实现心率血氧采集并显示的效果。

(文末附完整程序下载链接)


一、设计任务

  1.可以通过MAX30102心率血氧传感器对用户的心率血氧进行采集,并用实时显示在LCD液晶屏上;
  2.可以设定一个固定的报警温度值显示在液晶屏上;
  3.用户心率低于60或者高于阈值报警、用户血氧低于阈值报警,报警形式包括:蜂鸣器发出滴滴声,LCD中心率血氧字符根据不同情况显示相应的报警颜色,报警颜色有红、蓝、品红;
  4.能够通过按键动态修改报警温度阈值;
  5.LCD显示屏下方绘制心率波形图;
  6.ESP8266将数据发送给TCP助手;

二、系统硬件设计

1.元器件选用

  1、STM32f103VET6单片机一块
  2、ESP8266一块
(此项目使用野火指南者,指南者自带ESP8266,其他型号单片机杜邦线自连即可)
  3、MAX30102心率血氧传感器
  4、3.2寸LCD显示器
  5、杜邦线5根

2.系统模型设计

  按键1设置心率阈值,按键2设置血氧阈值,MAX30102检测用户心率和血氧值。
  当检测的用户心率值大于心率阈值时LCD当前心率一栏变为红色、蜂鸣器报警、LED红灯闪烁、串口输出警告。
  当检测的用户心率值底于60时LCD当前心率一栏变为品红色、蜂鸣器报警、LED红灯闪烁、串口输出警告。
  当检测的用户血氧浓度小于血氧阈值时LCD显示血氧过低警告、蜂鸣器报警、蓝灯闪烁、串口输出心率过低警告。
  血氧波形图将检测到的血氧数据绘制出来,在未检测时y轴绘制为0。相应的颜色警告也会在波形图中显示。
  ESP8266将单片机采集的数据通过联网的方式发送到TCP助手中并显示。
max30102

正常值
WiFi连接
波形图显示

 演示视频:

波形显示

3.硬件连接

  1、本系统使用野火指南者,由于该单片机自带ESP8266,因此无需连接。如果使用其他型号单片机,根据ESP8266用户手册连接即可。
  2、STM32F103与MAX30102的连接,VCC<->3.3V,GND<->GND,SCL<->PC7,SDA<->PC8,IM<->PC9。

总电路连接图:
总电路图

三、系统程序设计

1.程序流程

  基于STM32的血氧仪控制系统总体软件的设计,可以分为系统初始化、数据采集、数据处理、数据显示和系统控制。系统初始化包括各模块的初始化,包括MAX30102模块、LCD显示模块、按键模块、蜂鸣器模块等。同时还需要初始化串口通信模块。
  采集数据主要是获取的血氧数据,进行数字转换和滤波处理,得到血氧饱和度和脉搏率数据。数据处理是对采集到的血氧饱和度和脉搏率数据进行处理。同时,还需要对数据进行校验和处理,确保数据的准确性和可靠性。将处理后的数据通过LCD显示模块显示出来。同时,还需要通过蜂鸣器模块进行声音提示,例如当血氧饱和度低于一定阈值时,发出警报声。系统控制即通过按键控制模块控制系统的工作模式,如调节警报阈值等。

程序设计流程图:
程序设计流程图
WiFi运行逻辑图:
在这里插入图片描述

2.主程序

项目部分程序示例。
main.c

int main()
{/* 初始化 */USART_Config ();    //初始化串口1NVIC_Configuration();CPU_TS_TmrInit();   //初始化DWT计数器,用于延时函数LED_Init();         //初始化RGB彩灯EXTI_Key_Config();  //KEY中断初始化BEEP_GPIO_Config(); //初始化蜂鸣器引脚ESP8266_Init();     //初始化WiFi模块使用的接口和外设ILI9341_Init();     //LCD 初始化  max30102_init();    //max30102初始化ILI9341_GramScan(6);    //LCD显示模式 	ESP8266_StaTcpClient_Unvarnish_ConfigTest();   //对ESP8266进行配置max30102_read();  //数据预处理LCD_SetFont(&Font8x16);  //LCD显示字体		LCD_SetColors(WHITE,BLACK);//LCD黑底白字,这样显示它别致ILI9341_Clear(0,0,LCD_X_LENGTH,LCD_Y_LENGTH);	/* 清屏,显示全黑 */while (1){max30102_control();  //max30102控制函数ESP8266_Sendmax30102DataTest();//LCD显示及串口\网络数据发送drawCurve(280,dis_hr);//LCD画波形,第一个参数是LCD显示起始位置,第二个是波形的数值}
}

max30102_control(); max30102控制函数

void max30102_control()
{i=0;un_min=0x3FFFF;un_max=0;//将前100组样本转储到存储器中,并将最后400组样本移到顶部for(i=100;i<500;i++){aun_red_buffer[i-100]=aun_red_buffer[i];aun_ir_buffer[i-100]=aun_ir_buffer[i];//update the signal min and maxif(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];}//在计算心率之前采集100组样本。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 numberaun_ir_buffer[i] = (long)((long)((long)temp[3] & 0x03)<<16) |(long)temp[4]<<8 | (long)temp[5];   // Combine values to get the actual numberif(aun_red_buffer[i]>un_prev_data){f_temp=aun_red_buffer[i]-un_prev_data;f_temp/=(un_max-un_min);f_temp*=MAX_BRIGHTNESS;n_brightness-=(int)f_temp;if(n_brightness<0)n_brightness=0;}else{f_temp=un_prev_data-aun_red_buffer[i];f_temp/=(un_max-un_min);f_temp*=MAX_BRIGHTNESS;n_brightness+=(int)f_temp;if(n_brightness>MAX_BRIGHTNESS)n_brightness=MAX_BRIGHTNESS;}//通过USART将样本和计算结果发送到终端程序if(ch_hr_valid == 1 && n_heart_rate<120){//**/ ch_hr_valid == 1 && ch_spo2_valid ==1 && n_heart_rate<120 && n_sp02<101dis_hr = n_heart_rate;dis_spo2 = n_sp02;}else{dis_hr = 0;dis_spo2 = 0;}}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);if(dis_hr == 0 && dis_spo2 == 0)  //**dis_hr == 0 && dis_spo2 == 0{sprintf((char *)str,"HR:--- SpO2:--- ");//**HR:--- SpO2:--- ILI9341_DispStringLine_EN_CH(LINE(4),"        当前心率:---");ILI9341_DispStringLine_EN_CH(LINE(6),"        当前血氧:---");}else{sprintf((char *)str,"HR:%3d SpO2:%3d ",dis_hr,dis_spo2);//**HR:%3d SpO2:%3d LCD_SetTextColor(GREEN);sprintf(get_hr_char,"        当前心率:%d ",dis_hr);LCD_ClearLine(LINE(4));ILI9341_DispStringLine_EN_CH(LINE(4),get_hr_char); 	LCD_SetTextColor(GREEN);sprintf(get_spo2_char,"        当前血氧:%d%%",dis_spo2);LCD_ClearLine(LINE(6));ILI9341_DispStringLine_EN_CH(LINE(6),get_spo2_char); }}

ESP8266_Sendmax30102DataTest();LCD显示以及数据发送

void ESP8266_Sendmax30102DataTest(void)
{char cStr[170]={0};uint8_t ucStatus;LCD_SetTextColor(WHITE);ILI9341_DispStringLine_EN_CH(LINE(1),"        血氧仪控制系统   ");LCD_SetTextColor(GREEN);sprintf(set_hr_char,"        心率阈值:%d ",set_hr_max);LCD_ClearLine(LINE(3));ILI9341_DispStringLine_EN_CH(LINE(3),set_hr_char); LCD_SetTextColor(GREEN);sprintf(set_spo2_char,"        血氧阈值:%d%%",set_spo2);LCD_ClearLine(LINE(5));ILI9341_DispStringLine_EN_CH(LINE(5),set_spo2_char); if(dis_hr == 0 && dis_spo2 == 0)  //max30102未检测{printf("Max30102 not detected!/r/n");LCD_SetTextColor(GREEN);LCD_ClearLine(LINE(18));LCD_ClearLine(LINE(19));PBout(5)=1;//灯灭PBout(1)=1;//灯灭BEEP( OFF );//蜂鸣器关}else{                            //max30102开始检测/* 显示血氧 */if(dis_spo2 >= set_spo2){                 LCD_ClearLine(LINE(19));LCD_SetTextColor(GREEN);//当前血氧一栏显示绿色sprintf(get_spo2_char,"        当前血氧:%d%% ",dis_spo2);LCD_ClearLine(LINE(6));	/* 清除单行文字 */ILI9341_DispStringLine_EN_CH(LINE(6),get_spo2_char);PBout(1)=1;//灯灭BEEP( OFF );//蜂鸣器关} else{   			//当前血氧低于阈值时颜色变蓝PBout(1)=0;//灯亮BEEP( ON );//蜂鸣器开LCD_SetTextColor(BLUE);LCD_ClearLine(LINE(6));	/* 清除单行文字 */sprintf(get_spo2_char,"        当前血氧:%d%% ",dis_spo2);ILI9341_DispStringLine_EN_CH(LINE(6),get_spo2_char);ILI9341_DispStringLine_EN_CH(LINE(19),"          血氧过低          ");printf("!!!血氧低于阈值!!!");         //串口输出}/* 显示心率 */if((dis_hr <= set_hr_max) && (dis_hr >= set_hr_min)){                 //当前心率一栏显示绿色LCD_ClearLine(LINE(18));LCD_SetTextColor(GREEN);LCD_ClearLine(LINE(4));	/* 清除单行文字 */sprintf(get_hr_char,"        当前心率:%d ",dis_hr);ILI9341_DispStringLine_EN_CH(LINE(4),get_hr_char);PBout(5)=1;//灯灭BEEP( OFF );//蜂鸣器关}else if( ( dis_hr <= set_hr_min ) && ( dis_hr != 0) ){LCD_SetTextColor(MAGENTA);LCD_ClearLine(LINE(4));	/* 清除单行文字 */sprintf(get_hr_char,"        当前心率:%d ",dis_hr);ILI9341_DispStringLine_EN_CH(LINE(4),get_hr_char);ILI9341_DispStringLine_EN_CH(LINE(18),"          心率低于60        ");printf("!!!心率低于60!!!");         //串口输出BEEP( ON );//蜂鸣器开PBout(5)=0;//灯亮}else{                              //当前心率超过阈值时颜色变红BEEP( ON );//蜂鸣器开PBout(5)=0;//灯亮LCD_SetTextColor(RED);LCD_ClearLine(LINE(4));	/* 清除单行文字 */sprintf(get_hr_char,"        当前心率:%d ",dis_hr);ILI9341_DispStringLine_EN_CH(LINE(4),get_hr_char);ILI9341_DispStringLine_EN_CH(LINE(18),"          心率过高          ");printf("!!!心率超出阈值!!!");         //串口输出}}if(dis_hr !=0 || dis_spo2 != 0 ){sprintf ( cStr, "POST /devices/92648495/datapoints?type=5 HTTP/1.1\napi-key:Yn2cDHrWmsTL62QUjHYu4RNtgPw=\nHost:api.zj.cmcconenet.com\nContent-Length:23\n\n,;xinlv,%3d;xueyang,%3d",dis_hr,dis_spo2);printf ( "%s", cStr );                                             //打印读取 DHT11 温湿度信息ESP8266_SendString ( ENABLE, cStr, 0, Single_ID_0 );               //发送 DHT11 温湿度信息到网络调试助手}if ( ucTcpClosedFlag ){                                             //检测是否失去连接ESP8266_ExitUnvarnishSend ();                                    //退出透传模式do ucStatus = ESP8266_Get_LinkStatus ();                         //获取连接状态while ( ! ucStatus );if ( ucStatus == 4 ){                                             //确认失去连接后重连printf ( "\r\n正在重连热点和服务器 ......\r\n" );while ( ! ESP8266_JoinAP ( macUser_ESP8266_ApSsid, macUser_ESP8266_ApPwd ) );  while ( !	ESP8266_Link_Server ( enumTCP, macUser_ESP8266_TcpServer_IP, macUser_ESP8266_TcpServer_Port, Single_ID_0 ) );printf ( "\r\n重连热点和服务器成功\r\n" );}while ( ! ESP8266_UnvarnishSend () );		}
}

drawCurve(280,dis_hr);LCD画波形,第一个参数是LCD显示起始位置,第二个是波形的数值

void drawCurve(int coord_x,short int rawValue)  
{//coord_xLCD显示起始位置坐标u16 x,y;int rawValue_value;rawValue_value = rawValue*280;//rawValue_value波形高度,280可修改y = coord_x - rawValue_value/280;  	//数据处理代码//这里之所以是120-rawValue/280,与屏幕的扫描方向有关,如果出现上下颠倒的情况,可以改成120 + if(firstPoint){//如果是第一次画点,则无需连线,直接描点即可ILI9341_SetPointPixel(10,y);lastX=0;lastY=y;firstPoint=0;}else{x=lastX+1;if(x<240){  //不超过屏幕宽度ILI9341_DrawLine(lastX,lastY,x,y);lastX=x;lastY=y;}else{  //超出屏幕宽度,清屏,从第一个点开始绘制,实现动态更新效果ILI9341_Clear(0,0,LCD_X_LENGTH,LCD_Y_LENGTH);	/* 清屏,显示全黑 */ILI9341_SetPointPixel(10,y);lastX=0;lastY=y;}}
}

总结

  基于STM32的血氧仪控制系统是一个适合初学者的STM32设计,本系统设计包含了GPIO的配置、ESP8266的配置与使用、传感器MAX30102的使用、按键中断、串口发送信息、LCD显示等的使用。本系统主要部分即心率血氧采集和WiFi数据传输,比较适合初学者学习理论知识后对知识的总结和融会贯通。

下载

  下载包所含基于STM32的血氧仪控制系统程序一份,流程图、原理图若干。
在这里插入图片描述

下载地址1:http://cloud.tao-space.top/2023/05/28/13/595/

这篇关于单片机课程设计:基于STM32的心率血氧检测报警系统的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/236236

相关文章

什么是cron? Linux系统下Cron定时任务使用指南

《什么是cron?Linux系统下Cron定时任务使用指南》在日常的Linux系统管理和维护中,定时执行任务是非常常见的需求,你可能需要每天执行备份任务、清理系统日志或运行特定的脚本,而不想每天... 在管理 linux 服务器的过程中,总有一些任务需要我们定期或重复执行。就比如备份任务,通常会选在服务器资

TP-LINK/水星和hasivo交换机怎么选? 三款网管交换机系统功能对比

《TP-LINK/水星和hasivo交换机怎么选?三款网管交换机系统功能对比》今天选了三款都是”8+1″的2.5G网管交换机,分别是TP-LINK水星和hasivo交换机,该怎么选呢?这些交换机功... TP-LINK、水星和hasivo这三台交换机都是”8+1″的2.5G网管交换机,我手里的China编程has

基于Qt实现系统主题感知功能

《基于Qt实现系统主题感知功能》在现代桌面应用程序开发中,系统主题感知是一项重要的功能,它使得应用程序能够根据用户的系统主题设置(如深色模式或浅色模式)自动调整其外观,Qt作为一个跨平台的C++图形用... 目录【正文开始】一、使用效果二、系统主题感知助手类(SystemThemeHelper)三、实现细节

CentOS系统使用yum命令报错问题及解决

《CentOS系统使用yum命令报错问题及解决》文章主要讲述了在CentOS系统中使用yum命令时遇到的错误,并提供了个人解决方法,希望对大家有所帮助,并鼓励大家支持脚本之家... 目录Centos系统使用yum命令报错找到文件替换源文件为总结CentOS系统使用yum命令报错http://www.cppc

不懂推荐算法也能设计推荐系统

本文以商业化应用推荐为例,告诉我们不懂推荐算法的产品,也能从产品侧出发, 设计出一款不错的推荐系统。 相信很多新手产品,看到算法二字,多是懵圈的。 什么排序算法、最短路径等都是相对传统的算法(注:传统是指科班出身的产品都会接触过)。但对于推荐算法,多数产品对着网上搜到的资源,都会无从下手。特别当某些推荐算法 和 “AI”扯上关系后,更是加大了理解的难度。 但,不了解推荐算法,就无法做推荐系

基于人工智能的图像分类系统

目录 引言项目背景环境准备 硬件要求软件安装与配置系统设计 系统架构关键技术代码示例 数据预处理模型训练模型预测应用场景结论 1. 引言 图像分类是计算机视觉中的一个重要任务,目标是自动识别图像中的对象类别。通过卷积神经网络(CNN)等深度学习技术,我们可以构建高效的图像分类系统,广泛应用于自动驾驶、医疗影像诊断、监控分析等领域。本文将介绍如何构建一个基于人工智能的图像分类系统,包括环境

水位雨量在线监测系统概述及应用介绍

在当今社会,随着科技的飞速发展,各种智能监测系统已成为保障公共安全、促进资源管理和环境保护的重要工具。其中,水位雨量在线监测系统作为自然灾害预警、水资源管理及水利工程运行的关键技术,其重要性不言而喻。 一、水位雨量在线监测系统的基本原理 水位雨量在线监测系统主要由数据采集单元、数据传输网络、数据处理中心及用户终端四大部分构成,形成了一个完整的闭环系统。 数据采集单元:这是系统的“眼睛”,

综合安防管理平台LntonAIServer视频监控汇聚抖动检测算法优势

LntonAIServer视频质量诊断功能中的抖动检测是一个专门针对视频稳定性进行分析的功能。抖动通常是指视频帧之间的不必要运动,这种运动可能是由于摄像机的移动、传输中的错误或编解码问题导致的。抖动检测对于确保视频内容的平滑性和观看体验至关重要。 优势 1. 提高图像质量 - 清晰度提升:减少抖动,提高图像的清晰度和细节表现力,使得监控画面更加真实可信。 - 细节增强:在低光条件下,抖

嵌入式QT开发:构建高效智能的嵌入式系统

摘要: 本文深入探讨了嵌入式 QT 相关的各个方面。从 QT 框架的基础架构和核心概念出发,详细阐述了其在嵌入式环境中的优势与特点。文中分析了嵌入式 QT 的开发环境搭建过程,包括交叉编译工具链的配置等关键步骤。进一步探讨了嵌入式 QT 的界面设计与开发,涵盖了从基本控件的使用到复杂界面布局的构建。同时也深入研究了信号与槽机制在嵌入式系统中的应用,以及嵌入式 QT 与硬件设备的交互,包括输入输出设

JAVA智听未来一站式有声阅读平台听书系统小程序源码

智听未来,一站式有声阅读平台听书系统 🌟&nbsp;开篇:遇见未来,从“智听”开始 在这个快节奏的时代,你是否渴望在忙碌的间隙,找到一片属于自己的宁静角落?是否梦想着能随时随地,沉浸在知识的海洋,或是故事的奇幻世界里?今天,就让我带你一起探索“智听未来”——这一站式有声阅读平台听书系统,它正悄悄改变着我们的阅读方式,让未来触手可及! 📚&nbsp;第一站:海量资源,应有尽有 走进“智听