色婷婷AⅤ一区二区三区|亚洲精品第一国产综合亚AV|久久精品官方网视频|日本28视频香蕉

          新聞中心

          基礎(chǔ)知識(shí)之血氧傳感器

          作者: 時(shí)間:2024-03-18 來(lái)源:電子森林 收藏

          是一種用于測(cè)量人體血液中氧氣飽和度的設(shè)備。它通過(guò)非侵入性或微創(chuàng)性的方式獲取血氧水平的相關(guān)數(shù)據(jù)。通常使用光學(xué)原理來(lái)工作。

          本文引用地址:http://cafeforensic.com/article/202403/456426.htm

          血氧傳感器中最常見(jiàn)的類型是脈搏血氧飽和度(SpO2)傳感器,也被稱為脈搏血氧傳感器。SpO2傳感器利用光的吸收特性來(lái)測(cè)量血紅蛋白的氧合程度。它通過(guò)發(fā)射兩種不同波長(zhǎng)的光(通常是紅光和紅外光)經(jīng)過(guò)皮膚照射到血液中,然后通過(guò)相應(yīng)的光電傳感器測(cè)量經(jīng)過(guò)皮膚反射回來(lái)的光的強(qiáng)度。根據(jù)紅光和紅外光的吸收差異,可以計(jì)算出血液中氧氣的飽和度。

          人體需要并調(diào)節(jié)血液中氧氣的非常精確和特定的平衡。人體的正常動(dòng)脈血氧飽和度(SpO2)為97-100%,或96-99%。如果該水平低于90%,則被認(rèn)為是低氧血癥。動(dòng)脈血氧水平低于80%可能會(huì)損害器官功能,例如大腦和心臟,應(yīng)及時(shí)解決。持續(xù)的低氧水平可能導(dǎo)致呼吸或心臟驟停。

          血氧傳感器常見(jiàn)于醫(yī)療領(lǐng)域,特別是在監(jiān)護(hù)設(shè)備、手持式脈搏氧飽和度儀和睡眠呼吸監(jiān)測(cè)等應(yīng)用中。此外,它們也逐漸應(yīng)用于個(gè)人健康監(jiān)測(cè)設(shè)備,如智能手環(huán)、智能手表等。

          圖1:max30102光電式心率血氧傳感器

          血氧傳感器通常使用光學(xué)原理來(lái)測(cè)量血紅蛋白的氧合程度,其中最常見(jiàn)的類型是脈搏氧血飽和度(SpO2)傳感器。

          圖2:光學(xué)原理

          以下是血氧傳感器的工作原理:

          • 發(fā)射光:血氧傳感器發(fā)射兩種不同波長(zhǎng)的光,通常是紅光和紅外光。這兩種波長(zhǎng)的光可被血紅蛋白分別吸收。紅光波長(zhǎng)大約在600-700納米范圍內(nèi),而紅外光波長(zhǎng)大約在800-1000納米范圍內(nèi)。
          • 光的吸收:發(fā)射的光通過(guò)皮膚照射到血液中。在經(jīng)過(guò)皮膚的組織和血液后,光會(huì)被血紅蛋白吸收。被氧合的血紅蛋白和脫氧的血紅蛋白對(duì)紅光和紅外光的吸收程度不同。
          • 光的檢測(cè):血氧傳感器通過(guò)相應(yīng)的光電傳感器測(cè)量經(jīng)過(guò)皮膚反射回來(lái)的光的強(qiáng)度。光電傳感器會(huì)測(cè)量紅光和紅外光的強(qiáng)度,并將其轉(zhuǎn)換為電信號(hào)。
          • 數(shù)據(jù)處理:血氧傳感器會(huì)對(duì)紅光和紅外光的強(qiáng)度進(jìn)行比較和計(jì)算,以確定血液中氧氣的飽和度。通過(guò)比較兩種光的吸收差異,可以推導(dǎo)出血氧飽和度的估計(jì)值。

          血氧傳感器只能提供間接的血氧飽和度測(cè)量結(jié)果,并且有一定的誤差范圍。其他因素如溫度、燈光干擾、運(yùn)動(dòng)等也可能對(duì)測(cè)量結(jié)果產(chǎn)生影響。

          1 臨床監(jiān)護(hù):血氧傳感器常用于臨床監(jiān)護(hù)中,例如在手術(shù)室、急診室和重癥監(jiān)護(hù)病房。通過(guò)監(jiān)測(cè)患者的血氧飽和度(SPO2)水平,醫(yī)護(hù)人員可以實(shí)時(shí)了解患者的氧氣供應(yīng)情況,及時(shí)發(fā)現(xiàn)并處理低氧血癥或窒息等問(wèn)題,確?;颊叩陌踩?/span>

          2 睡眠呼吸監(jiān)測(cè):血氧傳感器被廣泛應(yīng)用于睡眠呼吸監(jiān)測(cè)領(lǐng)域。睡眠時(shí),佩戴血氧傳感器的設(shè)備(如脈搏氧飽和度儀)能夠監(jiān)測(cè)睡眠者的血氧水平。通過(guò)分析血氧飽和度數(shù)據(jù),醫(yī)生或睡眠專家可以評(píng)估睡眠質(zhì)量、檢測(cè)睡眠呼吸暫停等呼吸障礙,并為患者提供相應(yīng)的治療建議。

          3 慢性阻塞性肺疾病(COPD)管理:COPD患者常使用血氧傳感器來(lái)管理他們的疾病。他們可以在家中使用脈搏氧飽和度儀來(lái)測(cè)量自己的血氧水平,并追蹤數(shù)據(jù)的變化。這有助于監(jiān)測(cè)疾病的進(jìn)展、評(píng)估治療效果,并及時(shí)采取相應(yīng)的措施,如調(diào)整藥物劑量或進(jìn)行氧療。

          4 家庭健康監(jiān)測(cè):現(xiàn)代的脈搏氧飽和度儀(Pulse Oximeter)通常集成了血氧傳感器,被廣泛應(yīng)用于家庭健康監(jiān)測(cè)場(chǎng)景。人們可以通過(guò)在家中使用這種設(shè)備來(lái)監(jiān)測(cè)自己或家人的血氧水平,以及心率等信息。這對(duì)于早期發(fā)現(xiàn)可能存在的呼吸系統(tǒng)問(wèn)題、心血管疾病和睡眠呼吸暫停等狀況非常有幫助。此外,一些健康追蹤設(shè)備和智能手表也集成了血氧傳感器,能夠提供用戶的血氧飽和度數(shù)據(jù),幫助用戶更好地了解自己的健康狀況。

          5 高海拔登山:登山者在攀登高海拔地區(qū)時(shí)通常會(huì)面臨低氧環(huán)境。血氧傳感器被用于監(jiān)測(cè)登山者的血氧水平,幫助他們了解身體在高海拔環(huán)境下的氧氣供應(yīng)情況。這樣的信息可以幫助他們判斷是否需要停止攀登或采取其他適當(dāng)?shù)男袆?dòng)來(lái)避免高山病等潛在風(fēng)險(xiǎn)。

          6 運(yùn)動(dòng)訓(xùn)練和健身監(jiān)測(cè):血氧傳感器在運(yùn)動(dòng)訓(xùn)練和健身監(jiān)測(cè)中起著重要作用。運(yùn)動(dòng)員可以使用集成了血氧傳感器的可穿戴設(shè)備,如智能手表或運(yùn)動(dòng)耳機(jī),來(lái)監(jiān)測(cè)他們的血氧水平和心率等數(shù)據(jù)。這些數(shù)據(jù)可以幫助運(yùn)動(dòng)員和教練員了解身體在運(yùn)動(dòng)過(guò)程中的氧氣攝取能力和運(yùn)動(dòng)耐力水平,并進(jìn)行相應(yīng)的訓(xùn)練調(diào)整。此外,血氧傳感器還可以幫助跑步愛(ài)好者監(jiān)測(cè)自己的運(yùn)動(dòng)表現(xiàn),提供健身指導(dǎo)和優(yōu)化跑步計(jì)劃。

          Maxim Integrated :Maxim Integrated是一家知名的集成電路設(shè)計(jì)和生產(chǎn)公司,提供多種心率傳感器芯片和模塊。其中,MAX30102是一款常見(jiàn)的心率傳感器模塊,集成了紅外LED、紅光LED和光電傳感器,適用于便攜設(shè)備和健康監(jiān)測(cè)設(shè)備等應(yīng)用。

          Texas Instruments(TI):TI是一家全球領(lǐng)先的半導(dǎo)體公司,提供多款生物傳感器芯片和模塊。AFE4404是TI的一款心率監(jiān)測(cè)芯片,集成了紅外LED、綠光LED、光電傳感器和ADC等功能,可實(shí)現(xiàn)高精度的心率和血氧濃度測(cè)量。

          Analog Devices(ADI):ADI是一家知名的模擬與數(shù)字混合信號(hào)處理技術(shù)供應(yīng)商,提供多種生物傳感器芯片和模塊。AD8232是ADI的一款心率傳感器芯片,專為心電圖(ECG)采集設(shè)計(jì),具備高性能和低功耗特點(diǎn)。

          Nellcor (Medtronic):Nellcor是Medtronic旗下的品牌,專注于提供高質(zhì)量的血氧傳感器芯片和模塊。他們的SpO2傳感器采用專有的信號(hào)處理算法,具有高靈敏度和抗干擾能力。Nellcor的血氧傳感器在醫(yī)療領(lǐng)域廣泛應(yīng)用,包括重癥監(jiān)護(hù)、手術(shù)室和急診等環(huán)境。

          NXP Semiconductors:NXP Semiconductors是一家全球領(lǐng)先的半導(dǎo)體解決方案提供商,他們提供適用于醫(yī)療應(yīng)用的心率、血氧和心電圖傳感器芯片。

          Silicon Labs:Silicon Labs是一家專注于集成電路解決方案的公司,他們提供用于生物傳感器應(yīng)用的芯片產(chǎn)品,包括心率、血氧和心電圖傳感器芯片。

          在Thonny使用Mircopython編寫(xiě)程序控制RP2040控制Max30102讀取心率數(shù)據(jù)

          Max30102芯片介紹

          MAX30102是一個(gè)集成的脈搏血氧計(jì)和心率監(jiān)測(cè)器模塊。它包括內(nèi)部LED、光電探測(cè)器、光學(xué)元件和具有環(huán)境光抑制功能的低噪聲電子器件。

          MAX30102使用一個(gè)1.8V電源和一個(gè)用于內(nèi)部LED的獨(dú)立3.3V電源。通過(guò)標(biāo)準(zhǔn)I2C兼容接口進(jìn)行通信。該模塊可以通過(guò)零待機(jī)電流的軟件關(guān)閉,使電源導(dǎo)軌始終保持通電狀態(tài)。

          電路連接

          程序代碼

          程序文件需要文件

          • init.py
          • circular_buffer.py
          • spo2cal.py
          • HR_SpO2.py

          前面兩個(gè)文件可在github上面下載https://github.com/n-elia/MAX30102-MicroPython-driver/tree/main/max30102

          spo2cal.py程序如下

              # -*-coding:utf-8     # 25 samples per second (in algorithm.h)
             SAMPLE_FREQ = 25
             # taking moving average of 4 samples when calculating HR    # in algorithm.h, "DONOT CHANGE" comment is attached
             MA_SIZE = 4
             # sampling frequency * 4 (in algorithm.h)
             BUFFER_SIZE = 100 
               # this assumes ir_data and red_data as np.array
             def calc_hr_and_spo2(ir_data, red_data):
                 """
                 By detecting  peaks of PPG cycle and corresponding AC/DC
                 of red/infra-red signal, the an_ratio for the SPO2 is computed.
                 """
                 # get dc mean
                 ir_mean = int(sum(ir_data) / len(ir_data))         # remove DC mean and inver signal        # this lets peak detecter detect valley
                 x = [ir_mean - x for x in ir_data]         # 4 point moving average        # x is np.array with int values, so automatically casted to int
                 for i in range(len(x) - MA_SIZE):
                     x[i] = sum(x[i:i + MA_SIZE]) / MA_SIZE
                   # calculate threshold
                 n_th = int(sum(x) / len(x))
                 n_th = 30 if n_th < 30 else n_th  # min allowed
                 n_th = 60 if n_th > 60 else n_th  # max allowed
           
                 ir_valley_locs, n_peaks = find_peaks(x, BUFFER_SIZE, n_th, 4, 15)
                 # print(ir_valley_locs[:n_peaks], ",", end="")
                 peak_interval_sum = 0
                 if n_peaks >= 2:
                     for i in range(1, n_peaks):
                         peak_interval_sum += (ir_valley_locs[i] - ir_valley_locs[i - 1])
                     peak_interval_sum = int(peak_interval_sum / (n_peaks - 1))
                     hr = int(SAMPLE_FREQ * 60 / peak_interval_sum)
                     hr_valid = True        else:
                     hr = -999  # unable to calculate because # of peaks are too small
                     hr_valid = False
                   # ---------spo2---------         # find precise min near ir_valley_locs (???)
                 exact_ir_valley_locs_count = n_peaks
                   # find ir-red DC and ir-red AC for SPO2 calibration ratio        # find AC/DC maximum of raw
                   # FIXME: needed??
                 for i in range(exact_ir_valley_locs_count):
                     if ir_valley_locs[i] > BUFFER_SIZE:
                         spo2 = -999  # do not use SPO2 since valley loc is out of range
                         spo2_valid = False                return hr, hr_valid, spo2, spo2_valid
           
                 i_ratio_count = 0
                 ratio = []         # find max between two valley locations        # and use ratio between AC component of Ir and Red DC component of Ir and Red for SpO2
                 red_dc_max_index = -1
                 ir_dc_max_index = -1
                 for k in range(exact_ir_valley_locs_count - 1):
                     red_dc_max = -16777216
                     ir_dc_max = -16777216
                     if ir_valley_locs[k + 1] - ir_valley_locs[k] > 3:
                         for i in range(ir_valley_locs[k], ir_valley_locs[k + 1]):
                             if ir_data[i] > ir_dc_max:
                                 ir_dc_max = ir_data[i]
                                 ir_dc_max_index = i                    if red_data[i] > red_dc_max:
                                 red_dc_max = red_data[i]
                                 red_dc_max_index = i
           
                         red_ac = int((red_data[ir_valley_locs[k + 1]] - red_data[ir_valley_locs[k]]) * (red_dc_max_index - ir_valley_locs[k]))
                         red_ac = red_data[ir_valley_locs[k]] + int(red_ac / (ir_valley_locs[k + 1] - ir_valley_locs[k]))
                         red_ac = red_data[red_dc_max_index] - red_ac  # subtract linear DC components from raw
           
                         ir_ac = int((ir_data[ir_valley_locs[k + 1]] - ir_data[ir_valley_locs[k]]) * (ir_dc_max_index - ir_valley_locs[k]))
                         ir_ac = ir_data[ir_valley_locs[k]] + int(ir_ac / (ir_valley_locs[k + 1] - ir_valley_locs[k]))
                         ir_ac = ir_data[ir_dc_max_index] - ir_ac  # subtract linear DC components from raw
           
                         nume = red_ac * ir_dc_max
                         denom = ir_ac * red_dc_max                if (denom > 0 and i_ratio_count < 5) and nume != 0:
                             # original cpp implementation uses overflow intentionally.                    # but at 64-bit OS, Pyhthon 3.X uses 64-bit int and nume*100/denom does not trigger overflow                    # so using bit operation ( &0xffffffff ) is needed
                             ratio.append(int(((nume * 100) & 0xffffffff) / denom))
                             i_ratio_count += 1         # choose median value since PPG signal may vary from beat to beat
                 ratio = sorted(ratio)  # sort to ascending order
                 mid_index = int(i_ratio_count / 2) 
                 ratio_ave = 0
                 if mid_index > 1:
                     ratio_ave = int((ratio[mid_index - 1] + ratio[mid_index]) / 2)
                 else:
                     if len(ratio) != 0:
                         ratio_ave = ratio[mid_index]         # why 184?
                 # print("ratio average: ", ratio_ave)
                 if ratio_ave > 2 and ratio_ave < 184:
                     # -45.060 * ratioAverage * ratioAverage / 10000 + 30.354 * ratioAverage / 100 + 94.845
                     spo2 = -45.060 * (ratio_ave ** 2) / 10000.0 + 30.054 * ratio_ave / 100.0 + 94.845
                     spo2_valid = True        else:
                     spo2 = -999
                     spo2_valid = False
                   return hr - 20, hr_valid, spo2, spo2_valid
           
           
             def find_peaks(x, size, min_height, min_dist, max_num):
                 """
                 Find at most MAX_NUM peaks above MIN_HEIGHT separated by at least MIN_DISTANCE
                 """
                 ir_valley_locs, n_peaks = find_peaks_above_min_height(x, size, min_height, max_num)
                 ir_valley_locs, n_peaks = remove_close_peaks(n_peaks, ir_valley_locs, x, min_dist) 
                 n_peaks = min([n_peaks, max_num])         return ir_valley_locs, n_peaks
           
           
             def find_peaks_above_min_height(x, size, min_height, max_num):
                 """
                 Find all peaks above MIN_HEIGHT
                 """ 
                 i = 0
                 n_peaks = 0
                 ir_valley_locs = []  # [0 for i in range(max_num)]
                 while i < size - 1:
                     if x[i] > min_height and x[i] > x[i - 1]:  # find the left edge of potential peaks
                         n_width = 1
                         # original condition i+n_width < size may cause IndexError                # so I changed the condition to i+n_width < size - 1
                         while i + n_width < size - 1 and x[i] == x[i + n_width]:  # find flat peaks
                             n_width += 1
                         if x[i] > x[i + n_width] and n_peaks < max_num:  # find the right edge of peaks                    # ir_valley_locs[n_peaks] = i
                             ir_valley_locs.append(i)
                             n_peaks += 1  # original uses post increment
                             i += n_width + 1
                         else:
                             i += n_width            else:
                         i += 1         return ir_valley_locs, n_peaks
           
           
             def remove_close_peaks(n_peaks, ir_valley_locs, x, min_dist):
                 """
                 Remove peaks separated by less than MIN_DISTANCE
                 """         # should be equal to maxim_sort_indices_descend        # order peaks from large to small
                 # should ignore index:0
                 sorted_indices = sorted(ir_valley_locs, key=lambda i: x[i])
                 sorted_indices.reverse()         # this "for" loop expression does not check finish condition        # for i in range(-1, n_peaks):
                 i = -1
                 while i < n_peaks:
                     old_n_peaks = n_peaks
                     n_peaks = i + 1
                     # this "for" loop expression does not check finish condition            # for j in (i + 1, old_n_peaks):
                     j = i + 1
                     while j < old_n_peaks:
                         n_dist = (sorted_indices[j] - sorted_indices[i]) if i != -1 else (sorted_indices[j] + 1)  # lag-zero peak of autocorr is at index -1
                         if n_dist > min_dist or n_dist < -1 * min_dist:
                             sorted_indices[n_peaks] = sorted_indices[j]
                             n_peaks += 1  # original uses post increment
                         j += 1
                     i += 1 
                 sorted_indices[:n_peaks] = sorted(sorted_indices[:n_peaks])         return sorted_indices, n_peaks
           
               if __name__ == "__main__":
                 hr, hrb, sp, spb = calc_hr_and_spo2([12853, 15573, 15580, 15586, 15587, 15567, 15520, 15480, 15464, 15460, 15462, 15466, 15473, 15479, 15485, 15490, 15495, 15503, 15512, 15518, 15521, 15521, 15518, 15517, 15522, 15527, 15536, 15547, 15558, 15568, 15577, 15587, 15594, 15604, 15610, 15616, 15620, 15624, 15625, 15615, 15576, 15531, 15508, 15500, 15502, 15509, 15516, 15523, 15528, 15533, 15538, 15547, 15556, 15564, 15564, 15560, 15556, 15556, 15559, 15564, 15570, 15579, 15588, 15599, 15610, 15619, 15628, 15635, 15642, 15649, 15655, 15662, 15669, 15672, 15661, 15621, 15571, 15546, 15537, 15538, 15545, 15553, 15560, 15565, 15570, 15577, 15585, 15593, 15600, 15601, 15597, 15592, 15591, 15594, 15600, 15608, 15617, 15626, 15633, 15640], [12258, 14318, 14322, 14324, 14326, 14317, 14299, 14284, 14280, 14279, 14280, 14283, 14285, 14288, 14292, 14294, 14297, 14299, 14302, 14304, 14305, 14305, 14304, 14304, 14306, 14308, 14311, 14316, 14321, 14325, 14329, 14333, 14329, 14329, 14332, 14335, 14336, 14338, 14338, 14333, 14315, 14295, 14286, 14283, 14285, 14288, 14292, 14295, 14297, 14298, 14301, 14305, 14309, 14312, 14312, 14310, 14308, 14308, 14309, 14312, 14315, 14318, 14322, 14327, 14332, 14336, 14341, 14344, 14347, 14350, 14351, 14354, 14357, 14359, 14353, 14335, 14313, 14304, 14300, 14302, 14305, 14309, 14312, 14314, 14316, 14319, 14323, 14326, 14329, 14329, 14326, 14325, 14324, 14326, 14328, 14332, 14336, 14341, 14345, 14349]) 
                 print("hr detected:", hrb)
                 print("sp detected:", spb)         if (hrb == True and hr != -999):
                     hr2 = int(hr)
                     print("Heart Rate : ", hr2)
                 if (spb == True and sp != -999):
                     sp2 = int(sp)
                     print("SPO2       : ", sp2) 
           

          HR_SpO2.py程序如下:

              from machine import SoftI2C, Pin, Timer
             from utime import ticks_diff, ticks_us
             from max30102 import MAX30102, MAX30105_PULSE_AMP_MEDIUM
             from spo2cal import calc_hr_and_spo2
           
           
             BEATS = 0  # 存儲(chǔ)心率
             FINGER_FLAG = False  # 默認(rèn)表示未檢測(cè)到手指
           
             SPO2 = 0  # 存儲(chǔ)血氧
             TEMPERATURE = 0  # 存儲(chǔ)溫度
           
           
             def display_info(t):
                 # 如果沒(méi)有檢測(cè)到手指,那么就不顯示        if FINGER_FLAG is False:
                     return 
                 print('Heart Rate: ', BEATS, " SpO2:", SPO2, " Temperture:", TEMPERATURE) 
           
             def main():
                 global BEATS, FINGER_FLAG, SPO2, TEMPERATURE  # 如果需要對(duì)全局變量修改,則需要global聲明
                   # 創(chuàng)建I2C對(duì)象(檢測(cè)MAX30102)
                 i2c = SoftI2C(sda=Pin(16), scl=Pin(17), freq=400000)  # Fast: 400kHz, slow: 100kHz
                   # 創(chuàng)建傳感器對(duì)象
                 sensor = MAX30102(i2c=i2c)         # 檢測(cè)是否有傳感器        if sensor.i2c_address not in i2c.scan():
                     print("沒(méi)有找到傳感器")
                     return
                 elif not (sensor.check_part_id()):
                     # 檢查傳感器是否兼容
                     print("檢測(cè)到的I2C設(shè)備不是MAX30102或者M(jìn)AX30105")
                     return
                 else:
                     print("傳感器已識(shí)別到")         # 配置
                 sensor.setup_sensor()
                 sensor.set_sample_rate(400)
                 sensor.set_fifo_average(8)
                 sensor.set_active_leds_amplitude(MAX30105_PULSE_AMP_MEDIUM) 
                 t_start = ticks_us()  # Starting time of the acquisition
           
                 MAX_HISTORY = 32
                 history = []
                 beats_history = []
                 beat = False
           
                 red_list = []
                 ir_list = []         while True:
                     sensor.check()
                     if sensor.available():
                         # FIFO 先進(jìn)先出,從隊(duì)列中取數(shù)據(jù)。都是整形int
                         red_reading = sensor.pop_red_from_storage()
                         ir_reading = sensor.pop_ir_from_storage()                 if red_reading < 1000:
                             print('No finger')
                             FINGER_FLAG = False  # 表示沒(méi)有放手指                    continue
                         else:
                             FINGER_FLAG = True  # 表示手指已放
                           # 計(jì)算心率
                         history.append(red_reading)                 # 為了防止列表過(guò)大,這里取列表的后32個(gè)元素
                         history = history[-MAX_HISTORY:]                 # 提取必要數(shù)據(jù)
                         minima, maxima = min(history), max(history)
                         threshold_on = (minima + maxima * 3) // 4   # 3/4
                         threshold_off = (minima + maxima) // 2      # 1/2                 if not beat and red_reading > threshold_on:
                             beat = True                    
                             t_us = ticks_diff(ticks_us(), t_start)
                             t_s = t_us/1000000
                             f = 1/t_s
                             bpm = f * 60
                             if bpm < 500:
                                 t_start = ticks_us()
                                 beats_history.append(bpm)                    
                                 beats_history = beats_history[-MAX_HISTORY:]   # 只保留最大30個(gè)元素?cái)?shù)據(jù)
                                 BEATS = round(sum(beats_history)/len(beats_history), 2)  # 四舍五入                if beat and red_reading < threshold_off:
                             beat = False
                           # 計(jì)算血氧
                         red_list.append(red_reading)
                         ir_list.append(ir_reading)
                         # 最多 只保留最新的100個(gè)
                         red_list = red_list[-100:]
                         ir_list = ir_list[-100:]
                         # 計(jì)算血氧值                if len(red_list) == 100 and len(ir_list) == 100:
                             hr, hrb, sp, spb = calc_hr_and_spo2(red_list, ir_list)
                             if hrb is True and spb is True:
                                 if sp != -999:
                                     SPO2 = int(sp)                 # 計(jì)算溫度
                         TEMPERATURE = sensor.read_temperature() 
               if __name__ == '__main__': 
                 tim = Timer(period=1000, mode=Timer.PERIODIC, callback=display_info) 
                 main() 
           

          運(yùn)行效果



          關(guān)鍵詞: 血氧傳感器

          評(píng)論


          技術(shù)專區(qū)

          關(guān)閉