This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] AFE4490:AFE4490SPO2EVM 固件源版本1.4

Guru**** 2533390 points
Other Parts Discussed in Thread: AFE4490SPO2EVM

请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/data-converters-group/data-converters/f/data-converters-forum/705016/afe4490-afe4490spo2evm-firmware-source-v1-4

器件型号:AFE4490

尊敬的:

在 AFE4490SPO2EVM 固件源 v1.4中有一个带通滤波器函数,遵循 processData();

首先、我们得到 redcSample =collectRed()的 redcSample、并通过 MATLAB 将波形绘制为 Bule

然后、我们得到 filtIRSample = filter (redSample)、而 polt 波形由 MATLAB 显示为红色、 该 信号用于确定 信号是否通过零点并计算心率;

在图中、我们知道蓝色波形是正确的 SpO2 波形; 红色波形不 是正确的 SpO2;

我 想  知道为什么按 filter()处理不同的波形;  我知道该滤波器仅用于将波形移动到零点。




/** *@brief 处理收集到的红色和红外值 * *@param None * *@return None */ void processData() { static unsigned long i=0,j=0; voltageCodeCounter++; //跳过2秒后开始计算数据 if (voltageCodeCounter > 1000) { int index = voltageCodeCounter - 1001; //从 AFE4400读取红色和红外值 long irSample = collectIR(); long redSample = collectRedd (); //过滤 IR 值 //filtIRSample = filter (irSample); filtIRSample = filter (redSample); //GetIrData[i++]= filtIRSample; //if (i=1000) i=0; //GetFilterIrData[i++]= filtIRSample; // printf ("\n\r\n\r\n%8ld %8ld %d\n\r\n、redSample、filtIRSample、j++); //查找当前脉冲中的最大值和最小值 IR 和红色值 IF (脉冲启动) { if (irSample > maxIRValue) maxIRValue = irSample; if (irSample < minIRValue) minIRValue = irSample; if (redSample > maxRedValue) maxRedValue = redSample; if (redSample < minRedValue) minRedValue = redSample; } PreviousValue = CurrentValue; //CurrentValue = filtIRSample; CurrentValue = filtIRSample; //如果已过滤数据中有从负到正的转换 if (PreviousValue < 0 && CurrentValue > 0) { if (translions[0]=-1) transles[0]= index;//如果这是第一个转换 否则、如果(translions[1]=-1)//如果这是第二次转换 { 转换[1]=索引; pulseStarted=1;//仅在2个确认的转换后设置脉冲启动标志 } 其他 { //保留最后两次转换的索引以估算脉冲长度 转换[0]=转换[1]; 转换[1]=索引; //Call 信号函数、用于计算心率和 SpO2 心率= calcHeartRate (转换[0]、转换[1]); PulseOx = calcPulseOx (maxIRValue、minIRValue、maxRedValue、minRedValue); //Average Heart Rate with previous history of values if (hist_count < 4) { decision_hist[hist_count]=心率; HIST_COUNT++; hist_sum = hist_sum +耳戴式; 心跳2 =心率; } 其他 { // if (耳戴>(HET_SUM/4+300) ) if (耳戴>(HET_SUM/4+3)) { //cedrate2 = decision_hist[3]+(delta_hr)*100; 心跳2 = Decision_Hist[3]+(delta_hr)*1; if (delta_hr <3) Δ_hr++; } //else if (耳戴<(HET_SUM/4-300) ) else if (耳戴<(HET_SUM/4-3)) { //cedrate2 = decision_hist[3]-(300 -(delta_hr)*100); cedrate2 = decision_hist[3]-(3-(delta_hr)*1); 如果(delta_hr >0) Δ_hr--; } 其他 { 心跳2 =心率; } hist_sum = hist_sum - decision_hist[0]+ c心跳2; decision_hist[0]= decision_hist[1]; decision_hist[1]= decision_hist[2]; decision_hist[2]= decision_hist[3]; decision_hist[3]=心跳速率2; 心跳报告= HIST_SUM/4; } //重置最大和最小默认值,以便在下一个周期进行比较 maxIRValue = 0; minIRValue = 1000000000; maxRedValue = 0; minRedValue = 1000000000; } }
/**
*@0.5至3Hz 之间的短带通滤波
器*
*@param 采样 a long
*
@return long
*/

long filter (long sample)
{
// const long b_int [3][3]={
//(long)(SOS [0][0]* scale)、(long)(SOS [0][1]* 2)、
long (sos)(long/s)[0](long])、(sos)[0)、(long](sos [0]*)、[0) (SOS [1][0]*换算)、(长整型)(SOS [1][1]*换算)、(长整型)(SOS [1][2]*换算)}、
//(长整型)(SOS [2][0]*换算)、(长整型)(SOS [1][2]*

换算)、(长整型)(SOS [2]/[3]/长
整型)(SOS [3]/[3]/[0]/(长整型)(SOS [0]/[0]/)[*[*)[SOS[*[*[0]/(SOS [0]/长整型) (SOS [0][5]* Scale)}、
//{(long)(SOS [1][3]* Scale)、(long)(SOS [1][4]* scale)、(long)(SOS [1][5]* scale)}、
//{sos [1][5]* scale)、(sos [2][3]* scale)、(long)、(0、

0[0、
0]0

、0]0、0[0、0]0、0]0、0[0、0]0、0]0、0]0、0[0、0]0、0]0、0]0、0[0、0]0、0]0、0[0、0]0、0]0、0[0、0]0、0]0、0]0、0[0、0]0、0]0、0[0、0]0、0]0、


for (k=0;k<3; k++)
{
for (j=0;j<3;j++)
{
b_int[k][j]=(long)(sos [k][j]* scale);
a_int[k][j]=(long)(sos [k][j+3]* scale);
}


// long s_[4]*
(

s)、long scale (0)(s)(s [0)、s (s [0)、s (s)、s (s [0)、s (s [0)、s (s)、s (s [0)、s (s [0、s)、s (s)、s (s (s)、s)、s (s (s)、s (s)、s (s [0、s)、s (s (s)

for (j=0;j<4;j++)
{
s_int[j]=(long)(s[j]* scale);
}

static long dly[阶段][2]={0、0}、{0、0}、{0、0}};
长结果、wn;
long mysample =采样;
长 WA1、WA2、WA3;
长 wb1、wb2、wb3;

int i;
对于(I = 0;I <级;I++)
{
//二阶 LCCDE 代码
//(eqn 8)

WA1 =((long long) mysample * s_int[i])>>(TRUNC_BITS);
wa2 =((long long) a_int[i][1]* dly[i][0])>> TRUNC_BITS;
WA3 =((long long) a_int[i][2]* dly[i][1])>> TRUNC_BITS;
WN = WA1 - WA2 - WA3;

//(eqn 9)
WB1 =((long long) b_int[i][0]* wn)>> TRUNC_BITS;
WB2 =((long long) b_int[i][1]* dly[i][0])>> TRUNC_BITS;
WB3 =((long long) b_int[i][2]* dly[i][1])>> TRUNC_BITS;

结果= wb1 + wb2 + wb3;

//更新第一阶段的过滤器缓冲区
dly[i][1]= dly[i][0];
DLY[I][0]= wn;
mysample =结果;//以防我们必须再次循环


}

返回(长)结果

;}



  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好、George、

    AFE4490SPO2EVM 固件中不提供此功能、而是在我们不再支持的 healthhub watch 固件中提供此功能。
    我建议您实施自己的滤波器算法。

    此外、如果您查看原始 PPG 数据、会发现干扰滤波器的干扰。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    Praveen、
    1.是的,它是 healthhub watch 固件;我们几乎没有看到所有的演示代码,这个演示只存在一个疑问,所以我希望你能帮助我,因为你是专家;

    如上所述,我通过 MATLAB 获得 PPG 波形,通过 printf 的 reedSample 获取 PPG 数据("\n\r\n\r\n8ld %8ld %d\n\r\n,reedSample,filtIRSample,j++);PPG 波形正常且合理。

    但 PPG 波形(redSample)通过滤波器()(long filter (long sample))时并不正常;该滤波器只是0.5至3Hz 之间的带通滤波器。 为什么 PPG 波形失真和波形消除为 y=0轴?

    我们知道该固件可通过滤波器后的波形确定心率、我们使用 prosim 8P 生命体征仿真器来测试心率是否正确。 我怀疑 PPG 波形失真为什么会是正确的?

    此外、我们还有 MATLAB 提供的相同滤波器。

    2.我们是开发 SPO2的新公司;算法很难,您能给我一些方法或资源来支持我们的算法吗? 我很感谢你