加载中
加载中
表情图片
评为精选
鼓励
加载中...
分享
加载中...
文件下载
加载中...
修改排序
加载中...
【MAX30100】血氧心率检测仪DIY开源【STM32】
kmakise2021/08/08原创 仪器仪表 IP:河北
关键词
血氧饱和度心率

Github 项目链接

attachment icon MAX30100.zip 27.44MB ZIP 712次下载

发一个之前做的血氧心率检测的小东西,使用的是美信的MAX30100和30102

芯片框图:

upload_downloader_1628401817272_44436819.png

7VU1A@NAMVHFC3GUXN0DWB1.png

携带氧气的红血球能吸收较多红外光(850-1000nm),未携带氧气的红血球则是吸收较多的红光(600-750nm),通过这个特性就可以计算血液的血氧饱和度。

大概效果如下图:

2.jpg

1.jpg


数据处理方式:

首先配置传感器工作在FIFO模式下然后周期性读取FIFO,通过1024点的FFT变换得到频域数据,然后选择频带内的最高幅值为心率,通过对比两个幅值的幅度计算出血氧饱和度。通过平均其他频点的差值来标定两个波长数据。

数据波形图:

血氧1.jpg

QQ截图20210729191204.jpg

部分算法代码:

C++
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\r\n",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; // fifo_word_buff[0][0] = data1; // fifo_word_buff[0][1] = data2; // test(data1,data2); 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; // for(int i = 0;i < FFT_N;i++) // { // static uint8_t str[50]; // sprintf((char *)str,"%f,%f\r\n\0",FFTBUF1[i].real,FFTBUF2[i].real); // HAL_UART_Transmit(&huart1,str,sizeof(str),20); // } // static uint8_t str[50]; // sprintf((char *)str,"H:%d,S:%f\r\n",g_blooddata.heart,g_blooddata.SpO2 ); // HAL_UART_Transmit(&huart1,str,sizeof(str),20); } else //数据发生异常 { g_blooddata.heart = 0; g_blooddata.SpO2  = 0; g_blooddata.state = BLD_ERROR; } g_fft_index = 0; } }




来自:仪器与装备 / 仪器仪表动手实践:实验报导严肃内容:专业科普
4
 
5
新版本公告
~~空空如也
虎哥
4年0个月前 IP:广东
895845

代码挺漂亮

引用
评论
1
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
zRed洲虹
4年0个月前 IP:四川
895859
引用虎哥发表于1楼的内容
代码挺漂亮

sticker 猫子虎哥,突然回复这么多贴

引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
kmakise作者
4年0个月前 IP:河北
895864
引用虎哥发表于1楼的内容
代码挺漂亮

感谢大佬夸奖

引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
niewne
3年4个月前 IP:广东
902464

现在美信的样片不好申请了

引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论

想参与大家的讨论?现在就 登录 或者 注册

所属专业
上级专业
同级专业
kmakise
进士 机友 笔友
文章
3
回复
10
学术分
0
2021/08/07注册,3年11个月前活动

bilibili:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX://XXXXXXXXXXXXXXXXXX

主体类型:个人
所属领域:无
认证方式:手机号
IP归属地:河北
插入公式
评论控制
加载中...
文号:{{pid}}
投诉或举报
加载中...
{{tip}}
请选择违规类型:
{{reason.type}}

空空如也

笔记
{{note.content}}
{{n.user.username}}
{{fromNow(n.toc)}} {{n.status === noteStatus.disabled ? "已屏蔽" : ""}} {{n.status === noteStatus.unknown ? "正在审核" : ""}} {{n.status === noteStatus.deleted ? '已删除' : ''}}
  • 编辑
  • 删除
  • {{n.status === 'disabled' ? "解除屏蔽" : "屏蔽" }}
我也是有底线的