为啥 DTMF 双音拨号识别,用DFT比FFT好?
本来用 FFT 来解析的,能读,但有错误,准确度不高网上说 DTMF 要用 DFT,有大佬了解吗
FFT 不是比 DFT 高效吗? https://wenku.baidu.com/view/5f2cfd7eae02de80d4d8d15abe23482fb4da02c5.html?_wkts_=1717657420110&needWelcomeRecommand=1 本帖最后由 luosifu 于 2024-6-6 15:21 编辑
自己删除了我回复的内容,懒得去翻书了,没有依据的回复容易误导各位:lol luosifu 发表于 2024-6-6 15:14
我想瞎说的楼上坛友已经找到了,因为双音频的那几个频率是已知且固定的,DFT可以只针对这几个频率去计算。 ...
能用,就绘制图形能用,单看数值结果上看不出规律
都忽高忽低的= =# 也不知道啥问题 本帖最后由 MF35_ 于 2024-6-6 16:15 编辑
2楼已经给了答案了,除了频谱仪外,很多涉及到频域分析的仪器,典型的比如阻抗(复数)测试仪,都用DFT而不是FFT,就是因为频率已知的前提下,DFT的计算是非常简单的,只需要一个正弦表和一个余弦表而已
固定单频点的DFT算法还有有其他的名字,数字相干检波、数字鉴相、数字锁相检波等等,其实都一回事,本质上就是用余弦表和正弦表做两次加权积分,或者说加权平均抽取,都是一个概念
DFT没写出来,FFT倒是又可以了
看你用什麼機器 如果8位機用FFT會受不了,因為無法實時解碼 xiaolaba 发表于 2024-6-8 20:41
看你用什麼機器 如果8位機用FFT會受不了,因為無法實時解碼
air001 Cortex-M0 JuncoJet 发表于 2024-6-8 21:11
air001 Cortex-M0
要用1bit adc(比較器)的話可以用dft試試看,就一sin表 然後移相90度參個cos表
如果實時要求就看看Goertzel algorithm ,比dft更有效,8位機都行那arm更是輕鬆 xiaolaba 发表于 2024-6-8 21:29
要用1bit adc(比較器)的話可以用dft試試看,就一sin表 然後移相90度參個cos表
如果實時要求就看看Goer ...
用的 Arduino Goertzel 库,
参考 fsk 的例子做双音识别,失败
#define A1 PA6
// Define the ADC midpoint (512 is the default)
#define ADC_MIDPOINT 512
// Define the sample rate (8800 S/s is the default for 16 MHz Boards)
#define SAMPLE_RATE 8800
// include the Goertzel library
#include <Goertzel.h>
// Array buffer for ADC samples
int Samples;
// Variable for resulting magnitude
float Mag;
// Instantiate class for 440 Hz tone detection
Goertzel f1(697);
Goertzel f2(770);
Goertzel f3(852);
Goertzel f4(941);
Goertzel f5(1209);
Goertzel f6(1336);
Goertzel f7(1477);
void setup() {
Serial.begin(115200);
}
void loop() {
int DEPTH = sizeof(Samples) / sizeof(Samples);
// Get 100 ADC samples from A1 and store them in the buffer
for (int n = 0; n < DEPTH; n++) {
Samples = analogRead(A1);
}
// Determine the amount of Samples
char str[]="Num:",num=0;
float r1,r2,r3,r4,r5,r6,r7;
r1 = f1.Mag(Samples, DEPTH);
r2 = f2.Mag(Samples, DEPTH);
r3 = f3.Mag(Samples, DEPTH);
r4 = f4.Mag(Samples, DEPTH);
r5 = f5.Mag(Samples, DEPTH);
r6 = f6.Mag(Samples, DEPTH);
r7 = f7.Mag(Samples, DEPTH);
if(r5>r1>0){
num='1';
}else if(r6>r1>0){
num='2';
}else if(r7>r1>0){
num='3';
}else if(r5>r2>0){
num='4';
}else if(r6>r2>0){
num='5';
}else if(r7>r2>0){
num='6';
}else if(r5>r3>0){
num='7';
}else if(r6>r3>0){
num='8';
}else if(r7>r3>0){
num='9';
}else if(r5>r4>0){
num='*';
}else if(r6>r4>0){
num='0';
}else if(r7>r4>0){
num='#';
}
str=num;
// print result to serial
Serial.println(str);
} 在采样频率和被测频率不是整数倍的时候,FFT有个频谱泄露问题很麻烦,有改善的办法但无法完全避免 用MT8870芯片硬件译码很简单 快乐毛毛虫 发表于 2024-6-9 13:31
用MT8870芯片硬件译码很简单
自己主要是为了学习原理,乐趣
软解也能通用的解决很多类似的问题 20多年前,我用MT8870做电话遥控装置,用MT8880做自动拨打电话卡号和密码的自动拨号器,打IP电话省事多了。 JuncoJet 发表于 2024-6-9 00:47
用的 Arduino Goertzel 库,
参考 fsk 的例子做双音识别,失败
叉回去參考看看
https://github.com/xiaolaba/ATmega-DTMF-Decoder
DFT也是可以的, 第一代PIC用過, 不過源碼找不到了.
页:
[1]