基于MAX30100和stm32的血氧检测系统

    xiaoxiao2021-03-25  75

    参考资料

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6ruMH93P-1578563433204)(http://139.199.225.16/blog_pic/2017_03_10/system_block.jpg)]

    这里有一篇TI的测血氧文档http://www.ti.com/lit/an/slaa274b/slaa274b.pdf,其中的给的测血氧的公式没怎么看懂,关键怎么通过这公式得到血氧的含量的 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8cX5Iary-1578563433206)(http://139.199.225.16/blog_pic/2017_03_10/R_SaO2.jpg)]

    MX30100的使用

    通讯是标准的I2C通讯,在通讯过程中要注意一点,就是在进行读操作时,读出一个寄存器值后给予ACK,读寄存器的指针会自动加一,但有一个寄存器例外就是FIFO寄存器(0x05)。 Datasheet上有一段*“Reading the FIFO_DATA register does not automatically increment the register address; burst reading this register readsthe same address over and over. Each sample is 4 bytes of data, so this register has to be read 4 times to get one sample. The other exception is 0xFF, reading more bytes after the 0xFF register does not advance the address pointer back to0x00, and the data read is not meaningful”*两个LED的电流不要设成最大的值,否则读出来的值都是0xffff。

    数据的处理

    心率

    在实际操作中发现,使用IR(红外)读出的心跳值(AC Component)会比较偏大,所以使用IR读出的数据作为测心率的标准。

    初始数据读出如下图,注意纵坐标,交流部分只占直流的很少一部分

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XM0hMMxx-1578563433208)(http://139.199.225.16/blog_pic/2017_03_10/DataBeforeProcess.jpg)]

    滤波一开始采用带通滤波器的方法,目的是滤掉直流部分和交流部分中心率波上面的毛刺可是发现不理想(带通滤波器参数 fs = 100Hz, fls = 0.8Hz, fhs = 2.5Hz, 四阶IIR),选这个参数是因为心跳频率一般在1Hz-2Hz之间。估计是采样频率太低了,但是stm32f103的性能满足不了更高采样率的滤波器, 以后用更高性能的芯片试试。

    后来直接区512点的滑动平均求的直流分量,原始数据减去直流分量就得出交流分量,如下图 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LgWMZ6gL-1578563433211)(http://139.199.225.16/blog_pic/2017_03_10/DataAfterAve.jpg)] 做个峰值检测就得到心率

    血氧

    应该需要进行定标的工作,只根据公式简单写出算法。

    stm32滤波器的使用(官方DSP库的使用)

    arm_biquad_cascade_df1_q31(…)这次使用直接I型的IIR滤波器函数,用Matlab的Fdatool求出sos(安富莱教程), 然后将参数写入滤波器初始化函数中就行。注意因为使用的Q31格式,参数也必须是Q31格式,必须将参数缩小到Q31格式能表示的范围内。还要注意的就是输入序列,其值的范围必须在【-0.25 +0.25)中,因为官方库有这样一段话(In order to avoid overflows completely the input signal must be scaled down by 2 bits and lie in the range [-0.25 +0.25).)。

    附上一个Matlab 滤波器 与 MCU 滤波器的比较Matlab程序。

    function [X1, X2, X3] = MCU_Filter_Test(sos, xin, ymcu, Len) %MCU Filter Test [b, a] = sos2tf(sos); y = filter(b, a, xin); X1 = fft(xin); X2 = fft(y); X3 = fft(ymcu); n = [0 : Len - 1]; subplot(3,2,1); plot(n, xin);title('xin'); subplot(3,2,2); plot(n, abs(X1));title('xin-fft'); subplot(3,2,3); plot(n, y);title('y'); subplot(3,2,4); plot(n, abs(X2));title('y-fft'); subplot(3,2,5); plot(n, ymcu);title('ymcu'); subplot(3,2,6); plot(n, abs(X3));title('ymcu-fft');

    系统程序

    因为已经转行做软件了,所以将所有的代码公开。当初这个系统是在大学的时候做的,是帮的做毕业设计。

    下载 基于MAX30100和stm32的血氧检测系统。

    转载请注明原文地址: https://ju.6miu.com/read-27510.html

    最新回复(0)