基于max30102的物联网病房监测系统(中断处理和主题逻辑)

news/2024/5/19 1:56:17/文章来源:https://blog.csdn.net/qq_52479948/article/details/130504380

目录

五、中断处理

六、主体框架

对采集数据的初始化

核心功能的实现

烟雾

通信帧格式

wifi接收数据的处理

OLED显示


 

五、中断处理

void SysTick_Handler(void)
{TimingDelay_Decrement();
}void ESP8266_USART_INT_FUN(void)
{uint8_t ucCh;if ( USART_GetITStatus (ESP8266_USARTx, USART_IT_RXNE ) != RESET ){ucCh  = USART_ReceiveData(ESP8266_USARTx );if ( strEsp8266_Fram_Record .InfBit .FramLength < ( RX_BUF_MAX_LEN - 1 ) )                       //预留1个字节写结束符strEsp8266_Fram_Record .Data_RX_BUF [ strEsp8266_Fram_Record .InfBit .FramLength ++ ]  = ucCh;}if ( USART_GetITStatus(ESP8266_USARTx, USART_IT_IDLE ) == SET )                                         //数据帧接收完毕{strEsp8266_Fram_Record .InfBit .FramFinishFlag = 1;ucCh = USART_ReceiveData(ESP8266_USARTx );ucTcpClosedFlag = strstr(strEsp8266_Fram_Record .Data_RX_BUF, "CLOSED\r\n" ) ? 1 : 0;}
}void ADC_IRQHandler_FUN(void)
{if(ADC_GetITStatus(ADCx,ADC_IT_EOC)!=RESET){ADC_ClearITPendingBit(ADCx,ADC_IT_EOC);/* 读取ADC的转换值 */ADC_ConvertedValue = ADC_GetConversionValue(ADCx);}
}

主要就是3个ESP8266的通信中断,定时器中断和ADC采集中断

六、主体框架

对采集数据的初始化

 for(i=0;i<n_ir_buffer_length;i++){while(MAX30102_INT==1);   //wait until the interrupt pin assertsmax30102_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(un_min>aun_red_buffer[i])un_min=aun_red_buffer[i];    //update signal minif(un_max<aun_red_buffer[i])un_max=aun_red_buffer[i];    //update signal max}un_prev_data=aun_red_buffer[i];//calculate heart rate and SpO2 after first 500 samples (first 5 seconds of samples)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); 
		//dumping the first 100 sets of samples in the memory and shift the last 400 sets of samples to the topfor(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];}//take 100 sets of samples before calculating the heart rate.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;}//send samples and calculation result to terminal program through UARTif(ch_hr_valid == 1 && n_heart_rate<120)//**/ ch_hr_valid == 1 && ch_spo2_valid ==1 && n_heart_rate<120 && n_sp02<101{dis_hr = n_heart_rate;dis_spo2 = n_sp02;}else{dis_hr = 0;dis_spo2 = 0;}
//				printf("HR=%i, ", n_heart_rate); 
//				printf("HRvalid=%i, ", ch_hr_valid);
//				printf("SpO2=%i, ", n_sp02);
//				printf("SPO2Valid=%i\r\n", ch_spo2_valid);}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(order[0] == 1){show2(order[1],order[2],order[3],order[4]);Delay_ms(500);printf("可燃气体浓度  %f\r\n", Smog_GetPPM());if(order[1] == 1){LED1_ON;}else{LED1_OFF;}if(order[2] == 1){LED2_ON;}else{LED2_OFF;}if(order[3] == 1){LED3_ON;}else{LED3_OFF;}if(order[4] == 1){BEEP_StateSet(BEEPState_ON);}else{BEEP_StateSet(BEEPState_OFF);}			}else{sprintf(cStr,"%d+%d+%d+%d+%d+%d+%d",DHT11_Data.temp_int,DHT11_Data.humi_deci,DHT11_Data.temp_int,DHT11_Data.temp_deci,dis_hr,dis_spo2,m);ESP8266_SendString(ENABLE,cStr,0,Single_ID_0);  show((u8 *)temp_1,(u8 *)hum_2,(u8 *)s_3,(u8 *)o_4);if( DHT11_Data.temp_int > order[1] || DHT11_Data.temp_int < order[2] ){LED1_ON;LED2_OFF;LED3_OFF;BEEP_StateSet(BEEPState_ON);Delay_ms(1000);}else if( DHT11_Data.humi_int > order[3] || DHT11_Data.humi_int < order[4] ){LED2_ON;LED1_OFF;LED3_OFF;BEEP_StateSet(BEEPState_ON);Delay_ms(1000);}else if( dis_hr > order[6] || dis_hr < order[5]){if( dis_hr == 0){}else{LED1_ON;LED2_ON;LED3_OFF;BEEP_StateSet(BEEPState_ON);Delay_ms(1000);}}else if( dis_spo2 < order[7] || dis_spo2 > order[8]){if( dis_spo2 == 0){}else{LED2_ON;LED3_ON;LED1_OFF;BEEP_StateSet(BEEPState_ON);Delay_ms(1000);}}else if(m == 1){LED1_OFF;LED2_OFF;LED3_ON;BEEP_StateSet(BEEPState_ON);Delay_ms(1000);}else{LED1_OFF;LED2_OFF;LED3_OFF;BEEP_StateSet(BEEPState_OFF);	Delay_ms(1000);}LED1_OFF;LED2_OFF;LED3_OFF;BEEP_StateSet(BEEPState_OFF);}

我把服务器数据重新转换放到了数组中,再用一个大分支结构对其中的数据进行判别然后实现对应功能。

烟雾

读取电压值 

float Smog_Get_Vol(void)
{u16 adc_value = 0;//这是从MQ-7传感器模块电压输出的ADC转换中获得的原始数字值,该值的范围为0到4095,将模拟电压表示为数字值float voltage = 0;//MQ-7传感器模块的电压输出,与一氧化碳的浓度成正比adc_value = ADC_ConvertedValue;//#define SMOG_ADC_CHX	ADC_Channel_4	定义烟雾传感器所在的ADC通道编号Delay_ms(5);voltage  = (3.3/4096.0)*(adc_value);return voltage;
}

/*********************
// 传感器校准函数,根据当前环境PPM值与测得的RS电压值,反推出R0值。
// 在空气中运行过后测出R0为26
float MQ7_PPM_Calibration()
{
    float RS = 0;
    float R0 = 0;
    RS = (3.3f - Smog_Get_Vol()) / Smog_Get_Vol() * RL;//RL    10  // RL阻值
    R0 = RS / pow(CAL_PPM / 98.322, 1 / -1.458f);//CAL_PPM  10  // 校准环境中PPM值
    return R0;
}
**********************/ 

// 计算Smog_ppm
float Smog_GetPPM()
{float RS = (3.3f - Smog_Get_Vol()) / Smog_Get_Vol() * RL;float ppm = 98.322f * pow(RS/R0, -1.458f);}

通信帧格式

接收帧格式

模式 1
1 LED1 LED2 LED3 BEEP
每个功能一位控制 1开 0关

模式2

0 两位数表示温度上限 左高位右低位 温度下限 湿度上限 湿度下限 心率用一位表示 0 1 2 分别为 小孩 成年人 老人 输入其它数值表示是个人就行 两位表示血氧下限 左高右低
模式2接收一共12位

050108020490

发送帧格式
sprintf(cStr,"%d+%d+%d+%d+%d+%d+%d",DHT11_Data.temp_int,DHT11_Data.humi_deci,DHT11_Data.temp_int,DHT11_Data.temp_deci,dis_hr,dis_spo2,m);
温度整数+温度小数+湿度整数+湿度小数+心率+血氧饱和度+是否有可燃气体

wifi接收数据的处理

 由于接收到的是字符串,所以剪掉字符0变成整数,传多位数据的时候乘10改变位置就行。

主要是确保数据不会出错。暂时没使用任何协议,算是自己指定了一个没有校验的简单协议吧。以后有机会改成MQTT格式或者MODBUS格式的协议。

u32* wifi_rec(void)
{u32 pCH;int i;ESP8266_ReceiveString(ENABLE);if ( strEsp8266_Fram_Record .InfBit .FramFinishFlag ){strEsp8266_Fram_Record .Data_RX_BUF [ strEsp8266_Fram_Record .InfBit .FramLength ]  = '\0';printf ( "\r\n%s\r\n", strEsp8266_Fram_Record .Data_RX_BUF );if(strEsp8266_Fram_Record .Data_RX_BUF[0] == '1'){for(i = 0; i < 12;i++){order[i] = strEsp8266_Fram_Record .Data_RX_BUF[i] - '0';}	}else{for(i = 0; i < 9;i++){if (i == 0)order[i] = strEsp8266_Fram_Record .Data_RX_BUF[i] - '0';else{if( i % 2 == 0){order[i/2] = (((strEsp8266_Fram_Record .Data_RX_BUF[i-1] - '0') * 10) + (strEsp8266_Fram_Record .Data_RX_BUF[i] - '0'));}}}//0 模式 1234 温湿度 56心率 78血氧//第九位 0 1 2 小孩 成年人 老人   80-140  60-100  55-75  switch(strEsp8266_Fram_Record .Data_RX_BUF[9]){case 0:order[5] = 80;order[6] = 140;break;case 1:order[5] = 60;order[6] = 100;break;case 2:order[5] = 55;order[6] = 75;break;default:order[5] = 40;order[6] = 160;break;}//血氧饱和度正常人 90 - 100order[7] = (((strEsp8266_Fram_Record .Data_RX_BUF[10] - '0') * 10) + (strEsp8266_Fram_Record .Data_RX_BUF[11] - '0'));printf("血氧下限 %d",order[7]);order[8] = 100;}/*将接收到的字符串转成整形数*/pCH=atoi(strEsp8266_Fram_Record .Data_RX_BUF);switch(pCH){case 0:break;case 1:break;case 2:break;}         }  return order;
}

OLED显示

void show(uint8_t *a,uint8_t *b, uint8_t *c, uint8_t *o)
{OLED_CLS();//清屏OLED_ShowCN(0,0,26);//温OLED_ShowCN(16,0,27);//度OLED_ShowCN(32,0,14);//:OLED_ShowStr(48,0,a,2);		//2表示8X16OLED_ShowCN(0,2,28);//湿OLED_ShowCN(16,2,27);//度OLED_ShowCN(32,2,14);//:OLED_ShowStr(48,2,b,2);		//2表示8X16OLED_ShowCN(0,4,29);//心OLED_ShowCN(16,4,30);//率OLED_ShowCN(32,4,14);//:OLED_ShowStr(48,4,c,2);		//2表示8X16OLED_ShowCN(0,6,37);//血OLED_ShowCN(16,6,38);//氧OLED_ShowCN(32,6,14);//:OLED_ShowStr(48,6,o,2);		//2表示8X16
}

上面是自主更新,下面是被控制模式,由于服务器童鞋没写远程改上下限功能,我的这部分也被注释掉了。真要用还得调试一下,毕竟没检验过。 

void show2(u32 a,u32 b, u32 c, u32 o)
{OLED_CLS();//清屏OLED_ShowCN(0,0,41);//红OLED_ShowCN(16,0,44);//灯OLED_ShowCN(32,0,14);//:if(a  == 1){OLED_ShowCN(48,0,46);//开}else{OLED_ShowCN(48,0,47);//关}OLED_ShowCN(0,2,45);//绿OLED_ShowCN(16,2,44);//灯OLED_ShowCN(32,2,14);//:if(b  == 1){OLED_ShowCN(48,2,46);//开}else{OLED_ShowCN(48,2,47);//关}OLED_ShowCN(0,4,42);//黄OLED_ShowCN(16,4,44);//灯OLED_ShowCN(32,4,14);//:if(c  == 1){OLED_ShowCN(48,4,46);//开}else{OLED_ShowCN(48,4,47);//关}OLED_ShowStr(0,6,(u8*)"BEEP",2);OLED_ShowCN(32,6,14);//:if(o  == 1){OLED_ShowCN(48,6,46);//开}else{OLED_ShowCN(48,6,47);//关}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_484545.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【ROS】如何让ROS中节点实现数据交换Ⅰ--ROS话题通信

Halo&#xff0c;这里是Ppeua。平时主要更新C语言&#xff0c;C&#xff0c;数据结构算法…感兴趣就关注我吧&#xff01;你定不会失望。 目录 0.ROS文件系统及常用指令1.话题通信概念2.利用标准消息类型实现话题通信实现(python)2.1发布方实现2.2订阅方实现 3.利用自定义消息类…

SPSS如何进行使用时间序列模型之案例实训?

文章目录 0.引言1.时间序列数据平稳处理2.指数平滑法建模3.ARIMA建模4.季节性分解 0.引言 因科研等多场景需要进行绘图处理&#xff0c;笔者对SPSS进行了学习&#xff0c;本文通过《SPSS统计分析从入门到精通》及其配套素材结合网上相关资料进行学习笔记总结&#xff0c;本文对…

【Git】制造冲突以及解决冲突的详细方法

介绍 这里是小编成长之路的历程&#xff0c;也是小编的学习之路。希望和各位大佬们一起成长&#xff01; 以下为小编最喜欢的两句话&#xff1a; 要有最朴素的生活和最遥远的梦想&#xff0c;即使明天天寒地冻&#xff0c;山高水远&#xff0c;路远马亡。 一个人为什么要努力&a…

编译原理笔记(一)引论

文章目录 1.什么是编译程序2.编译过程和编译程序的结构2.1.编译过程概述2.2.编译程序的结构2.3.编译阶段的组合 3.解释程序和一些软件工具3.1.解释程序3.2.处理源程序的软件工具 4.PL/0语言编译系统 学习总结&#xff1a;这一部分是编译原理的绪论部分内容&#xff0c;对编译程…

神经网络结构搜索NAS

推荐课程&#xff1a;神经网络结构搜索 感谢博主ShusenWang提供的课程讲解&#xff01; 目录 1. 为什么要学习神经网络结构搜索NAS&#xff1f; 2. 什么是神经网络结构搜索NAS&#xff1f; &#xff08;1&#xff09;随机搜素Random Search 1. 为什么要学习神经网络结构搜…

漫天花雨HTML特效+3D相册

大家好&#xff0c;我是csdn的博主&#xff1a;lqj_本人 这是我的个人博客主页&#xff1a; lqj_本人的博客_CSDN博客-微信小程序,前端,python领域博主lqj_本人擅长微信小程序,前端,python,等方面的知识https://blog.csdn.net/lbcyllqj?spm1011.2415.3001.5343哔哩哔哩欢迎关注…

or-tools 应用案例分析:复杂作业车间调度问题

作业调度问题是常见的线性规划(整数规划)问题&#xff0c;其中多个作业在多台机器上处理。每个作业由一系列任务组成&#xff0c;这些任务必须按给定的顺序执行&#xff0c;并且每个任务都必须在特定的机器上处理。如何有效的利用所有的机器在最短的时间内完成所有的作业任务&a…

调试别人的API,一般有哪些步骤?

当我们使用了一些由别人实现的API接口时&#xff0c;该如何进行调试呢&#xff1f;当我们使用的API返回一些意想不到错误时&#xff0c;该怎么办呢?这个问题可能是由于用户输入或者API本身&#xff0c;或者其他完全无关的内容等引起的。调试是我们进行定位并修复由单个API调用…

[杂谈]从《天堂2》到永恒之塔私服的感慨

不才在下是个老丫头了&#xff0c;平时喜欢潜水&#xff0c;还是在玩激战时注册的多玩论坛号&#xff0c;也不怎么说话&#xff0c;都是看别人说得多&#xff08;害羞嘛……&#xff09;。 想当年《天堂二》内测时&#xff0c;刚好在成都开了个内测号 首发会&#xff0c;我大清…

Linux 五种网络IO模式(阻塞IO、非阻塞IO、IO多路复用、信号驱动IO、异步IO)

Linux网络编程中&#xff0c;有五种网络IO模式&#xff0c;分别是阻塞IO、非阻塞IO、IO多路复用、信号驱动IO、异步IO&#xff1b; 虽然说不能全都认识得很透彻&#xff0c;但至少得都知道一点&#xff01; 开始之前&#xff0c;先了解以下同步IO和异步IO&#xff1b; 1. 同步…

linux0.12-8-4-sys_call.s

[301页] 8-4 sys_call.s 程序 sys_call.s 程序简单总结&#xff1a; int 0x80 – _system_call int16 – 处理器错误中断 int7 – 设备不存在或协处理器不存在。 int32 – (int 0x20)时钟中断处理程序。 两个系统功能的底层接口&#xff0c;分别是 sys_execve 和 sys_fork 。…

【JVM】面试题总结

JVM 1、JVM 的运行时内存区域是怎样的2、堆和栈的区别3、Java 中的对象一定在堆上分配内存吗4、什么是 Stop The World5、JVM 如何判断对象是否存活6、JVM 有哪些垃圾回收算法7、什么是三色标记算法8、新生代和老年代的GC算法9、新生代和老年代的垃圾回收器有何区别10、Java 中…

MYSQL用户组管理

1&#xff1a;使用明文密码创建用户 使用密文密码创建用户 1.2 查看用户信息 1.3 重命名用户 rename 1.4 删除用户信息 drop 1.5 修改当前登录用户的密码 set password password(123456); 1.6 修改其他用户的密码 set password for nancylocalhost password(abc123); 1.7…

电子价签能给生鲜零售带来什么?

生鲜零售 变价难 超市中的水果、蔬菜、鱼肉海鲜等商品&#xff0c;往往会受季节变化、运输和储存成本、自然环境引起的生产成本、供需关系等因素影响&#xff0c;其商品价格变动比较频繁。如不能及时更新价格&#xff0c;容易影响商品的销售&#xff0c;进而影响超市的盈利能…

【致敬未来的攻城狮计划】第2期定向赠书《RT-Thread设备驱动开发指南》+ 《GD32 MCU原理及固件库开发指南》

开启攻城狮的成长之旅&#xff01;这是我参与的由 CSDN博客专家 架构师李肯&#xff08;超链接&#xff1a;http://yyds.recan-li.cn&#xff09;和 瑞萨MCU &#xff08;超链接&#xff1a;瑞萨电子 (Renesas Electronics Corporation)&#xff09; 联合发起的「 致敬未来的攻…

测试用例覆盖不全面的解决方法

测试用例覆盖不全面的解决方法 问题分析 在测试用例设计过程中&#xff0c;容易出现思维受限或者需求盲区&#xff0c;我们不可能完全覆盖用户使用的所有场景&#xff0c;编写测试用例的时不可能把所有的场景都能想周全&#xff0c;把所有的场景下的情况都写成测试用例去模拟、…

儿童书写台灯哪个牌子比较好?盘点护眼学生用台灯品牌排行

想要拥有一个健康的视力对于我们多么重要&#xff0c;日常生活多么不便利&#xff0c;就是像家里孩子考学时视力也是对于未来专业选择的一个阻碍。 想要孩子不吃近视的苦&#xff0c;从小就要开始抓孩子对于视力和眼睛的呵护。 养成好习惯必须保持一个正确的学习姿势&#xff…

基于pytorch+transformers的车牌识别

目录 程序流程设计熟悉训练数据集CCPD2019数据集CCPD数据集标注信息单例再现 加载本地车牌数据集 程序流程设计 1&#xff0c;熟悉训练数据集&#xff1b; 2&#xff0c;加载本地车牌数据集&#xff1b; 3&#xff0c;定义网络模型&#xff1b; 4&#xff0c;输入数据集训练模…

Baumer工业相机堡盟工业相机如何联合BGAPISDK和Halcon实现图像的线性灰度变换ScaleImage算法增强(C#)

Baumer工业相机堡盟工业相机如何联合BGAPISDK和Halcon实现图像的线性灰度变换算法增强&#xff08;C#&#xff09; Baumer工业相机Baumer工业相机使用图像算法增加图像的技术背景Baumer工业相机通过BGAPI SDK联合Halcon使用线性灰度变换增强算法1.引用合适的类文件2.BGAPI SDK在…

「STC8A8K64D4开发板」——外部中断(INT0~INT4)

第2-4讲&#xff1a;外部中断(INT0~INT4) 学习目的学习中断的相关概念。掌握外部中断配置及中断优先级配置的程序设计。掌握中断服务程序的编写。 中断相关概念 什么是中断 中断系统是为使 CPU 具有对外界紧急事件的实时处理能力而设置的。 CPU在处理某一事件A时&#xff0c…