1610|7

244

帖子

0

TA的资源

纯净的硅(初级)

楼主
 

【ACM32G103RCT6】10-ADC测试——用心率算法算心率 [复制链接]

 
本帖最后由 qiao--- 于 2024-1-28 01:24 编辑

前言:

本次测评的是基于ADC用心率算法测出人体心率

参考文章:使用 PulseSensor 脉搏传感器测量心率之一:平台搭建_pulsesenneor-CSDN博客

我使用的心率传感器

 

 

1.测试ADC能正常检测到模拟量

1.1在msp.c文件中初始化引脚

这里我使用的的是ADC1,引脚用的是PA0

void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{
    uint32_t i;
    GPIO_InitTypeDef GPIO_Handle; 
    uint32_t ADC_Pin_Map[][3] =
    {
        { ADC_CHANNEL_0_EN, (uint32_t)GPIOA, GPIO_PIN_0 }, 
//        { ADC_CHANNEL_1_EN, (uint32_t)GPIOA, GPIO_PIN_1 },
//        { ADC_CHANNEL_2_EN, (uint32_t)GPIOA, GPIO_PIN_2 },
//        { ADC_CHANNEL_3_EN, (uint32_t)GPIOA, GPIO_PIN_3 },
//        { ADC_CHANNEL_4_EN, (uint32_t)GPIOA, GPIO_PIN_4 },
//        { ADC_CHANNEL_5_EN, (uint32_t)GPIOA, GPIO_PIN_5 },
//        { ADC_CHANNEL_6_EN, (uint32_t)GPIOA, GPIO_PIN_6 },
//        { ADC_CHANNEL_7_EN, (uint32_t)GPIOA, GPIO_PIN_7 },
//        { ADC_CHANNEL_8_EN, (uint32_t)GPIOB, GPIO_PIN_0 },
//        { ADC_CHANNEL_9_EN, (uint32_t)GPIOB, GPIO_PIN_1 },
//        { ADC_CHANNEL_10_EN, (uint32_t)GPIOC, GPIO_PIN_0 },
//        { ADC_CHANNEL_11_EN, (uint32_t)GPIOC, GPIO_PIN_1 },
//        { ADC_CHANNEL_12_EN, (uint32_t)GPIOC, GPIO_PIN_2 },
//        { ADC_CHANNEL_13_EN, (uint32_t)GPIOC, GPIO_PIN_3 },
//        { ADC_CHANNEL_14_EN, (uint32_t)GPIOC, GPIO_PIN_4 },
//        { ADC_CHANNEL_15_EN, (uint32_t)GPIOC, GPIO_PIN_5 },
        { 0xffffffff, 0 }, //结束标志
    };    

    __HAL_RCC_GPIOA_CLK_ENABLE();
//    __HAL_RCC_GPIOB_CLK_ENABLE();
//    __HAL_RCC_GPIOC_CLK_ENABLE();

    //Set gpio to analog.
    for(i = 0; ADC_Pin_Map[i][0] != 0xffffffff; i++)
    {
        if(hadc->Init.ChannelEn & ADC_Pin_Map[i][0])
        {
            GPIO_Handle.Pin            = ADC_Pin_Map[i][2];
            GPIO_Handle.Mode           = GPIO_MODE_ANALOG;
            GPIO_Handle.Pull           = GPIO_NOPULL;
            HAL_GPIO_Init((GPIO_TypeDef *)ADC_Pin_Map[i][1], &GPIO_Handle);   
        }
    }

    /* Enable ADC Clock */
    __HAL_RCC_ADC12_CLK_ENABLE();
    /* Clear Pending Interrupt */
    NVIC_ClearPendingIRQ(ADC12_IRQn);	
    /* Enable External Interrupt */
    NVIC_EnableIRQ(ADC12_IRQn);
  
}

1.2硬件使能ADC

这里我新建了一个pulse.c文件,下面为ADC1的硬件初始化代码

ADC_HandleTypeDef ADC_Handle;
/******************************************************************************
* @brief  : ADC Polling Mode Initialization.
* @param : none
* @return: none
******************************************************************************/ 
void ADC_Init_Polling_Nchannels(void)
{
    ADC_ChannelConfTypeDef ADC_ChannelConf;

    ADC_Handle.Init.ClockPrescaler = ADC_CLOCK_DIV16;       //ADC_CLK分频选择
    ADC_Handle.Init.Resolution     = ADC_RESOLUTION_12B;    //分辨率
    ADC_Handle.Init.DataAlign      = ADC_DATAALIGN_RIGHT;   //数据对齐
    ADC_Handle.Init.ConConvMode    = DISABLE;               //连续转换模式

    ADC_Handle.Init.DiscontinuousConvMode = DISABLE;        //间断模式
    ADC_Handle.Init.NbrOfDiscConversion   =1;               //间断模式通道计数
    ADC_Handle.Init.ExternalTrigConv = ADC_SOFTWARE_START;  //触发模式:外部触发或软件触发
    ADC_Handle.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;//外部触发边沿选择
    ADC_Handle.Init.DMAMode = ADC_DMAMODE_DISABLE;          //DMA选择
    ADC_Handle.Init.OverMode = ADC_OVERMODE_DISABLE;        //溢出时是否保留上次采样数据

    ADC_Handle.Init.OverSampMode = ADC_OVERSAMPMODE_DISABLE;//过采样使能
    ADC_Handle.Init.Oversampling.Ratio =ADC_OVERSAMPLING_RATIO_2;//过采样率
    ADC_Handle.Init.Oversampling.RightBitShift =ADC_RIGHTBITSHIFT_2;//过采样移位系数
    ADC_Handle.Init.Oversampling.TriggeredMode =0;          //过采样触发模式    
    ADC_Handle.Init.AnalogWDGEn = ADC_ANALOGWDGEN_DISABLE;  //模拟看门狗
    ADC_Handle.Init.ChannelEn = ADC_CHANNEL_0_EN ;

    ADC_Handle.Instance = ADC1;  

    HAL_ADC_Init(&ADC_Handle);


    /* The total adc regular channels number */
    ADC_Handle.ChannelNum = 1;

    /* Add adc channels */
    ADC_ChannelConf.Channel = ADC_CHANNEL_0;
    ADC_ChannelConf.Sq = ADC_SEQUENCE_SQ1;  //转换顺序
    ADC_ChannelConf.Smp = ADC_SMP_CLOCK_320;//采样时间
    ADC_ChannelConf.SingleDiff =  ADC_SINGLE_ENDED;  // ADC_DIFFERENTIAL_ENDED ;    //单端/差分模式
    //offset config
    ADC_ChannelConf.OffsetNumber = ADC_OFFSET_NONE;   //modeString[0].number;  //ADC_OFFSET_NONE;  //偏移通道选择
    ADC_ChannelConf.Offset =  0; //偏移量
    ADC_ChannelConf.OffsetSign = 0; //偏移计算方式
    ADC_ChannelConf.OffsetSaturation = 0;//偏移结果格式选择
    HAL_ADC_ConfigChannel(&ADC_Handle,&ADC_ChannelConf);  
}

1.3.测试ADC功能

这里创建了一个测试函数,用于输出检测到我的心率传感器的模拟量

 

1.4测试结果

在主函数中调用,然后给开发板接上传感器并且上电,接线图

   

我们打开串口助手查看输出是否合理,如下图

 

输出正确,这样我们可以接着写心率的算法了。

 

2.心率算法

心率图如下

 

算法根据

 

算法大家可以去看看我前面提到的参考文章,总的来说就是算出两次脉搏跳动的时间,然后用60秒去除以这个时间来估算心率。

但是其实并没有那么简单,在这当中有两个关键点(也是难点):

  1. 怎么判断波峰---->阈值的选取。
  2. 怎么选取我们需要的特征点---->也就是怎么选取我们需要记录的时间点,进而计算这两个时间的差值,就是两次脉搏跳动的时间。

 

 

综上得出算法整体的框架如下:

  1. 缓存一个波形周期内的多次采样值,求出最大最小值,计算出振幅中间值作为信号判定阈值
  2. 通过把当前采样值和上一采样值与阈值作比较,寻找到「信号上升到振幅中间位置」的特征点,记录当前时间
  3. 寻找下一个特征点并记录时间,算出两个点的时间差值,即相邻两次脉搏的时间间隔 IBI
  4. 由 IBI 计算心率值 BPM

说干结干下面就是根据上方框架写出的算法

  

 

3.测试

接上心率模块后看看心率是否在正常范围内

IMG_8325

 

 

总结:这款ACM32单片机ADC的测量值挺准确,能够正常测出心率值。

 

05ADC+pulse.7z (1.3 MB, 下载次数: 5)

 

最新回复

推荐一下这个串口工具,图形化的画波形还挺方便,用过vofa之类的,自己也用pyqt写过   详情 回复 发表于 2024-2-18 09:37
点赞 关注
 
 

回复
举报

6809

帖子

0

TA的资源

五彩晶圆(高级)

沙发
 

测量值准确说明ADC测试很成功,赞

 
 
 

回复

6483

帖子

9

TA的资源

版主

板凳
 

这个算法不错,已收藏,看着挺稳定的  

个人签名

在爱好的道路上不断前进,在生活的迷雾中播撒光引

 
 
 

回复

539

帖子

1

TA的资源

纯净的硅(中级)

4
 

不错呀,挺好的测评


点评

感谢支持  详情 回复 发表于 2024-1-29 18:30
 
 
 

回复

244

帖子

0

TA的资源

纯净的硅(初级)

5
 
Honghuzaitian 发表于 2024-1-29 02:17 不错呀,挺好的测评

感谢支持

 
 
 

回复

6992

帖子

11

TA的资源

版主

6
 
是不是有点激动,心跳有点快呀。我记得有个血氧传感器的找不到了,要不用血氧也可以算出来。

点评

哈哈,难怪我说有点高呢  详情 回复 发表于 2024-2-13 09:08
 
 
 

回复

244

帖子

0

TA的资源

纯净的硅(初级)

7
 
lugl4313820 发表于 2024-2-12 21:12 是不是有点激动,心跳有点快呀。我记得有个血氧传感器的找不到了,要不用血氧也可以算出来。

哈哈,难怪我说有点高呢

 
 
 

回复

365

帖子

0

TA的资源

版主

8
 

推荐一下这个串口工具,图形化的画波形还挺方便,用过vofa之类的,自己也用pyqt写过

 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/8 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表