0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

基于STM32+ESP8266+华为云IoT设计的健康管理系统并完成应用侧开发

DS小龙哥-嵌入式技术 来源:DS小龙哥-嵌入式技术 作者:DS小龙哥-嵌入式技 2023-07-11 09:09 次阅读

一、前言

近几年随着科技的进步和智能化浪潮的到来,智能穿戴设备也在飞速火爆发展,各种健康智能手环,智能手表、智能跑鞋、智能眼镜纷纷上市,并出现了很多针对个人家庭的健康管理设备。比如: 智能血压计、智能心率检测、脂肪秤、智能体重秤等等,都带上了智能、健康各种标签

可穿戴设备,即直接穿在身上,或是整合到用户的衣服或配件的一种便携式设备。可穿戴设备不仅仅是一种硬件设备,更是通过软件支持以及数据交互、云端交互来实现强大的功能,可穿戴设备将会对生活、感知带来很大的转变。

这篇文章就利用STM32加上各种外设传感器配合华为云IOT物联网平台设计一个健康管理设备,通过ESP8266+MQTT协议将数据传输导致华为云物联网平台,并通过华为云的应用侧完成应用层软件开发;设计本项目的目的就是,上手体验华为云物联网平台,并探究一下智能设备的实现原理。

当前设计的监控管理设备支持的功能有: (1)人体温度测量 (2)运动监测、计步功能 (3)睡眠监测 (4)心率测量

STM32采集这些传感器数据之后,进行处理,在本地OLED显示屏上完成显示;再通过ESP8266将数据传递到华为云物联网平台,关联数据可视化大屏完成数据展示。

下面是示波器测量的心率显示

image-20220113113247970

设备运行效果:

image-20220113105130355

image-20220113170207055

二、硬件介绍

2.1 主控芯片

主控芯片采用STM32F103C8T6,它一款基于ARM Cortex-M 内核STM32系列的32位的微控制器,程序存储器容量是64KB,RAM空间是20K,工作电压2V~3.6V,运行速度72MHZ。

image-20220113113146484

2.2 体温测量

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

image-20220113105156144

2.3 心率测量

心率测量,采用PulseSensor传感器,这是一款用于脉搏心率测量的光电反射式模拟传感器,通过模拟输出口可将采集到的模拟信号传输给 STM32单片机用来转换为数字信号,再通过单片机简单计算后就可以得到心率数值。

image-20220113105210621

2.4 计步、睡眠监测功能

计步模块,睡眠监测,运动监测功能采用MUP6050陀螺仪实现,这是一款高性能三轴加速度+三轴陀螺仪的六轴传感器,该模块采用InvenSense 公司的 MPU6050 芯片作为核心, 该芯片内部整合了3轴陀螺仪和3轴加速度传感器,并可利用自带的数字运动处理器硬件加速引擎,通过主 IIC 接口,向应用端输出姿态解算后的数据。有了DMP,可以使用 InvenSense 公司提供的运动处理资料库,非常方便的实现姿态解算,降低了运动处理运算对操作系统的负荷,同时大大降低了开发难度。 MPU6050 模块具有:体积小、自带 DMP、 自带温度传感器、 支持 IIC 从机地址设置和中断、兼容 3.3V/5V 系统、使用方便等特点。

image-20220113105326453

(5)本地数据显示用的OLED显示屏采用0.96寸的SPI接口显示屏,分辨率为 128*64,主要是在本地显示采集的数据,时间等信息

image-20220113105602232

(6)上网的模块采用ESP8266,ESP8266是物联网领域常见无线网卡芯片,支持AT指令,支持串口协议控制,只需要几个简单的AT指令就可以完成网络连接,数据传输。当前项目里,就是通过ESP8266将采集的数据传递到华为云IOT平台,实现数据展示。

image-20220113105659834

三、创建IOT产品、上云测试

3.1 创建产品

官网地址: https://www.huaweicloud.com/s/JeeJqeiBlOe9kSU

选择IOTDA进入,选择免费试用。

image-20220113111627259

image-20220113111713754

在产品页面,选择右上角创建产品。

image-20220113111757856

根据提示,填入对应参数

image-20220113112005762

创建好之后,查看产品详情,进入属性配置页面。

image-20220113112059026

选择自定义模型。

image-20220113112129287

添加服务。

image-20220113112224296

接下来就添加属性,属性就是传感器上传的数据类型,需要展示的数据;根据自己传感器的数量、类型自己设置即可。

添加心率传感器数据属性。

image-20220113112431629

添加体温传感器数据属性。

image-20220113112528866

添加计步功能的数据属性。

image-20220113112657761

创建成功:

image-20220113112841104

3.2 注册设备

打开设备页面,点击右上角注册设备按钮,根据提示和产品的信息填入;创建完保存得到的信息。

image-20220113113532461

点击确定之后,创建成功效果如下;目前设备还未激活,需要设备登录一次服务器即可激活;接下来就是如何登录了。

image-20220113113713819

3.3 设备上云测试

完成产品、设备创建之后,接下来采用MQTT客户端模拟设备,测试是否可以正常上华为云。

连接协议使用MQTT协议,MQTT协议登录服务器,就像QQ登录一样,需要输入账号、密码等一些信息;下面先利用华为云的小工具完成这些数据的创建。

华为云提供的MQTT账户信息生成在线小工具: https://iot-tool.obs-website.cn-north-4.myhuaweicloud.com/

前面两行填入的数据,在创建设备成功时提示下载的文件里有,照着填写即可。

image-20220113114545591

我的设备生成的数据如下:

ClientId   61df9a6bc7fb24029b0c160d_1126626497_0_0_2022011303
 Username   61df9a6bc7fb24029b0c160d_1126626497
 Password   20618c172eb24418e0910804889c7d2074a5847e9e7205a41a8bf5adeec399f9

华为云IOT平台的MQTT服务器地址信息如下:

端口: 1883
 域名: a161a58a78.iot-mqtts.cn-north-4.myhuaweicloud.com
 IP地址: 121.36.42.100

华为云IOT平台MQTT协议订阅主题的格式:

格式: $oc/devices/{device_id}/sys/messages/down
 //订阅主题: 平台下发消息给设备
 $oc/devices/61df9a6bc7fb24029b0c160d_1126626497/sys/messages/down

华为云IOT平台MQTT协议上报主题的格式:

格式: $oc/devices/{device_id}/sys/properties/report
 //设备上报主题请求
 $oc/devices/61df9a6bc7fb24029b0c160d_1126626497/sys/properties/report
 ​
 ​
 //上报的数据格式如下
 {"services": [{"service_id": "healthy","properties":{"HeartRate":127}},{"service_id": "healthy","properties":{"motion":2000}},{"service_id": "healthy","properties":{"temperature":36.2}}]}

打开MQTT客户端,填入对应数据,连接华为云物联网平台:

如需使用和我一样的同款软件,打开百度搜索MQTT客户端_v2.4(协议3.1.1).exe 即可找到下载地址。

image-20220113115522655

登录成功后,查看华为云页面,可以看到设备已经在线,并且上传的数据已经展示出来。

image-20220113115641873

四、应用侧软件开发

4.1 功能介绍

为了更方便的展示设备数据,与设备完成交互,还需要开发一个配套的上位机,官方提供了应用侧开发的API接口、SDK接口,为了方便通用一点,我这里采用了API接口完成数据交互,上位机软件采用QT开发。

帮助文档地址: https://support.huaweicloud.com/usermanual-iothub/iot_01_0045.html

image-20220113142020653

4.2 查询设备属性接口

设备属性就是设备上传的传感器状态数据信息,应用侧提供了API接口,可以主动向设备端下发请求指令;设备端收到指令之后需要按照约定的数据格式上报数据;所以,要实现应用层与设备端的数据交互,需要应用层与设备端配合才能完成。

下面分别介绍应用测和设备测的实现流程。

(1)应用层下发的指令

帮助文档地址: https://support.huaweicloud.com/api-iothub/iot_06_v5_0034.html

接口的在线调试地址: https://apiexplorer.developer.huaweicloud.com/apiexplorer/debug?product=IoTDA&api=ListProperties

如果请求参数和返回值不清楚,写代码前,先使用在线调试接口体验一下,验证数据交互是否OK。

image-20220113143843235

请求参数里比较总要的两个必填参数,是设备ID和服务ID,这两个参数在第3章节就介绍过如何获取了,在产品页面创建自定义属性时可以看到服务ID。

image-20220113144010538

请求接口总结:

请求方法 GET
 URI地址  /v5/iot/{project_id}/devices/{device_id}/properties
 传输协议 HTTPS
 ​
 拼接好的地址: 
 https://iotda.cn-north-4.myhuaweicloud.com/v5/iot/0e5957be8a00f53c2fa7c0045e4d8fbf/devices/61df9a6bc7fb24029b0c160d_1126626497/properties?service_id=1126626497
 ​
 其中的project_id和device_id需要根据自己的设备信息修改。
 ​
 ​
 请求头:
 {
  "User-Agent": "API Explorer",
  "X-Auth-Token": "******",   这个是鉴权用的token
  "Content-Type": "application/json"
 }
 ​
 ​
 响应体(设备上传的数据)
 {
  "response": {
   "services": [
    {
     "service_id": "healthy",
     "properties": {
      "HeartRate": 127
     }
    },
    {
     "service_id": "healthy",
     "properties": {
      "motion": 2000
     }
    },
    {
     "service_id": "healthy",
     "properties": {
      "temperature": 36.2
     }
    }
   ]
  }
 }

请求头里需要填X-Subject-Token参数,这个参数只要是访问任何华为云都需要填,获取具体的流程可以看这里。https://bbs.huaweicloud.com/blogs/317759 翻到第3小节。

(2)设备上传数据

应用层向设备端请求查询设备属性时,设备端会收到如下的消息:

$oc/devices/61df9a6bc7fb24029b0c160d_1126626497/sys/properties/get/request_id=336bcb57-0e0a-44d0-90f7-31386cb54a3c{"service_id":"1126626497"}

这个消息里有一个主要参数request_id请求ID,设备端需要解析出这个参数,给应用层响应数据时,需要带上这个ID。

这个请求属性详细帮助文档看这里: https://support.huaweicloud.com/api-iothub/iot_06_v5_3011.html

image-20220113145229538

设备响应的数据格式:

主题格式: $oc/devices/{device_id}/sys/properties/get/response/request_id={request_id}
 ​
 示    例:
 $oc/devices/61df9a6bc7fb24029b0c160d_1126626497/sys/properties/get/response/request_id=336bcb57-0e0a-44d0-90f7-31386cb54a3c
 ​
 响应的数据格式:
 {"services": [{"service_id": "healthy","properties":{"HeartRate":127}},{"service_id": "healthy","properties":{"motion":2000}},{"service_id": "healthy","properties":{"temperature":36.2}}]}

响应的数据格式可以看这里的介绍: https://support.huaweicloud.com/api-iothub/iot_06_v5_3010.html

image-20220113144957661

4.3 在线API调试结合设备模拟

下面使用MQTT客户端与在线API接口联合模拟一下接口效果:

(1)先打开调试页面: https://apiexplorer.developer.huaweicloud.com/apiexplorer/debug?product=IoTDA&api=ListProperties

然后填好设备DI和服务ID:

image-20220113145604854

(2)、打开MQTT客户端,登录华为云物联网平台(也就是模拟设备上线):

image-20220113145709545

(3)、打开在线API调试页面,点击调试: 点击后可以看到页面上已经在等待客户端的响应了。

image-20220113145810872

(4)、MQTT客户端响应详细

按照前面说的响应格式,拼接好接口,数据。然后发布主题。

image-20220113150012520

(5)、应用层收到客户端响应,调试成功

调试成功后,响应体里收到的就是设备端上传的设备属性数据。

image-20220113150211946

4.4 应用层核心代码

/*
 功能: 获取token
 */
 void Widget::GetToken()
 {
     //表示获取token
     function_select=3;
 ​
     QString requestUrl;
     QNetworkRequest request;
 ​
     //设置请求地址
     QUrl url;
 ​
     //获取token请求地址
     requestUrl = QString("https://iam.%1.myhuaweicloud.com/v3/auth/tokens")
                  .arg(SERVER_ID);
 ​
     //自己创建的TCP服务器,测试用
     //requestUrl="http://10.0.0.6:8080";//设置数据提交格式
     request.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/json;charset=UTF-8"));
 ​
     //构造请求
     url.setUrl(requestUrl);
 ​
     request.setUrl(url);
 ​
     QString text =QString("{"auth":{"identity":{"methods":["password"],"password":"
     "{"user":{"domain": {"
     ""name":"%1"},"name": "%2","password": "%3"}}},"
     ""scope":{"project":{"name":"%4"}}}}")
             .arg(MAIN_USER)
             .arg(IAM_USER)
             .arg(IAM_PASSWORD)
             .arg(SERVER_ID);
 ​
     //发送请求
     manager- >post(request, text.toUtf8());
 }
 ​
 //查询设备属性
 void Widget::Get_device_properties()
 {
     //表示获取token
     function_select=0;
 ​
     QString requestUrl;
     QNetworkRequest request;
 ​
     //设置请求地址
     QUrl url;
 ​
     //获取token请求地址
     requestUrl = QString("https://iotda.%1.myhuaweicloud.com/v5/iot/%2/devices/%3/properties?service_id=%4")
                  .arg(SERVER_ID)
             .arg(PROJECT_ID)
             .arg(device_id)
             .arg(service_id);
 ​
     //自己创建的TCP服务器,测试用
     //requestUrl="http://10.0.0.6:8080";//设置数据提交格式
     request.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/json"));
 ​
     //设置token
     request.setRawHeader("X-Auth-Token",Token);
 ​
     //构造请求
     url.setUrl(requestUrl);
 ​
     request.setUrl(url);
 ​
     //发送请求
     manager- >get(request);
 }

image-20220113164911187

五、设备底层开发

篇幅有限,整个项目工程和上位机源码可以在这里下载: https://download.csdn.net/download/xiaolong1126626497/81993720

下面列出STM32设备底层端的一些传感器核心处理代码。

5.1 心率采集计算算法

int BPM;                             // 用于保存脉冲速率
 int Signal;                          // 持有的原始数据
 int IBI = 600;                       
 unsigned char Pulse = false;    
 unsigned char QS = false;        
 int rate[10];                    
 unsigned long sampleCounter = 0; 
 unsigned long lastBeatTime = 0;  
 int P =512;                      
 int T = 512;                     
 int thresh = 512;               
 int amp = 100;                  
 unsigned char firstBeat = true;  
 unsigned char secondBeat = false;
 /*
     定时器2中断服务函数 用于周期性采集心率值
 */
 void TIM2_IRQHandler(void)
 {
     uint16_t runningTotal=0;
     uint8_t i;
     uint16_t Num;
     
     if(TIM2- >SR&1< < 0)
     {
             //读取到的值右移2位,12位-- >10位
         Signal = Get_AdcCHx_DATA(1) > >2;         
         sampleCounter += 2;                          
         Num = sampleCounter - lastBeatTime; 
 ​
         //发现脉冲波的波峰和波谷
         //  find the peak and trough of the pulse wave
         if(Signal < thresh && Num > (IBI/5)*3)
         {   
             if (Signal < T)
             {                                                   
                 T = Signal;  
             }
         }
 ​
         if(Signal > thresh && Signal > P)
         { 
             P = Signal; 
         }  
 ​
         //开始寻找心跳
         //当脉冲来临的时候,signal的值会上升
         if (Num > 250)
         {                            
             if ( (Signal > thresh) && (Pulse == false) && (Num > (IBI/5)*3) )
             {        
                 Pulse = true;                         
                 //LED0(0); 
                 IBI = sampleCounter - lastBeatTime;       
                 lastBeatTime = sampleCounter;              
 ​
                 if(secondBeat)
                 {                       
                     secondBeat = false;             
                     for(i=0; i<=9; i++)
                     {               
                         rate[i] = IBI;              
                     }
                 }
 ​
                 if(firstBeat)
                 {                                               
                     firstBeat = false;                      
                     secondBeat = true;                      
                     return;                                 
                 }   
 ​
                 for(i=0; i<=8; i++)
                 {                                               
                     rate[i] = rate[i+1];                
                     runningTotal += rate[i];           
                 }
 ​
                 rate[9] = IBI;                       
                 runningTotal += rate[9];                
                 runningTotal /= 10;                     
                 BPM = 60000/runningTotal;               
                 QS = true;                            
             }                       
         }
 ​
         //脉冲开始下降
         if (Signal < thresh && Pulse == true)
         {
             Pulse = false;                        
             amp = P - T;                          
             thresh = amp/2 + T;                    
             P = thresh;                         
             T = thresh;
         }
 ​
         //没有检测到脉冲,设置默认值
         if (Num > 2500)
         {                       
             thresh = 512;                       
             P = 512;                              
             T = 512;                              
             lastBeatTime = sampleCounter;               
             firstBeat = true;                      
             secondBeat = false;                    
         }   
     }
     TIM2- >SR&=0x0; //清中断标志
 }

5.2 OLED关键代码

//向SSD1106写入一个字节。
 //dat:要写入的数据/命令
 //cmd:数据/命令标志 0,表示命令;1,表示数据;
 void OLED_WR_Byte(u8 dat,u8 cmd)
 {   
     u8 i;             
     if(cmd)
       OLED_DC_Set();
     else 
       OLED_DC_Clr();          
     OLED_CS_Clr();
     for(i=0;i< 8;i++)
     {             
         OLED_SCLK_Clr();
         if(dat&0x80)
            OLED_SDIN_Set();
         else 
            OLED_SDIN_Clr();
         OLED_SCLK_Set();
         dat< <=1;   
     }                         
     OLED_CS_Set();
     OLED_DC_Set();        
 } 
 ​
 //设置坐标的位置(x范围: 0~127   ,   y的范围:0~63)
 //注意: 8 行为一页,共 64 行即 8 页
 void OLED_Set_Pos(unsigned char x, unsigned char y) 
 { 
     OLED_WR_Byte(0xb0+y,OLED_CMD);
     OLED_WR_Byte(((x&0xf0) > >4)|0x10,OLED_CMD);
     OLED_WR_Byte((x&0x0f)|0x01,OLED_CMD); 
 }

5.3 体温采集换算

u8 Receive_ok;
 u8 rebuf[20]={0};
 void RxTempInfo(void)
 {
      static uint8_t i=0;
     if(USART2- >SR&1< < 5)     //判断接收标志
     {
         rebuf[i++]=USART2- >DR;//读取串口数据,同时清接收标志
         if(rebuf[0]!=0x5a)    //帧头不对
             i=0;    
         if((i==2)&&(rebuf[1]!=0x5a))//帧头不对
             i=0;
     
         if(i >3)//i等于4时,已经接收到数据量字节rebuf[3]
         {
             if(i!=(rebuf[3]+5))//判断是否接收一帧数据完毕
                 return ;    
             switch(rebuf[2])   //接收完毕后处理
             {
                 case 0x45:
                     if(!Receive_ok)//当数据处理完成后才接收新的数据
                     {
                          Receive_ok=1;//接收完成标志
                     }
                     break;
                 case 0x15:break;
                 case 0x35:break;
             }
             i=0;//缓存清0
         }
     }
 }
 ​
 void GetTempInfo(void)
 {
     float TO=0,TA=0;
     u8 sum=0,i=0;
     for(sum=0,i=0;i< (rebuf[3]+4);i++)
     {
         sum+=rebuf[i];  
     }
     if(sum==rebuf[i])//校验和判断
     {
         TO=(float)((rebuf[4]< < 8)|rebuf[5])/100;  //得到真实温度
         TA=(float)((rebuf[6]< < 8)|rebuf[7])/100;  //得到真实温度   
     }
     printf("TO: %f
",TO);
     printf("TA: %f
",TA);
 }

5.4 运动计步算法

/*******************************************************************************
 * LOCAL VARIABLES
 */
 //存放三轴数据  
 float oriValues[3] = {0};    
 //用于存放计算阈值的波峰波谷差值  
 float tempValue[VALUE_NUM] ={0};  
 int tempCount = 0;  
 //是否上升的标志位  
 u8 isDirectionUp = FALSE;  
 //持续上升次数  
 int continueUpCount = 0;  
 //上一点的持续上升的次数,为了记录波峰的上升次数  
 int continueUpFormerCount = 0;  
 //上一点的状态,上升还是下降  
 u8 lastStatus = FALSE;  
 //波峰值  
 float peakOfWave = 0;  
 //波谷值  
 float valleyOfWave = 0;  
 //此次波峰的时间  
 long timeOfThisPeak = 0;  
 //上次波峰的时间  
 long timeOfLastPeak = 0;  
 //当前的时间  
 long timeOfNow = 0;  
 //当前传感器的值  
 float gravityNew = 0;  
 //上次传感器的值  
 float gravityOld = 0;  
 //动态阈值需要动态的数据,这个值用于这些动态数据的阈值  
 float initialValue = (float) 1.3;  
 //初始阈值  
 float ThreadValue = (float) 2.0;
 //三轴轴值
 accValue_t accValue;
 //行走信息:卡路里、里程、步数
 static sportsInfo_t sportsInfo;
 //计步缓存
 static u8 stepTempCount =0;
 ​
 ​
 /*******************************************************************************
 * 函数名:DetectorNewStep
 * 功能描述: 
 *         步伐更新:如果检测到了波峰,并且符合时间差以及阈值的条件,则判定为1步       
 *         阀值更新:符合时间差条件,波峰波谷差值大于initialValue,则将该差值纳入阈值的计算中       
 * 参数说明:  
 输入:
 values:经过处理的G-sensor数据
 timeStamp_p:时间戳
 * 返回值说明:
 * 修改记录:sportsInfo_t *onSensorChanged(accValue_t *pAccValue,timeStamp_t *timeStamp_p,personInfo_t * personInfo)
 *******************************************************************************/
 sportsInfo_t *DetectorNewStep(float values,timeStamp_t *timeStamp_p,personInfo_t * personInfo) 
 {  
   static u32 time_old;
   personInfo_t *userInfo = personInfo;
   static u32 step_per_2_second;  //每两秒所走的步数
   float step_lenth,walk_speed,walk_distance,Calories;//步长
   u32 time_now;
   timeStamp_t *time_p = timeStamp_p;
   if (gravityOld == 0) 
   {  
     gravityOld = values;  
   } 
   else 
   {  
     if (DetectorPeak(values, gravityOld))//检测到波峰
     {  
       timeOfLastPeak = timeOfThisPeak;//更新上次波峰的时间  
       //将时间戳转换为以毫秒ms为单位
       time_now = timeOfNow = ((time_p- >hour*60+time_p- >minute)*60+time_p- >second)*1000+time_p- >twentyMsCount*20; //获取时间 ,并转化为毫秒
       //如果检测到了波峰,并且符合时间差以及阈值的条件,则判定为1步 
       if (  (timeOfNow - timeOfLastPeak >= 250 )//Jahol Fan 修改为300,防止轻微动都也会检测步子
           //&& (timeOfNow - timeOfLastPeak <= 2000)
           &&(peakOfWave - valleyOfWave >= ThreadValue)
             )
       {  
         timeOfThisPeak = timeOfNow; //更新此次波峰时间 
         
         
         stepTempCount++;//Jahol:加1为两步
         step_per_2_second ++;
         //Jahol:这样计算卡路里,不能滤除人为的误操作,导致的结果是:里程和卡路里偏大
         if((time_now - time_old) >= 2000 )    //如果时间过了2秒
         {
 ​
           if( 1 == step_per_2_second )                 
           {
             step_lenth = userInfo- >height/5;
           }
           else if( 2 == step_per_2_second )
           {
             step_lenth = userInfo- >height/4;
           }
           else if( 3 == step_per_2_second )
           {
             step_lenth = userInfo- >height/3;
           }
           else if( 4 == step_per_2_second )
           {
             step_lenth = userInfo- >height/2;
           }
           else if(5 == step_per_2_second)             //Jahol:为了使计步准确,设置上限值为5步,牺牲卡路里准确性
           {
             step_lenth = userInfo- >height/1.2f;
           }
           else if( 7 == step_per_2_second )
           {
             step_lenth = userInfo- >height;
           }
           else if(step_per_2_second >= 8)               //      step_diff >8
           {
             step_lenth = userInfo- >height*1.2f;
           }
           else 
           {
             step_lenth = 0;
           }
           walk_speed = step_per_2_second*step_lenth/2;   //速度 ,单位:米/秒
           walk_distance  = step_per_2_second*step_lenth; //行走距离,单位:米
           Calories = 4.5f*walk_speed*(userInfo- >weight/2)/1800;  //Jahol:weight是以kg为单位
           sportsInfo.calories  += Calories;
           sportsInfo.distance  += walk_distance;        
           time_old = time_now;         //更新时间
           step_per_2_second = 0;
           
         }   
         else 
         {
           //do nothing
         }       
         /* 
         * 处理无效运动: 
         * 1.连续记录5才开始计步 
         * 2.例如记录的步用户停住超过3秒,则前面的记录失效,下次从头开始 
         * 3.连续4记录了步用户还在运动,之前的数据才有效 
         * */                
         if ((stepTempCount< 5 )&&(timeOfNow - timeOfLastPeak >= 3000))          
         {
           stepTempCount = 0;
         }
         else if((stepTempCount >= 5)&&(timeOfNow - timeOfLastPeak <= 3000))
         {
           sportsInfo.stepCount += stepTempCount;          
           stepTempCount         = 0;                
         }
         else
         {
           //do nothing
         }
         
         
       }  
       //Jahol:更新阀值,问题:阀值不会一直变大,不能变小?
       if (timeOfNow - timeOfLastPeak >= 250  
           && (peakOfWave - valleyOfWave >= initialValue)) 
       {  
         timeOfThisPeak = timeOfNow;  
         ThreadValue = Peak_Valley_Thread(peakOfWave - valleyOfWave);//更新阀值  
       }  
     }  
   }  
   gravityOld = values;  
   return &sportsInfo;
 }

审核编辑:汤梓红

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • STM32
    +关注

    关注

    2249

    文章

    10697

    浏览量

    350110
  • IIC
    IIC
    +关注

    关注

    11

    文章

    289

    浏览量

    37943
  • IOT
    IOT
    +关注

    关注

    186

    文章

    4042

    浏览量

    193933
  • ESP8266
    +关注

    关注

    50

    文章

    950

    浏览量

    44219
  • 华为云
    +关注

    关注

    3

    文章

    2222

    浏览量

    16956
收藏 人收藏

    评论

    相关推荐

    通过STM32+ESP8266 Wifi模块 +服务器,做一个数据收发控制的板子服务器方面该如何选择?

    通过STM32+ESP8266 Wifi模块 +服务器 做一个数据收发控制的板子 服务器方面该如何选择?
    发表于 04-25 08:16

    STM32ESP8266与MQTT连接阿里云物联网的串口通信异常解析

    STM32ESP8266与MQTT协议连接阿里云物联网平台时常见的串口通信异常介绍 在构建物联网应用时,STM32ESP8266与MQTT协议的结合是实现设备与网络间稳定通信的关键
    的头像 发表于 04-19 17:19 576次阅读

    基于ESP8266的机智云平台控制系统设计

    项目摘要:本项目以智能家居为主题,基于ESP8266的机智云平台控制系统,利用机智云平台和ESP8266WiFi模块、红外发射模块、STM32核心板、DHT11温湿度传感器模块,
    的头像 发表于 11-07 08:10 971次阅读
    基于<b class='flag-5'>ESP8266</b>的机智云平台控制<b class='flag-5'>系统</b>设计

    nodemcu和esp8266是什么关系?

    nodemcu和esp8266是什么关系 nodemcu和esp8266是什么关系?通俗理解就是nodemcu是一个开发板,基于esp8266开发
    的头像 发表于 10-20 14:53 2768次阅读
    nodemcu和<b class='flag-5'>esp8266</b>是什么关系?

    ESP8266 Non-OS SDK API参考

    ESP8266EX 由乐鑫公司开发,提供了⼀套⾼度集成的 Wi-Fi SoC 解决⽅案,其低功耗、紧凑设计和⾼稳定性可以满⾜⽤户的需求。ESP8266EX 拥有完整的且⾃成体系的 Wi-Fi ⽹络
    发表于 10-10 06:23

    esp8266ex引脚详细 ESP8266EX参考手册

    ESP8266EX 由乐鑫公司开发,提供了⼀套⾼度集成的 Wi-Fi SoC 解决⽅案,其低功耗、 紧凑设计和⾼稳定性可以满⾜⽤户的需求。 ESP8266EX 拥有完整的且⾃成体系的 Wi-Fi
    发表于 09-08 17:05 2次下载

    ch32v307与esp8266的区别

    ch32v307与esp8266的区别 ESP32和ESP8266都是Espressif Systems生产的芯片系列,分别是第二代和第一代的Wi-Fi和蓝牙芯片。两者在外观上相似,但是它们之间
    的头像 发表于 08-22 15:53 801次阅读

    【NK-IOT-M487试用】WIFI模块ESP8266驱动

    NK-IOT-M487到手也几天了。今天我们就来把玩一下它的ESP8266,WiFi模块。由于RTTStudio已全面支持M487,我们就要RTTStudio进行开发
    发表于 08-07 16:12 415次阅读
    【NK-<b class='flag-5'>IOT</b>-M487试用】WIFI模块<b class='flag-5'>ESP8266</b>驱动

    基于STM32设计的智能家居控制系统华为IOT

    设计了一款基于华为云物联网平台的智能家居控制系统,硬件采用了STM32ESP8266的组合,实现了设备的上云连接。
    的头像 发表于 07-11 13:58 2180次阅读
    基于<b class='flag-5'>STM32</b>设计的智能家居控制<b class='flag-5'>系统</b>(<b class='flag-5'>华为</b>云<b class='flag-5'>IOT</b>)

    基于STM32设计的智能门锁(华为IOT)

    这篇文章就介绍如何使用华为物联网云平台实现智能锁的应用场景构建,硬件采用STM32F103ZET6 + ESP8266+步进电机实现。在华为IOT
    的头像 发表于 07-11 13:53 2717次阅读
    基于<b class='flag-5'>STM32</b>设计的智能门锁(<b class='flag-5'>华为</b>云<b class='flag-5'>IOT</b>)

    ESP8266物联网茶壶

    电子发烧友网站提供《ESP8266物联网茶壶.zip》资料免费下载
    发表于 07-10 16:45 0次下载
    <b class='flag-5'>ESP8266</b>物联网茶壶

    采用ESP8266的物联网开关

    电子发烧友网站提供《采用ESP8266的物联网开关.zip》资料免费下载
    发表于 07-06 15:03 4次下载
    采用<b class='flag-5'>ESP8266</b>的物联网开关

    ESP8266的RFID智能门锁

    电子发烧友网站提供《带ESP8266的RFID智能门锁.zip》资料免费下载
    发表于 07-06 10:07 0次下载
    带<b class='flag-5'>ESP8266</b>的RFID智能门锁

    使用Firebase的ESP8266物联网平台

    电子发烧友网站提供《使用Firebase的ESP8266物联网平台.zip》资料免费下载
    发表于 07-03 09:54 0次下载
    使用Firebase的<b class='flag-5'>ESP8266</b>物联网平台

    想通过ESP8266连接阿里,固件哪里有?

    想用新唐的板子,通过esp8266连接阿里 有没有测试好的esp8266的固件? 还是说,这个固件要自己修改,自己写?
    发表于 06-27 07:40