一阶差分法求取波形起始点、顶点

之前有发过一篇关于波形起始点检测的心得体会,后来有同学私信我,找源码。由于前一段时间很少上csdn,没有看到,这里表示抱歉。今天特意整理了一下之前的代码,摘选出来一段可以直接使用的代码。

`
#include <stdio.h>
#include <math.h>
void main()
{int i,N,n=0;
float x[5000],val,in[5000],out[5000],fdiff[5000],avar;

FILE *fp;
//void cubicSmooth;

if((fp=fopen("E:\\1.csv","rt"))==NULL)
{
printf("cannot open file\n");
return;
}

while (1) 
{
if(fscanf(fp,"%f,", &val) == EOF) break;
x[n]=val;
n++;
}
fclose(fp);

val=0; 
avar=0;
printf("%f\n",x[0]);
printf("%f\n",x[2729]);
for(i=0;i<n;i++){in[i]=x[i];}

for(N=0;N<=n;N++){
    if ( N < 7 )
    {
        for ( i = 0; i <= N - 1; i++ )
        {
            out[i] = in[i];
        }
    }
    else
    {
        out[0] = ( 39.0 * in[0] + 8.0 * in[1] - 4.0 * in[2] - 4.0 * in[3] +
                  1.0 * in[4] + 4.0 * in[5] - 2.0 * in[6] ) / 42.0;
        out[1] = ( 8.0 * in[0] + 19.0 * in[1] + 16.0 * in[2] + 6.0 * in[3] -
                  4.0 * in[4] - 7.0* in[5] + 4.0 * in[6] ) / 42.0;
        out[2] = ( -4.0 * in[0] + 16.0 * in [1] + 19.0 * in[2] + 12.0 * in[3] +
                  2.0 * in[4] - 4.0 * in[5] + 1.0 * in[6] ) / 42.0;
        for ( i = 3; i <= N - 4; i++ )
        {
            out[i] = ( -2.0 * (in[i - 3] + in[i + 3]) +
                       3.0 * (in[i - 2] + in[i + 2]) +
                      6.0 * (in[i - 1] + in[i + 1]) + 7.0 * in[i] ) / 21.0;
        }
        out[N - 3] = ( -4.0 * in[N - 1] + 16.0 * in [N - 2] + 19.0 * in[N - 3] +
                      12.0 * in[N - 4] + 2.0 * in[N - 5] - 4.0 * in[N - 6] + 1.0 * in[N - 7] ) / 42.0;
        out[N - 2] = ( 8.0 * in[N - 1] + 19.0 * in[N - 2] + 16.0 * in[N - 3] +
                      6.0 * in[N - 4] - 4.0 * in[N - 5] - 7.0 * in[N - 6] + 4.0 * in[N - 7] ) / 42.0;
        out[N - 1] = ( 39.0 * in[N - 1] + 8.0 * in[N - 2] - 4.0 * in[N - 3] -
                      4.0 * in[N - 4] + 1.0 * in[N - 5] + 4.0 * in[N - 6] - 2.0 * in[N - 7] ) / 42.0;
    }

}   

printf("尾点=%f\n",out[N-2]);

  fp=fopen("e:\\7点平滑.xls","w");
    for(i=0;i<n;i++)
        fprintf(fp,"%f\n",out[i]);
    fclose(fp);


    for(i=0;i<n;i++){
        avar+=out[i];}

    for(i=0;i<n-1;i++){
      fdiff[i]=out[i+1]-out[i];
      if(fdiff[i]<-50)printf("%f\n",fdiff[i]);
        if(fdiff[i]>50)printf("%f\n",fdiff[i]);
     }
    for(i=0;i<n-1;i++){
        val+=fdiff[i];}

      printf("%f\n",fdiff[0]);
      printf("差分和=%f\n",val);
      printf("幅值和=%f\n",avar);



 // FILE *fp;
    fp=fopen("e:\\一阶差分.xls","w");
    for(i=0;i<n-1;i++)
        fprintf(fp,"%f\n",fdiff[i]);
    fclose(fp);

     val=val/n-1;
     avar=avar/n;
   printf("差分均值val=%f\n",val);
   printf("幅值均值avr=%f\n",avar);

   val=fabs(val);
   printf("差分均值绝对值val=%f\n",val);


   for(i=0;i<n;i++)

   {
        if(fdiff[i-4]>0&&fdiff[i-3]>0&&fdiff[i-2]>0&&fdiff[i-1]>0&&fdiff[i]<=0&&fdiff[i+1]<0&&fdiff[i+2]<0)

      { 
          int j=0;
          int k=0;
          float ten_fdiffq=0;
          float ten_fdiffh=0;
          for(j=i-35;j<i-25;j++){ten_fdiffq+=fdiff[j];}
          for(j=i+15;j<i+25;j++){ten_fdiffh+=fdiff[j];}

          if(ten_fdiffq>1.25*val&&-ten_fdiffh>1.25*val)  //系数自选
          { 
              printf("位置%d\n峰值%f\n",i,out[i]);

              for(k=i-30;k>0;k--)
              {
                  if(fdiff[k]<=0)
                  {
                      printf("起始位置%d\n",k);
                      break;
                  }
              }
              for(k=i+30;k<n;k++)
              {
                  if(fdiff[k]>=0)
                  {
                      printf("终止位置%d\n",k);
                      break;
                  }
              }

          }
      }

    }
    getchar();`
 }
'

比较简单,希望对同学有所帮助。选择的系数是固定的,同学最好改成自适应的系数。中间使用的平滑算法,是借鉴自《几个简单的数据点平滑处理算法》。地址:http://blog.csdn.net/liyuanbhu/article/details/11119081#comments

  • 3
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: 在 C 语言中,可以通过编写程序来求取波形任意的电压幅值和相位。实现这个目标的常用方是使用离散傅里叶变换(Discrete Fourier Transform,DFT)。DFT 是一种将离散时间域信号转换成其频域表示的方,对于一个周期性的信号,可以使用 DFT 来分析其频率和相位。 为了求取波形某一的电压幅值和相位,需要将该的样本值看做一个离散时间域信号,然后对其进行 DFT 变换,得到该在频域上的幅值和相位。求取某一的幅值和相位需要根据 DFT 的公式计算,其中幅值等于频谱中对应频率的振幅,相位则为频谱中对应频率的相位角。 在编写程序时,需要先将样本数据处理成离散时间域信号,然后使用 DFT 算对其进行变换。一般情况下,会使用 FFT(快速傅里叶变换)算来实现 DFT,因为 FFT 具有计算速度快、效率高的优。对于周期性的波形,可以使用周期曲线拟合方来获取样本数据,从而获得准确的波形数据。 总之,使用离散傅里叶变换,可以方便地求取波形任意的电压幅值和相位。需要注意的是,为了获得准确的结果,需要处理好数据和算的选择。 ### 回答2: 要求取波形任意的电压幅值和相位,需要先了解相关的基本知识。电压幅值是指电压的最大值与最小值之间的差值,可以通过读取波形在该的电压数值来计算。相位是指波形在某一与参考之间的时间差,也可以通过读取波形的周期和该位置来计算。 在c语言中,要求取波形任意的电压幅值和相位,可以使用相关的计算公式来实现。例如,要计算电压幅值,可以通过读取波形在该的电压数值并出最大值和最小值,两者之差即为电压幅值。要计算相位,则需要先确定波形的周期,例如利用FFT算求取波形频谱信息,然后计算波形在该位置,最后将位置除以周期即可得到相位。 在程序实现时,需要合理选择数据结构和算,以提高计算的效率和准确度。同时,需要注意浮数计算的精度问题,以避免误差的积累影响计算结果。在实际应用中,还需要结合实际情况进行调试和优化,以确保计算结果的可靠性和准确性。 ### 回答3: 在C语言中,求取波形任意的电压幅值和相位可以通过使用三角函数来完成。首先需要定义信号的频率和幅值,以及当前时间。然后,可以使用sine函数(正弦函数)计算该时间的电压值。以下是具体步骤: 1. 定义信号频率,幅值和时间。可以使用float类型或double类型来定义变量: float frequency = 50.0; // 信号频率为50Hz float amplitude = 10.0; // 信号幅值为10V float time = 0.01; // 当前时间为0.01秒 2. 计算电压值。可以使用sinf函数(计算正弦函数)来计算电压值,公式为: float voltage = amplitude * sinf(2 * M_PI * frequency * time); 其中,“2 * M_PI”是一个常数,代表2π(其中π约等于3.14159)。 3. 计算相位。可以使用atan2f函数(计算反正切函数)来计算相位,公式为: float phase = atan2f(voltage, amplitude); 其中,voltage是通过上面的公式计算出的电压值,amplitude是信号的幅值。 通过以上步骤,就可以求取任意时间的电压幅值和相位了。可以根据实际情况,将以上代码封装成函数,方便在程序中调用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值