HarmonyOS基于LYEVK-3861开发心率和血氧检测

开发 前端 OpenHarmony
本次实验使用的是GPIO模拟I2C通信,I2C协议规定在总线上出现起始信号start后,若SCL在高电平期间SDA保持电平不变,则SDA的状态表示有效数据(data valid)。

[[420002]]

想了解更多内容,请访问:

51CTO和华为官方合作共建的鸿蒙技术社区

https://harmonyos.51cto.com

前言

由于本人爱好爬山,去过很多高海拔的地方,每次出行都会携带心率和血氧检测仪。其实很多人对高反不是很了解。高反,是人体在缺氧情况下,对环境的不适应。人体在一定氧气的情况下可以很舒服的呼吸,但是高原因为海拔高,气压低,空气干燥,供给的氧气稀薄,使得人体的机能无法正常工作,就会出现呕吐、头晕头疼、流鼻血、浮肿的各种情况。

海拔高度一般达到2700米,就会有高原反应。

海拔高度(米) 为0海拔含氧量的% 

 

那我们如何去判断自己是否有高反呢?

可以通过血氧饱和度来判定,当我们血氧饱和度低于80%的时候就会有高原反应了。

血氧:是指血液中的氧气,人体正常血氧饱和度为95%以上。血液中含氧量越高,人的新陈代谢就越好。当然血氧含量高并不是一个好的现象,人体内的血氧都是有一定的饱和度,过低会造成机体供氧不足,过高会导致体内细胞老化。

本次内容讲解基于LYEVK-3861开发板完成一个简单的心率和血氧检测,来检查身体的状态。主要测量HR-心率 、SaO2-血氧。

效果演示 

[[420003]]

环境准备

1、开发环境、编译环境搭建,参考官方文档,此处不在赘述。参考链接如下:

Window开发环境

Ubuntu编译环境

2、OpenHarmony 2.0 Canary源码 源码获取,参考:

源码获取说明

镜像全量下载

3、LYEVK-3861 IoT物联网开发板套件:

LYEVK-3861开发板

开发调试

1、基础介绍

血氧检测传感器选用的是MAX30102,其大致的工作原理将RED/IR 光射向皮肤,透过皮肤组织反射回的光被光敏传感器接受并转换成电信号,再经过AD转换成数字信号。简化过程:光–> 电 --> 数字信号,然后将数字信号通过I2C与主控交互。

本次实验使用的是GPIO模拟I2C通信,I2C协议规定在总线上出现起始信号start后,若SCL在高电平期间SDA保持电平不变,则SDA的状态表示有效数据(data valid)。在传输数据时SDA的改变必须只能发生在SCL为低电平期间,每一bit数据有1个时钟脉冲时长,I2C串行总线上的数据传输时序如下图所示:

HarmonyOS 基于LYEVK-3861开发心率和血氧检测-鸿蒙HarmonyOS技术社区

I2C协议规定每个被寻址设备在接收1字节数据后都必须向发送字节的设备发送应答(ACK)信号,确认的器件必须在应答时钟脉冲期间下拉SDA线,使得SDA线在应答相关时钟脉冲SCL为高电平期间稳定为低电平。

I2C协议规定与ACK信号相反的信号为非应答(not ACK)信号。在主器件从从器件中读取数据时,主器件必须在读取的最后1字节数据后在SDA总线上产生not ACK信号以示意从器件停止发送数据。not ACK信号是在SCL为高电平期间保持SDA也为高电平。

根据时序图,用GPIO模拟IIC通信,

2、开始调试

先用GPIO模拟初始化IIC

  1. void IIC_Init(void){     
  2.     GpioInit();  
  3.     IoSetFunc(PIN_SCL, WIFI_IOT_IO_FUNC_GPIO_10_GPIO);// SCL 
  4.     GpioSetDir(PIN_SCL, WIFI_IOT_GPIO_DIR_OUT); 
  5.  
  6.     IoSetFunc(PIN_SDA, WIFI_IOT_IO_FUNC_GPIO_11_GPIO);// SDA 
  7.     GpioSetDir(PIN_SDA, WIFI_IOT_GPIO_DIR_OUT); 
  8.     IIC_SCL(1); 
  9.     IIC_SDA(1); 
  10.      
  11.     IoSetFunc(PIN_INT, WIFI_IOT_IO_FUNC_GPIO_8_GPIO);// INT 
  12.     GpioSetDir(PIN_INT, WIFI_IOT_GPIO_DIR_IN); 

用GPIO模拟IIC起始信号

  1. void IIC_Start(void){ 
  2.     SDA_OUT();     //sda线输出 
  3.     IIC_SDA(1);        
  4.     IIC_SCL(1); 
  5.     delay_us(4); 
  6.     IIC_SDA(0);//START:when CLK is high,DATA change form high to low  
  7.     delay_us(4); 
  8.     IIC_SCL(0);//钳住I2C总线,准备发送或接收数据  
  9. }    

 用GPIO模拟IIC停止信号

  1. void IIC_Stop(void){ 
  2.     SDA_OUT();//sda线输出 
  3.     IIC_SCL(0); 
  4.     IIC_SDA(0);//STOP:when CLK is high DATA change form low to high 
  5.     delay_us(4); 
  6.     IIC_SCL(1);  
  7.     IIC_SDA(1);//发送I2C总线结束信号 
  8.     delay_us(4);                                 

 用GPIO模拟产生ACK应答信号

  1. void IIC_Ack(void){ 
  2.     IIC_SCL(0); 
  3.     SDA_OUT(); 
  4.     IIC_SDA(0); 
  5.     delay_us(2); 
  6.     IIC_SCL(1); 
  7.     delay_us(2); 
  8.     IIC_SCL(0); 

 用GPIO模拟产生not ACK应答

  1. void IIC_NAck(void){ 
  2.     IIC_SCL(0); 
  3.     SDA_OUT(); 
  4.     IIC_SDA(1); 
  5.     delay_us(2); 
  6.     IIC_SCL(1); 
  7.     delay_us(2); 
  8.     IIC_SCL(0); 
  9. }    

 用GPIO模拟等待应答信号,如果返回值是1,则接受应答失败,如果返回值是0,则接受应答成功

  1. u8 IIC_Wait_Ack(void){ 
  2.     u8 ucErrTime=0; 
  3.     SDA_IN();      //SDA设置为输入   
  4.     IIC_SDA(1);delay_us(1);     
  5.     IIC_SCL(1);delay_us(1);   
  6.      
  7.     #if 1 
  8.     while(READ_SDA){ 
  9.         ucErrTime++; 
  10.         if(ucErrTime>250) 
  11.         { 
  12.             IIC_Stop(); 
  13.             //printf("IIC_Wait_Ack erro\r\n"); 
  14.             return 1; 
  15.         } 
  16.     } 
  17.     #else 
  18.     ucErrTime++; 
  19.     delay_us(3); 
  20.      
  21.     #endif 
  22.     IIC_SCL(0);//时钟输出0      
  23.     return 0;   
  24. }  

发送数据的实现

  1. void IIC_Send_Byte(u8 txd){                         
  2.     u8 t;    
  3.     SDA_OUT();       
  4.     IIC_SCL(0);//拉低时钟开始数据传输 
  5.      
  6.     for(t=0;t<8;t++){               
  7.         IIC_SDA((txd&0x80)>>7); 
  8.         txd<<=1;       
  9.         delay_us(2);   //对TEA5767这三个延时都是必须的 
  10.         IIC_SCL(1); 
  11.         delay_us(2);  
  12.         IIC_SCL(0);  
  13.         delay_us(2); 
  14.     }     
  15. }  

 IIC发送一个字节,返回从机有无应答,返回值是1时有应答,返回值是0时无应答

  1. u8 IIC_Read_Byte(unsigned char ack){ 
  2.     unsigned char i,receive=0; 
  3.     SDA_IN();//SDA设置为输入 
  4.     for(i=0;i<8;i++ ){ 
  5.         IIC_SCL(0);  
  6.         delay_us(2); 
  7.         IIC_SCL(1); 
  8.         receive<<=1; 
  9.         if(READ_SDA)receive++;    
  10.         delay_us(1);  
  11.     }    
  12.      
  13.     if (!ack) 
  14.         IIC_NAck();//发送nACK 
  15.     else 
  16.         IIC_Ack(); //发送ACK    
  17.     return receive; 

读1个字节,ack=1时,发送ACK,ack=0时,发送nACK

在主函数里初始化IIC,再初始化芯片里的相关寄存器

HarmonyOS 基于LYEVK-3861开发心率和血氧检测-鸿蒙HarmonyOS技术社区

在max30102.c里按照芯片规格书,通过模拟的IIC对寄存器进行读取,再调用下芯片原厂提供的算法,将采集到的值输出在显示屏上

HarmonyOS 基于LYEVK-3861开发心率和血氧检测-鸿蒙HarmonyOS技术社区

3、结语

以上都完成之后,就可以编译、烧录,就可以测试最后的完成效果。

对于想去高海拔的小伙伴们,可以带一个便携式血氧检测仪,随时监控自己的身体状况哦~

文章相关附件可以点击下面的原文链接前往下载

心率和血氧检测demo.rar

想了解更多内容,请访问:

51CTO和华为官方合作共建的鸿蒙技术社区

https://harmonyos.51cto.com

 

责任编辑:jianghua 来源: 鸿蒙社区
相关推荐

2021-11-05 09:58:58

鸿蒙HarmonyOS应用

2021-10-11 10:07:09

鸿蒙HarmonyOS应用

2021-09-02 15:25:53

鸿蒙HarmonyOS应用

2021-08-17 14:40:43

鸿蒙HarmonyOS应用

2021-04-08 21:10:24

办公

2020-12-15 11:57:49

Hi3861 HarmonyOS开发板

2022-12-30 12:15:16

芯片DIY

2021-12-06 15:05:41

鸿蒙HarmonyOS应用

2021-09-16 10:03:39

鸿蒙HarmonyOS应用

2020-11-30 13:57:48

Hi3861

2021-12-20 21:01:52

鸿蒙HarmonyOS应用

2021-09-09 10:06:09

鸿蒙HarmonyOS应用

2017-03-21 08:41:51

iOS手机摄像头检测心率

2024-07-04 09:22:24

2022-07-19 20:25:54

鸿蒙MaskRCNN算法

2021-12-31 15:07:00

鸿蒙HarmonyOS应用

2020-11-02 12:07:11

鸿蒙 GPIO

2022-11-09 11:02:00

2020-10-28 10:00:09

海思Hi3861CentOS鸿蒙LiteOS

2021-02-01 13:58:51

鸿蒙HarmonyOS应用开发
点赞
收藏

51CTO技术栈公众号