在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

嵌入式軟件設計之PPG采集系統

云深之無跡 ? 來源:云深之無跡 ? 2023-08-03 10:18 ? 次閱讀

500d6ae2-318e-11ee-9e74-dac502259ad0.png

嵌入式系統是分層級的,分模塊的。

使用的硬件資源有:

IMU-IIC

采集-ADC

電源-ADC

外置接口-串口

主控部分使用ESP32-IDF進行開發,因為芯片寄存器較多,而且采集對的實時性有要求,所以選用freeRTOS,在滿足實時性的要求上程序的設計也會更簡單。

FreeRTOS任務設計

MAX30102采集任務:初始化IIC和MAX30102,在一個死循環里面以50Hz的頻率讀取紅外線和紅光傳感器的數據,進行簡單濾波后存入隊列。

MPU6050任務:初始化IIC和MPU6050,連續讀取Euler角,以20Hz的頻率進行更新,數據處理后存入隊列。

ADC采集任務:初始化ADC,以適當采樣頻率(例如100Hz)采集模擬通道電壓,發送到隊列。

串口發送任務:優先級最低,從隊列中讀取數據并打包發送。可以設置一定的數據緩存。

空閑任務:優先級最低,MCU睡眠時運行,用于切換低功耗模式。

數據同步

采用FreeRTOS的隊列和信號量機制進行任務間同步。信號量可用于指示隊列已滿或空。

給每個數據包添加采集時間戳,上位機可以根據時間戳重新同步。

也可以僅在串口發送任務中合并時間戳,不在各個采集任務中添加。

低功耗設計

利用調度器suspend/resume接口暫停任務實現睡眠喚醒。

DMA采集ADC數據,避免CPU占用。

使用內部PERIPH FIFO buffer,減少IIC任務調用。

串口使用DMA傳輸,CPU僅在發送完一個包后進行復位。

關閉不需要的外設時鐘。利用IDLE調度鉤子函數實現自動降頻。

模塊化設計

獨立通信模塊,內部封裝串口通信的復雜度。

采集核心模塊只輸出統一格式的采集數據。

模塊間使用統一的隊列/緩存接口進行數據交換。

502d2292-318e-11ee-9e74-dac502259ad0.png504c494c-318e-11ee-9e74-dac502259ad0.png

這里給出采集的樣板任務

針對MAX30102的芯片,更多的技術細節是:首先配置傳感器工作在FIFO模式下然后周期性讀取FIFO,通過1024點的FFT變換得到頻域數據,然后選擇頻帶內的最高幅值為心率,通過對比兩個幅值的幅度計算出血氧飽和度。通過平均其他頻點的差值來標定兩個波長數據。

struct compx FFTBUF1[FFT_N + 16];
struct compx FFTBUF2[FFT_N + 16];
uint16_t g_fft_index = 0;
BloodData g_blooddata = {0};


void test(float data1, float data2)
{
    static uint8_t str[50];
    sprintf((char *)str, "%f,%f
", data1, data2);
    HAL_UART_Transmit_DMA(&huart1, str, sizeof(str));
}


// 血液檢測信息更新
void blood_data_update(void)
{
    static DC_FilterData dc1 = {.w = 0, .init = 0, .a = 0.8};
    static DC_FilterData dc2 = {.w = 0, .init = 0, .a = 0.8};
    static float data1buf[20];
    static uint8_t data1cur = 0;
    static float data2buf[20];
    static uint8_t data2cur = 0;
    uint16_t temp_num = 0;
    uint16_t fifo_word_buff[1][2];
    temp_num = max30100_Bus_Read(INTERRUPT_REG);
    if (INTERRUPT_REG_A_FULL & temp_num)
    {
        max30100_FIFO_Read(0x05, fifo_word_buff, 1); // read the hr and spo2 data form fifo in reg=0x05
        float data1 = dc_filter(fifo_word_buff[0][0], &dc1) + 100.0;
        float data2 = dc_filter(fifo_word_buff[0][1], &dc2) + 100.0;
        data1buf[data1cur] = data1;
        data2buf[data2cur] = data2;
        data1 = 0;
        data2 = 0;
        for (int i = 0; i < 20; i++)
        {
            data1 += data1buf[i];
            data2 += data2buf[i];
        }
        data1 /= 20;
        data2 /= 20;
        data1cur = (data1cur < 19) ? data1cur + 1 : 0;
        data2cur = (data2cur < 19) ? data2cur + 1 : 0;
        g_blooddata.hb = data1 + 50;
        g_blooddata.hbo2 = data2 + 50;
        // 將數據寫入fft輸入并清除輸出
        for (int i = 0; i < 1; i++)
        {
            if (g_fft_index < FFT_N)
            {
                FFTBUF1[g_fft_index].real = fifo_word_buff[i][0];
                FFTBUF1[g_fft_index].imag = 0;
                FFTBUF2[g_fft_index].real = fifo_word_buff[i][1];
                FFTBUF2[g_fft_index].imag = 0;
                g_fft_index++;
            }
        }
        // 信息更新標志位
        g_blooddata.update++;
    }
}
// 血液信息轉換
void blood_data_translate(void)
{
    // 緩沖區寫入結束
    if (g_fft_index >= FFT_N)
    {
        // 快速傅里葉變換
        FFT(FFTBUF1);
        FFT(FFTBUF2);
        // 解平方
        for (int i = 0; i < FFT_N; i++)
        {
            FFTBUF1[i].real = sqrtf(FFTBUF1[i].real * FFTBUF1[i].real + FFTBUF1[i].imag * FFTBUF1[i].imag);
            FFTBUF2[i].real = sqrtf(FFTBUF2[i].real * FFTBUF2[i].real + FFTBUF2[i].imag * FFTBUF2[i].imag);
        }
        // 讀取峰值點 10-100帶通 頻率范圍30-292次/分鐘
        uint16_t s1_max_index = find_max_num_index(FFTBUF1, 100);
        uint16_t s2_max_index = find_max_num_index(FFTBUF2, 100);


        // 檢查HbO2和Hb的變化頻率是否一致
        if (s1_max_index == s2_max_index)
        {
            // 心率計算
            uint16_t Heart_Rate = 60 * SAMPLES_PER_SECOND *
                                  s2_max_index / FFT_N;
            g_blooddata.heart = Heart_Rate;
            // 血氧含量計算
            float sp02_num = (FFTBUF1[s1_max_index].real * FFTBUF1[0].real) / (FFTBUF2[s1_max_index].real * FFTBUF2[0].real);
            sp02_num = sp02_num * SAMPLES_PER_SECOND + CORRECTED_VALUE;
            g_blooddata.SpO2 = sp02_num;
            // 狀態正常
            g_blooddata.state = BLD_NORMAL;
        }
        else // 數據發生異常
        {
            g_blooddata.heart = 0;
            g_blooddata.SpO2 = 0;
            g_blooddata.state = BLD_ERROR;
        }


        g_fft_index = 0;
    }
}

因為PPG的數據處理是難點,以上給出一段處理代碼,但是還有優化的空間。

將采集數據和處理算法分離開來,降低耦合

可以創建獨立的采集模塊和處理模塊,采集模塊專注獲取傳感器數據,處理模塊實現算法邏輯。兩者通過統一的數據結構進行交互。這可以提高代碼的模塊化和可維護性。

優化數據濾波方式

當前的平均濾波可以考慮改為滾動平均濾波,這樣可以加快數據更新的響應速度。同時可以引入一階IIR濾波來平滑數據。

優化FFT實現

可以考慮使用更優化的FFT庫,或者直接調用DSP庫的FFT函數,提高運算效率。當前的FFTBUFFER可以改為復數數組,簡化運算。

血氧算法可進一步優化

血氧計算中使用了簡單的比值法,可以參考更復雜的算法來提高精度,比如考慮LED功率補償等。

添加參數配置接口

例如采樣率、FFT長度、濾波參數等可以設計成可配置的,而不是硬編碼的數字。這樣可以更靈活地調整參數。

優化數據包發送流程

可以考慮使用FreeRTOS隊列來緩存要發送的數據,發送任務從隊列中獲取數據。這可以避免直接在中斷中發送造成的阻塞。

增加狀態機管理

可以設計一個狀態機來管理整個采集和處理的流程,例如初始化狀態,檢測狀態,發送狀態等。這可以使代碼流程更清晰。

50769b8e-318e-11ee-9e74-dac502259ad0.png

50ac82ee-318e-11ee-9e74-dac502259ad0.png

審核編輯:湯梓紅
聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 嵌入式
    +關注

    關注

    5094

    文章

    19183

    瀏覽量

    307792
  • adc
    adc
    +關注

    關注

    99

    文章

    6534

    瀏覽量

    545787
  • 采集系統
    +關注

    關注

    0

    文章

    171

    瀏覽量

    20706
  • PPG
    PPG
    +關注

    關注

    2

    文章

    67

    瀏覽量

    18246
  • FreeRTOS
    +關注

    關注

    12

    文章

    484

    瀏覽量

    62403

原文標題:PPG采集系統-嵌入式軟件設計思路

文章出處:【微信號:TT1827652464,微信公眾號:云深之無跡】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    嵌入式軟件設計思想與方法

    本帖最后由 lee_st 于 2018-2-24 17:16 編輯 嵌入式軟件設計思想與方法
    發表于 02-24 17:15

    掌握嵌入式系統軟件設計方法

    實驗目的(1)掌握嵌入式系統軟件設計方法,培養分析問題、解決問題、應用知識的能力和創新精神,全面提高綜合素質。(2)熟悉嵌入式Linux開發環境,學會基于UP-CUP6410-II型平臺的Linux
    發表于 11-09 09:05

    嵌入式系統軟件設計的原則是什么

    嵌入式系統軟件設計的原則1、基本原則是“物盡其用”,嵌入式系統的硬件和軟件都必須高效率地設計,去除冗雜? 還應盡可能采用高效率的設計方法,標
    發表于 12-24 06:29

    基于ARM的嵌入式系統軟件設計

    嵌入式軟件的啟動代碼嵌入式軟件開發關鍵技術嵌入式實時操作系統程序的鏈接定位
    發表于 03-25 15:03 ?203次下載
    基于ARM的<b class='flag-5'>嵌入式</b><b class='flag-5'>系統軟件設計</b>

    基于嵌入式的腦卒中康復儀的軟件設計

    本文介紹一種新型嵌入式腦卒中康復治療儀系統軟件設計。以Qt/Embedded為核心實現治療儀的軟件設計,利用Qt/Embedded的多線程技術來實現肌電信號的
    發表于 08-14 09:30 ?29次下載

    ARM嵌入式系統開發-軟件設計與優化

    ARM嵌入式系統開發-軟件設計與優化
    發表于 02-11 09:57 ?94次下載
    ARM<b class='flag-5'>嵌入式</b><b class='flag-5'>系統</b>開發-<b class='flag-5'>軟件設計</b>與優化

    嵌入式USB主機設計(硬件設計和軟件設計)

    嵌入式USB主機設計(硬件設計和軟件設計) 嵌入式USB主機硬件設計選用廉價的51系列單片機(89C52)控制US
    發表于 11-26 13:58 ?1337次閱讀
    <b class='flag-5'>嵌入式</b>USB主機設計(硬件設計和<b class='flag-5'>軟件設計</b>)

    采用構件技術的嵌入式系統復用軟件設計

    采用構件技術的嵌入式系統復用軟件設計 提高軟件生產率成為軟件產業的當務之急;基于構件的軟件復用
    發表于 03-29 15:10 ?804次閱讀
    采用構件技術的<b class='flag-5'>嵌入式</b><b class='flag-5'>系統</b>復用<b class='flag-5'>軟件設計</b>

    嵌入式系統智能鍵盤的軟件設計

    嵌入式系統智能鍵盤的軟件設計 引言鍵盤是智能化測控系統主要的信息輸入方式,是實現人機對話的重要途徑,因此如何有效地控制鍵盤并為系統服務是
    發表于 03-11 13:45 ?1132次閱讀
    <b class='flag-5'>嵌入式</b><b class='flag-5'>系統</b>智能鍵盤的<b class='flag-5'>軟件設計</b>

    基于ARM的嵌入式系統軟件設計部分

    基于ARM的嵌入式系統軟件設計部分
    發表于 01-14 12:32 ?15次下載

    ARM的嵌入式系統軟件設計

    ARM的嵌入式系統軟件設計
    發表于 10-27 15:00 ?8次下載
    ARM的<b class='flag-5'>嵌入式</b><b class='flag-5'>系統軟件設計</b>

    基于RTOS的嵌入式系統軟件設計

    基于RTOS的嵌入式系統軟件設計說明。
    發表于 04-19 14:38 ?17次下載

    嵌入式軟件設計設計模式

    文章目錄前言1.設計模式適配器模式2.設計模式單例模式3.設計模式命令模式前言在嵌入式軟件設計過程中,也會用到一些設計模式,所以說設計
    發表于 10-21 11:07 ?9次下載
    <b class='flag-5'>嵌入式</b><b class='flag-5'>軟件設計</b><b class='flag-5'>之</b>設計模式

    嵌入式系統軟件設計教材資料

    嵌入式系統軟件設計教材資料免費下載。
    發表于 04-12 14:44 ?5次下載

    嵌入式軟件設計的原則分享

    嵌入式軟件開發如果具有更好的閱讀性、擴展性以及維護性,就需要考慮很多因素。今天給大家分享幾個嵌入式軟件設計的原則。
    發表于 02-25 10:54 ?751次閱讀
    <b class='flag-5'>嵌入式</b><b class='flag-5'>軟件設計</b>的原則分享
    主站蜘蛛池模板: 午夜久久久久久网站 | 国产视频资源 | 性夜影院爽黄a爽在线看香蕉 | 亚洲一级影院 | 欧美一区二区三区不卡免费观看 | 免费看大黄 | 欧美成人天天综合天天在线 | 日韩毛片在线影视 | 天天色综合1 | 曰本又色又爽又黄三级视频 | 天天干天天摸天天操 | 天天曰天天干天天操 | 中文字幕乱码人成乱码在线视频 | 六月婷婷综合网 | 午夜 福利| 性久久久久 | 综合激情六月 | 日本欧美强乱视频在线 | 4399一级成人毛片 | 乱妇伦小说 | 奇米网狠狠干 | 久久久国产精品免费看 | 亚洲jjzzjjzz在线观看 | 天天舔天天色 | 国产色爽女 | 99精品久久久久久久婷婷 | 狠狠色狠狠色综合日日32 | 亚色影视| 午夜影院在线观看视频 | 人人揉人人爽五月天视频 | 三级视频在线播放线观看 | 视频综合网 | 夜夜操夜夜爽 | 国产码一区二区三区 | 韩国三级无遮挡床戏视频 | 日韩色天使综合色视频 | 极品丰满翘臀后进啪啪 | 精品黄色录像 | 色香焦| 奇米影视777四色米奇影院 | 欧美午夜场 |