HarmonyOS基于LYEVK-3861開發心率和血氧檢測
前言
由于本人愛好爬山,去過很多高海拔的地方,每次出行都會攜帶心率和血氧檢測儀。其實很多人對高反不是很了解。高反,是人體在缺氧情況下,對環境的不適應。人體在一定氧氣的情況下可以很舒服的呼吸,但是高原因為海拔高,氣壓低,空氣干燥,供給的氧氣稀薄,使得人體的機能無法正常工作,就會出現嘔吐、頭暈頭疼、流鼻血、浮腫的各種情況。
海拔高度一般達到2700米,就會有高原反應。
海拔高度(米) 為0海拔含氧量的%
那我們如何去判斷自己是否有高反呢?
可以通過血氧飽和度來判定,當我們血氧飽和度低于80%的時候就會有高原反應了。
血氧:是指血液中的氧氣,人體正常血氧飽和度為95%以上。血液中含氧量越高,人的新陳代謝就越好。當然血氧含量高并不是一個好的現象,人體內的血氧都是有一定的飽和度,過低會造成機體供氧不足,過高會導致體內細胞老化。
本次內容講解基于LYEVK-3861開發板完成一個簡單的心率和血氧檢測,來檢查身體的狀態。主要測量HR-心率 、SaO2-血氧。
效果演示
環境準備
1、開發環境、編譯環境搭建,參考官方文檔,此處不在贅述。參考鏈接如下:
2、OpenHarmony 2.0 Canary源碼 源碼獲取,參考:
3、LYEVK-3861 IoT物聯網開發板套件:
開發調試
1、基礎介紹
血氧檢測傳感器選用的是MAX30102,其大致的工作原理將RED/IR 光射向皮膚,透過皮膚組織反射回的光被光敏傳感器接受并轉換成電信號,再經過AD轉換成數字信號。簡化過程:光–> 電 --> 數字信號,然后將數字信號通過I2C與主控交互。
本次實驗使用的是GPIO模擬I2C通信,I2C協議規定在總線上出現起始信號start后,若SCL在高電平期間SDA保持電平不變,則SDA的狀態表示有效數據(data valid)。在傳輸數據時SDA的改變必須只能發生在SCL為低電平期間,每一bit數據有1個時鐘脈沖時長,I2C串行總線上的數據傳輸時序如下圖所示:

I2C協議規定每個被尋址設備在接收1字節數據后都必須向發送字節的設備發送應答(ACK)信號,確認的器件必須在應答時鐘脈沖期間下拉SDA線,使得SDA線在應答相關時鐘脈沖SCL為高電平期間穩定為低電平。
I2C協議規定與ACK信號相反的信號為非應答(not ACK)信號。在主器件從從器件中讀取數據時,主器件必須在讀取的最后1字節數據后在SDA總線上產生not ACK信號以示意從器件停止發送數據。not ACK信號是在SCL為高電平期間保持SDA也為高電平。
根據時序圖,用GPIO模擬IIC通信,
2、開始調試
先用GPIO模擬初始化IIC
- void IIC_Init(void){
- GpioInit();
- IoSetFunc(PIN_SCL, WIFI_IOT_IO_FUNC_GPIO_10_GPIO);// SCL
- GpioSetDir(PIN_SCL, WIFI_IOT_GPIO_DIR_OUT);
- IoSetFunc(PIN_SDA, WIFI_IOT_IO_FUNC_GPIO_11_GPIO);// SDA
- GpioSetDir(PIN_SDA, WIFI_IOT_GPIO_DIR_OUT);
- IIC_SCL(1);
- IIC_SDA(1);
- IoSetFunc(PIN_INT, WIFI_IOT_IO_FUNC_GPIO_8_GPIO);// INT
- GpioSetDir(PIN_INT, WIFI_IOT_GPIO_DIR_IN);
- }
用GPIO模擬IIC起始信號
- void IIC_Start(void){
- SDA_OUT(); //sda線輸出
- IIC_SDA(1);
- IIC_SCL(1);
- delay_us(4);
- IIC_SDA(0);//START:when CLK is high,DATA change form high to low
- delay_us(4);
- IIC_SCL(0);//鉗住I2C總線,準備發送或接收數據
- }
用GPIO模擬IIC停止信號
- void IIC_Stop(void){
- SDA_OUT();//sda線輸出
- IIC_SCL(0);
- IIC_SDA(0);//STOP:when CLK is high DATA change form low to high
- delay_us(4);
- IIC_SCL(1);
- IIC_SDA(1);//發送I2C總線結束信號
- delay_us(4);
- }
用GPIO模擬產生ACK應答信號
- void IIC_Ack(void){
- IIC_SCL(0);
- SDA_OUT();
- IIC_SDA(0);
- delay_us(2);
- IIC_SCL(1);
- delay_us(2);
- IIC_SCL(0);
- }
用GPIO模擬產生not ACK應答
- void IIC_NAck(void){
- IIC_SCL(0);
- SDA_OUT();
- IIC_SDA(1);
- delay_us(2);
- IIC_SCL(1);
- delay_us(2);
- IIC_SCL(0);
- }
用GPIO模擬等待應答信號,如果返回值是1,則接受應答失敗,如果返回值是0,則接受應答成功
- u8 IIC_Wait_Ack(void){
- u8 ucErrTime=0;
- SDA_IN(); //SDA設置為輸入
- IIC_SDA(1);delay_us(1);
- IIC_SCL(1);delay_us(1);
- #if 1
- while(READ_SDA){
- ucErrTime++;
- if(ucErrTime>250)
- {
- IIC_Stop();
- //printf("IIC_Wait_Ack erro\r\n");
- return 1;
- }
- }
- #else
- ucErrTime++;
- delay_us(3);
- #endif
- IIC_SCL(0);//時鐘輸出0
- return 0;
- }
發送數據的實現
- void IIC_Send_Byte(u8 txd){
- u8 t;
- SDA_OUT();
- IIC_SCL(0);//拉低時鐘開始數據傳輸
- for(t=0;t<8;t++){
- IIC_SDA((txd&0x80)>>7);
- txd<<=1;
- delay_us(2); //對TEA5767這三個延時都是必須的
- IIC_SCL(1);
- delay_us(2);
- IIC_SCL(0);
- delay_us(2);
- }
- }
IIC發送一個字節,返回從機有無應答,返回值是1時有應答,返回值是0時無應答
- u8 IIC_Read_Byte(unsigned char ack){
- unsigned char i,receive=0;
- SDA_IN();//SDA設置為輸入
- for(i=0;i<8;i++ ){
- IIC_SCL(0);
- delay_us(2);
- IIC_SCL(1);
- receive<<=1;
- if(READ_SDA)receive++;
- delay_us(1);
- }
- if (!ack)
- IIC_NAck();//發送nACK
- else
- IIC_Ack(); //發送ACK
- return receive;
- }
讀1個字節,ack=1時,發送ACK,ack=0時,發送nACK
在主函數里初始化IIC,再初始化芯片里的相關寄存器

在max30102.c里按照芯片規格書,通過模擬的IIC對寄存器進行讀取,再調用下芯片原廠提供的算法,將采集到的值輸出在顯示屏上

3、結語
以上都完成之后,就可以編譯、燒錄,就可以測試最后的完成效果。
對于想去高海拔的小伙伴們,可以帶一個便攜式血氧檢測儀,隨時監控自己的身體狀況哦~
文章相關附件可以點擊下面的原文鏈接前往下載