硬汉嵌入式论坛

 找回密码
 立即注册
查看: 24415|回复: 66
收起左侧

[DSP] FFT加窗插值修正后,求解多次谐波频率,幅值,相位的精度杠杠的(暂时不开源)

  [复制链接]

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106422
QQ
发表于 2020-5-17 14:49:44 | 显示全部楼层 |阅读模式
此贴算法暂时没有开源打算(2022-07-18添加)

以工频信号为例,如果波形是固定的50Hz,我们可以直接设置采样率是这个周期的整数倍,并进行同步采样,求出来的数据精度就比较高,但实际频率是50Hz左右,从会导致FFT求解出来的频率,幅值,相位都有偏差。

所以就有了各种加窗处理(其实就是加权),FFT处理完毕后再做插值修正(目的是解决栅栏效应),准确率高了很多。



设置信号由10次谐波组成,基波49.9Hz。
谐波幅值 =[11,2,1,0.5,0.3,0.1,0.05,0.05,0.05,0.05];
谐波初始相位=[0.9,0.8,0.7,0.6,0.5,0.3,0.2,0.2,0.2,0.2];


信号先做汉宁窗,FFT后再做插值,10次谐波的频率,赋值和相位如下:
   1     49.901010   11.000616  0.899702
   2     99.768131   1.999112    0.808405
   3     149.673843  0.999671   0.706992
   4     199.562452  0.499779  0.610078
   5     249.454945  0.299804  0.512082
   6     299.301802  0.099861  0.327334
   7     349.223025  0.049967  0.221232
   8     399.165802  0.050010  0.209194
   9     449.065492  0.050015  0.209054
  10     498.939165  0.049954  0.215565




评分

参与人数 1金币 +20 收起 理由
missfox + 20 赞一个!

查看全部评分

回复

使用道具 举报

0

主题

77

回帖

77

积分

初级会员

积分
77
发表于 2020-5-17 23:17:08 | 显示全部楼层
只知道加窗,插值是用来干什么的?是用来提高精度么?
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106422
QQ
 楼主| 发表于 2020-5-18 01:35:26 | 显示全部楼层
艾那的小强 发表于 2020-5-17 23:17
只知道加窗,插值是用来干什么的?是用来提高精度么?

加窗是解决频谱泄露问题,插值是解决栅栏效应。
回复

使用道具 举报

23

主题

1403

回帖

1472

积分

至尊会员

积分
1472
发表于 2020-5-18 09:30:35 | 显示全部楼层
继续坐等白嫖

一次嫖一次爽,一直嫖一直爽
代码不规范,亲人两行泪!
回复

使用道具 举报

0

主题

77

回帖

77

积分

初级会员

积分
77
发表于 2020-5-20 09:56:27 | 显示全部楼层
eric2013 发表于 2020-5-18 01:35
加窗是解决频谱泄露问题,插值是解决栅栏效应。

硬汉哥。能请教一下,怎么对FFT结果插值吗?
回复

使用道具 举报

10

主题

139

回帖

169

积分

初级会员

积分
169
发表于 2020-5-20 11:16:12 | 显示全部楼层
对音频信号进行FFT时存在以下问题,请问如何解决。
音频采样频率为48000Hz,FFT为1024线,48000/1024=46.875Hz。
不是整数,如果是50次就完美了,因为要求1秒出50个频谱。
一种方法是采用升采样的方法,比如实际获得960点数据即开始FFT计算。
但是FFT算法必须是2的N次方,而960不是,所以计算之前要将数据扩展为1024个。
请问如何对数据进行升采样操作?数据扩充后,FFT计算得到的频率、幅值、能量等是否要修正?如何修正?
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106422
QQ
 楼主| 发表于 2020-5-20 11:33:33 | 显示全部楼层
lvehe 发表于 2020-5-20 11:16
对音频信号进行FFT时存在以下问题,请问如何解决。
音频采样频率为48000Hz,FFT为1024线,48000/1024=46.8 ...

不用修正,补零后前后效果。

FFT补零计算的前后效果
http://www.armbbs.cn/forum.php?m ... 7804&fromuid=58
(出处: 硬汉嵌入式论坛)
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106422
QQ
 楼主| 发表于 2020-5-20 11:34:07 | 显示全部楼层
艾那的小强 发表于 2020-5-20 09:56
硬汉哥。能请教一下,怎么对FFT结果插值吗?

下次DSP教程更新。
回复

使用道具 举报

0

主题

77

回帖

77

积分

初级会员

积分
77
发表于 2020-5-20 12:32:50 | 显示全部楼层
eric2013 发表于 2020-5-20 11:34
下次DSP教程更新。

哦。谢谢硬汉哥。
回复

使用道具 举报

0

主题

77

回帖

77

积分

初级会员

积分
77
发表于 2020-5-21 18:07:16 | 显示全部楼层
eric2013 发表于 2020-5-20 11:34
下次DSP教程更新。

请问一下,硬汉哥。你楼主位的例子后面会给出来吗?想学习一下。
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106422
QQ
 楼主| 发表于 2020-5-22 07:58:06 | 显示全部楼层
艾那的小强 发表于 2020-5-21 18:07
请问一下,硬汉哥。你楼主位的例子后面会给出来吗?想学习一下。

会。下期DSP先发布matlab操作,后面再发布板子操作。
回复

使用道具 举报

0

主题

77

回帖

77

积分

初级会员

积分
77
发表于 2020-5-22 10:15:25 | 显示全部楼层
eric2013 发表于 2020-5-22 07:58
会。下期DSP先发布matlab操作,后面再发布板子操作。

期待。谢谢硬汉哥。
回复

使用道具 举报

12

主题

134

回帖

170

积分

初级会员

积分
170
发表于 2020-5-23 11:44:39 | 显示全部楼层
硬汉哥,我语音信号FFT->填充滤波->IFFT后有杂音,间断的哒声,周期跟每次处理的长度一致,是不是也可以这样处理?
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106422
QQ
 楼主| 发表于 2020-5-23 11:48:10 | 显示全部楼层
xiaosir 发表于 2020-5-23 11:44
硬汉哥,我语音信号FFT->填充滤波->IFFT后有杂音,间断的哒声,周期跟每次处理的长度一致,是不是也可以这样处 ...

不行,这个是为了更好的求解谐波的幅值和相位。
回复

使用道具 举报

0

主题

77

回帖

77

积分

初级会员

积分
77
发表于 2020-5-25 14:26:51 | 显示全部楼层
硬汉哥,我现在用了你说的,加了汉宁窗,也做了全相位处理,现在算手动生成的数据(比如我在程序里面生成一组正弦波数据),相位和频率均能计算正确。

但我用ADC采集信号发生器发出的正弦波,却总是测不准。是ADC采集这里有什么特殊要求吗?

我用的是你例子里面的定时器触发ADC采集,DMA中断的方式。在DMA完成中断中关掉定时器。然后计算FFT(在主循环中计算FFT)。计算完了再打开定时器。
能给点指点吗?谢谢了。
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106422
QQ
 楼主| 发表于 2020-5-25 15:44:38 | 显示全部楼层
艾那的小强 发表于 2020-5-25 14:26
硬汉哥,我现在用了你说的,加了汉宁窗,也做了全相位处理,现在算手动生成的数据(比如我在程序里面生成一 ...

等我发布了,参考即可。
回复

使用道具 举报

0

主题

77

回帖

77

积分

初级会员

积分
77
发表于 2020-5-25 17:31:15 | 显示全部楼层
eric2013 发表于 2020-5-25 15:44
等我发布了,参考即可。

硬汉哥,我想调皮一下。
能不能开通个付费尝鲜服务。
我被这个问题卡了两周了。实在是着急了。
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106422
QQ
 楼主| 发表于 2020-5-25 17:32:12 | 显示全部楼层
艾那的小强 发表于 2020-5-25 17:31
硬汉哥,我想调皮一下。
能不能开通个付费尝鲜服务。
我被这个问题卡了两周了。实在是着急了。

没有这种服务,只能等。
回复

使用道具 举报

0

主题

77

回帖

77

积分

初级会员

积分
77
发表于 2020-5-25 18:05:16 | 显示全部楼层
eric2013 发表于 2020-5-25 17:32
没有这种服务,只能等。

嗯嗯。好的。那我再查查。期待。。
回复

使用道具 举报

0

主题

77

回帖

77

积分

初级会员

积分
77
发表于 2020-5-27 15:30:23
顶一下,硬汉哥别忙忘了这事。

2

主题

6

回帖

12

积分

新手上路

积分
12
发表于 2020-7-1 22:18:03 | 显示全部楼层
版主,请教下,如果采样频率不是(幅值最大频率)的整数倍,而且不是50.05倍这种很小的,比如说50.5倍,通过加窗和插值可以解决吗?
我现在加了ntuuall窗,再用的时域平移相位差校正法,效果还是不理想,具体表现为(采样频率不是整数倍时),计算相位与实际相位差90度,
(采样频率是整数倍时),计算相位与实际相位无差别,我现在的做法是:计算出频率后(频率计算的比较准),根据当前频率实时调整采样频率,这样才能得到比较好的效果
PS:信号频率是变化的。
请教下有没有更好的办法

回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106422
QQ
 楼主| 发表于 2020-7-2 09:28:40 | 显示全部楼层
haci 发表于 2020-7-1 22:18
版主,请教下,如果采样频率不是(幅值最大频率)的整数倍,而且不是50.05倍这种很小的,比如说50.5倍,通 ...

此贴就是解决这个问题而生,待我后面腾出精力了,分享相关教程和Demo到第2版DSP教程里面。
回复

使用道具 举报

1

主题

17

回帖

20

积分

新手上路

积分
20
发表于 2020-7-2 10:54:57 | 显示全部楼层
xiaosir 发表于 2020-5-23 11:44
硬汉哥,我语音信号FFT->填充滤波->IFFT后有杂音,间断的哒声,周期跟每次处理的长度一致,是不是也可以这样处 ...

FFT和IFFT要进行重叠处理
回复

使用道具 举报

44

主题

560

回帖

697

积分

金牌会员

积分
697
发表于 2020-8-14 21:28:11 | 显示全部楼层
佬大这个demo例程能发布一下,参考参考
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106422
QQ
 楼主| 发表于 2020-8-15 01:09:55 | 显示全部楼层
ou513 发表于 2020-8-14 21:28
佬大这个demo例程能发布一下,参考参考

下次DSP教程更新时发布matlab版,后面发布单片机版。
回复

使用道具 举报

0

主题

10

回帖

10

积分

新手上路

积分
10
发表于 2020-8-24 20:59:17 | 显示全部楼层
非常期待硬汉MATLAB版例程!!!!!!!!!!!!!
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106422
QQ
 楼主| 发表于 2020-8-25 08:56:16 | 显示全部楼层
zhm19840622 发表于 2020-8-24 20:59
非常期待硬汉MATLAB版例程!!!!!!!!!!!!!

好,正确早点发布。
回复

使用道具 举报

0

主题

10

回帖

10

积分

新手上路

积分
10
发表于 2020-8-31 19:12:34 | 显示全部楼层
eric2013 发表于 2020-8-25 08:56
好,正确早点发布。

牛!!!!!!!!!
回复

使用道具 举报

2

主题

8

回帖

14

积分

新手上路

积分
14
发表于 2020-9-3 22:04:03 | 显示全部楼层
eric2013 发表于 2020-8-25 08:56
好,正确早点发布。

跪求硬汉哥早点发布,等着呢
回复

使用道具 举报

2

主题

8

回帖

14

积分

新手上路

积分
14
发表于 2020-9-4 14:10:57 | 显示全部楼层
本帖最后由 713042507 于 2020-9-4 16:00 编辑

硬汉哥,小白请教一下,
我现在需要做两个正弦波的相位差,
x=SIN(2*PI* 64),初始相位为0;
算4096个点的FFT,分辨率为1HZ,然后求出幅值,
通过比较法;找到幅值最大的那个点对应的频率。
然后在将频率带入到FFT的输出数组算出来相位为-87度
微信图片_20200904155937.png


代码如下:
      for (i=0;i<= FFT_LENGTH ; i++)      
      {
          fft_inputbuf [2*i  ] = data;
          fft_inputbuf [2*i+1] = 0;
      }
      arm_cfft_radix4_f32(&scfft,fft_inputbuf); //FFT计算(基4)

      arm_cmplx_mag_f32(fft_inputbuf,fft_outputbuf_amp,FFT_LENGTH); //算出幅值

      dc_vaule = fft_outputbuf_amp[0] /4096;//算出直流分量
   
      for (i=0;i<= FFT_LENGTH/2 ; i++)
      {
        fft_outputbuf_amp = fft_outputbuf_amp[i+1] ;  //去掉直流分量,去前2047个点
      }

      arm_max_f32(fft_outputbuf_amp,2047,&max_seq_value,&mean_value_seq); //在2047个点中找到幅值最大的那个点
   
      phase = atan2(fft_inputbuf[(mean_value_seq+1)*2+1], fft_inputbuf[(mean_value_seq+1)*2]);  //算出幅值最大的点的相位,




回复

使用道具 举报

2

主题

8

回帖

14

积分

新手上路

积分
14
发表于 2020-9-9 20:54:22 | 显示全部楼层
艾那的小强 发表于 2020-5-25 14:26
硬汉哥,我现在用了你说的,加了汉宁窗,也做了全相位处理,现在算手动生成的数据(比如我在程序里面生成一 ...

小哥,能借鉴一下你的FFT求解相位的代码吗?我现在频率求得很准,但相位算不对
回复

使用道具 举报

4

主题

74

回帖

86

积分

初级会员

积分
86
发表于 2020-9-15 13:12:00 | 显示全部楼层
谢谢!!!!
回复

使用道具 举报

0

主题

9

回帖

9

积分

新手上路

积分
9
发表于 2020-9-23 20:27:33 | 显示全部楼层
期待 顶一下
回复

使用道具 举报

1

主题

4

回帖

7

积分

新手上路

积分
7
发表于 2020-11-6 12:10:55 | 显示全部楼层
哥 MATLAB程序有了吗?参考一下
回复

使用道具 举报

1

主题

4

回帖

7

积分

新手上路

积分
7
发表于 2020-11-6 12:13:51 | 显示全部楼层
713042507 发表于 2020-9-9 20:54
小哥,能借鉴一下你的FFT求解相位的代码吗?我现在频率求得很准,但相位算不对

我也想要哥
回复

使用道具 举报

1

主题

4

回帖

7

积分

新手上路

积分
7
发表于 2020-11-6 12:27:45 | 显示全部楼层
为什么我加窗之后 栅栏效应更明显了? 代码如下:
%% 窗函数测试
clc
close all

Ts=12800;
Fs=1/Ts;
t=1/12800:1/12800:0.02;
yt = sin(2*pi*50*t)+ 0.1*sin(3*2*pi*50*t)+ 0.5*sin(5*2*pi*50*t);%原始电网信号
fft_out1 = abs(fft(yt));
figure
subplot(211)
plot( yt)
title('原始信号')
subplot(212)
stem(fft_out1)
title('原始信号频谱')

win = hanning(length(t));%调用汉宁窗。
yt1 = yt.*win';
fft_out2=abs(fft(2*yt1));
figure
subplot(211)
plot(yt1)
title('加窗信号')
subplot(212)
stem(fft_out2)
title('加窗信号频谱');

Pinpu.png
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106422
QQ
 楼主| 发表于 2020-11-6 13:24:50 | 显示全部楼层
嵌入式小白 发表于 2020-11-6 12:27
为什么我加窗之后 栅栏效应更明显了? 代码如下:
%% 窗函数测试
clc

过段时间时间开源发布后,参考即可。
回复

使用道具 举报

1

主题

4

回帖

7

积分

新手上路

积分
7
发表于 2020-11-6 16:41:11 | 显示全部楼层
eric2013 发表于 2020-11-6 13:24
过段时间时间开源发布后,参考即可。

哥 啥时候出啊 好期待啊
回复

使用道具 举报

0

主题

3

回帖

3

积分

新手上路

积分
3
发表于 2020-11-12 19:21:29 | 显示全部楼层
期待期待!
回复

使用道具 举报

0

主题

3

回帖

3

积分

新手上路

积分
3
发表于 2020-12-2 21:02:00 | 显示全部楼层
硬汉哥,啥时候发布matlab版呀,最近一直在学,看不明白
回复

使用道具 举报

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

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-4-20 06:25 , Processed in 0.373670 second(s), 32 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表