(Perfect operation) QT-based filter design (including signal synthesis, FFT, FIR filtering, IIR filtering)

QT version 5.9.6, see the information for detailed codes and complete project files, download and run, suitable for QT novices and learning C language algorithm implementation of IIR, FIR filtering, and FFT, and definitely benefit a lot.
(1) On the host computer, use QT software to write and complete the synthesis of two or three frequency signals, and display the synthesized time domain waveform on the graphical interface; (2) Use FFT to calculate the frequency
of the synthesized signal, and draw a spectrum diagram on the interface ;
(3) Use Matlab's Filter Designer to design FIR and IIR filters, respectively complete the removal of a frequency component, and display the filtered signal time domain waveform on the interface.

1. Synthesis of three frequency signals, sinusoidal signal a, sinusoidal signal b, sinusoidal signal c, and display the time domain waveform of the synthesized signal on the UI interface: by inputting the frequency of the three signals on the interface, and then read it in the
program Three frequencies, converted to angles, generate three sinusoidal signals, draw three waveforms. The following program realizes the function of reading the frequency from the input box, generating three sine signals, and drawing the signals synthesized by three sine waves on the graph.

//三种频率的正弦波信号合成  
void Widget::on_com_clicked()  
{
    
      
    QLayoutItem *child;  
    while ((child = ui->layout->takeAt(0)) != 0)  
    {
    
      
           if(child->widget())  
           {
    
      
               child->widget()->setParent(NULL);  
           }  
            delete child;  
    }  
    Widget::Chart_Init();  
    series->clear();  
    chart->removeSeries(series);  
series->setName("合成");  

//读取文本框中的频率
    QString fa = ui->fa->toPlainText();  
    double fa1=fa.toDouble();  
    QString fb = ui->fb->toPlainText();  
    double fb1=fb.toDouble();  
    QString fc = ui->fc->toPlainText();  
    double fc1=fc.toDouble();  
  
    for(double i=0.0;i<10.0;i+=0.0001){
    
      
        double angle1 = i * fa1;  
        double angle2 = i * fb1;  
        double angle3 = i * fc1;  
        series->append(i,(sin(2*3.14159265*angle1)+sin(2*3.14159265*angle2)+sin(2*3.14159265*angle3)));  
    }  
    chart->addSeries(series);//把折线添加到图表  
    series->attachAxis(axisX); 
    series->attachAxis(axisY);  
    chart->axisY()->setRange(-3, 3);  
}  

insert image description here
2. Use FFT to calculate the frequency of the synthesized signal, and draw a spectrogram on the interface.
1) The following paragraph is the main program, which calls the FFT.h header file, and calls the FFT.c function in the header file to calculate the FFT, and then calculates the resulting frame frequency curve:

//对合成信号做FFT,绘制幅频曲线  
void Widget::on_FFT_clicked()  
{
    
      
    QLayoutItem *child;  
     while ((child = ui->layout->takeAt(0)) != 0)  
     {
    
      
            if(child->widget())  
            {
    
      
                child->widget()->setParent(NULL);  
            }  
            delete child;  
     }  
   Widget::Chart_Init();  
    series->clear();  
    series->setName("IIR滤波");  
    //获得文本输入框中a波形的频率  
    QString fa = ui->fa->toPlainText();  
    double freq_a=fa.toDouble();  
    double freq_a_radians=freq_a*2*3.1415926;  
    //获得文本输入框中b波形的频率  
    QString fb = ui->fb->toPlainText();  
    double freq_b=fb.toDouble();  
    double freq_b_radians=freq_b*2*3.1415926;  
    QString fc = ui->fc->toPlainText();  
    double freq_c=fc.toDouble();  
    double freq_c_radians=freq_c*2*3.1415926;  
    double max_freq=freq_a;  
    if(max_freq<=freq_b)  
        max_freq=freq_b;  
    else if(max_freq<=freq_c)  
        max_freq=freq_c;  
   //获得FFT数据,用于显示  
    double real_freq[1024];  
    double amp[1024];  
    get_FFT_data(real_freq,amp,freq_a_radians,freq_b_radians,freq_c_radians);  
    //显示FFT变换后计算得到的频谱图  
    for(int i=0;i<max_freq+50;i++)  
    {
    
      
        series->append(real_freq[i],amp[i]);  
    }  
    chart->addSeries(series);//把折线添加到图表  
    series->setName("FFT");  
    chart->createDefaultAxes();  
    chart->axisY()->setRange(-1, 1);  
}  

insert image description here
insert image description here
3. FIR filtering
uses Matlab's Filter Designer to design FIR filters. The passband frequency is 100Hz, the cutoff frequency is 200Hz, the passband ripple is 0.5dB, the stopband ripple is 80dB, and the signal sampling rate is 800Sa/s. According to Nyquist Sampling law, so theoretically speaking, the signal that can be processed is within 400Hz, and the order of the designed FIR filter is 21.

insert image description here

FIR滤波程序:
//FIR滤波  
void Widget::on_FIRfilter_clicked()  
{
    
      
    QLayoutItem *child;  
    while ((child = ui->layout->takeAt(0)) != 0)  
    {
    
      
           if(child->widget())  
           {
    
      
               child->widget()->setParent(NULL);  
           }  
           delete child;  
    }  
    Widget::Chart_Init();  
    series->clear();  
    series->setName("FIR滤波");   //添加波形名字  
    chart->removeSeries(series);  
    double data_in[10000];  
    double data_out[10000];  
    QString fa = ui->fa->toPlainText();  
    double fa1=fa.toDouble();  
    QString fb = ui->fb->toPlainText();  
    double fb1=fb.toDouble();  
    QString fc = ui->fc->toPlainText();  
    double fc1=fc.toDouble();  
    for(double i=0.0;i<10.0;i+=0.001){
    
      
        double angle1 = 2*3.14159*i * fa1;  
        double angle2 = 2*3.14159*i * fb1;  
        double angle3 = 2*3.14159*i * fc1;  
        int j = 1000 * i;  
        data_in[j]=sin(angle1)+sin(angle2)+sin(angle3);  
    }  
    int i=0,j=0,k=0;  
    double state[FIR_FILTER_LENGTH];  
    double temp=0;    
double FIR_COFFES[FIR_FILTER_LENGTH]= {
    
      
      0.000828859699301925110029309884396298003, 0.005491897013585840710281349430488262442,0.014807416606805706704719227673194836825, 0.021389125806650765432292971013339411002,
       0.010554414190420358110600318468641489744, -0.022661508756789315588431321657481021248,  
      -0.053911115172153287189438231052918126807, -0.0357090761579505269751599882965820143,  
       0.061219089267199357229376488476191298105, 0.205966149469584192122084687071037478745,  
       0.31493515071552402595500552706653252244, 0.31493515071552402595500552706653252244 ,  
       0.205966149469584192122084687071037478745, 0.061219089267199357229376488476191298105,  
      -0.0357090761579505269751599882965820143, -0.053911115172153287189438231052918126807,  
       -0.022661508756789315588431321657481021248, 0.010554414190420358110600318468641489744,  
        0.021389125806650765432292971013339411002, 0.014807416606805706704719227673194836825,  
        0.005491897013585840710281349430488262442, 0.000828859699301925110029309884396298003};  
  
    for (k = 0; k < 10000; k++){
    
      
        state[0] = data_in[k];  
        for (i = 0, temp = 0; i < FIR_FILTER_LENGTH-1; i++)  
            temp += FIR_COFFES[i] * state[i];  
        data_out[k] = temp;  
        for (j = FIR_FILTER_LENGTH - 2; j > -1 ; j--)  
        state[j+1] = state[j];  
    }  
    for(double i=0.0;i<10.0;i+=0.001){
    
      
        series->append(i,data_out[int (1000 * i)]);  
    }  
    chart->addSeries(series);//把折线添加到图表  
    series->attachAxis(axisX);  
    series->attachAxis(axisY);  
    chart->axisY()->setRange(-1.5, 1.5);  
}  

Set the frequency of three groups of three signals on the interface to verify the effect of FIR filtering:
insert image description here
insert image description here
Group 2: Use signal waveforms of three frequencies of 50Hz, 220Hz and 280Hz for filtering verification:
insert image description here
Group 3: Use three frequencies of 20Hz, 220Hz and 340Hz The signal waveform is filtered and verified:
insert image description here
4. IIR filtering
uses the Filter Designer toolbox of Matlab to design the IIR filter. In order to compare the filtering effect with the FIR filter, most parameters are consistent with the order of the FIR filter, so the passband is also set The frequency is 100Hz, the cutoff frequency is 200Hz, the passband ripple is 0.5dB, the stopband ripple is 80dB, and the signal sampling rate is 800Sa/s. According to the Nyquist sampling law, the signal that can be processed is theoretically within 400Hz. The design The resulting filter order is 12.

insert image description here
The following is the code part of the IIR filter, which calls the two functions of IIR parameter setting and IIR filter. The type 2 IIR filter function is not listed, and you can refer to the program for details.

//点击IIR滤波按钮,进行IIR滤波  
void Widget::on_IIRfilter_clicked()  
{
    
      
    QLayoutItem *child;  
     while ((child = ui->layout->takeAt(0)) != 0)  
     {
    
      
            if(child->widget())  
            {
    
      
                child->widget()->setParent(NULL);  
            }  
            delete child;  
     }  
    Widget::Chart_Init();  
    series->clear();  
    series->setName("IIR滤波");   //添加波形名字    
    int N=13;  
double b[N]={
    
    
3.09525176187779e-06,  3.71430211425335e-05,   0.000204286616283934, 
0.000680955387613114,   0.00153214962212951,    0.00245143939540721,    
0.00286001262797508,    0.00245143939540721,    0.00153214962212951,
0.000680955387613114,   0.000204286616283934,   3.71430211425335e-05,   3.09525176187779e-06};  
double a[N]={
    
    
1, -5.34962036107987,  14.1411241339418,   -23.9072313155838,  
28.4874436778036,   -25.0265817923911,  16.5375193873507,   
8.25031849575782,  3.07476132941233,   -0.832796574455573,
0.155288255056261,  -0.0178681514268133,    0.000958058346940756};  
    IIR_II filter;  
    filter.setPara(b, N-1, a, N-1);//设置IIR滤波器参数,b是分子,a是分母,分母,  
    //N-1是滤波器阶数,由于从0开始,所以是N-1,而不是N  
  
    double data_in[10000];  
    double data_out[10000];  
    //读取三个输入框中的频率数字  
    QString fa = ui->fa->toPlainText();  
    double fa1=fa.toDouble();  
    QString fb = ui->fb->toPlainText();  
    double fb1=fb.toDouble();  
    QString fc = ui->fc->toPlainText();  
    double fc1=fc.toDouble();  
  
    //将频率转换为角度  
    for(double i=0.0;i<10.0;i+=0.001){
    
      
        double angle1 = 2*3.14159*i * fa1;  
        double angle2 = 2*3.14159*i * fb1;  
        double angle3 = 2*3.14159*i * fc1;  
        int j = 1000 * i;  
        data_in[j]=sin(angle1)+sin(angle2)+sin(angle3);  
        }  
  
    //调用IIR滤波器进行滤波  
    //data_in是待滤波信号,data_out是滤波后的信号,10000是信号长度  
    filter.filter(data_in,data_out,10000);  
  
    //在图上画滤波后的波形  
     for(double i=0.0;i<10.0;i+=0.001)  
        {
    
      
            series->append(i,data_out[int (1000 * i)]);  
        }  
        chart->addSeries(series);//把折线添加到图表   
        series->attachAxis(axisX);  
        series->attachAxis(axisY);  
        chart->axisY()->setRange(-1.5, 1.5);  
}  

In order to verify the filtering performance of the designed IIR filter, we used three groups of signals, which are still consistent with the FIR filtering part.
insert image description here
Group 1: Use signal waveforms of three frequencies of 100Hz, 250Hz and 380Hz for filtering verification:
insert image description here
Group 2: Use signal waveforms of three frequencies of 50Hz, 220Hz and 280Hz for filtering verification: Group
insert image description here
3: Use three frequencies of 20Hz, 220Hz and 340Hz Filtering verification of the signal waveform:
insert image description here
Comparison of IIR and FIR filtering:
Since I deliberately kept the filtering indicators of the filter consistent during the stage of designing the filter indicators in this experiment, the order of the designed FIR filter is 21, and the IIR filter The filter order is 12. It can be seen that when the computing resources are very precious, the IIR filter is very useful, that is, the filtering is realized with the smallest filter filter order. In addition, the number of filter coefficients of the IIR and FIR filters can be compared. It is found that the number of digits of IIR is much less than that of FIR, almost half, which is a good thing for processors such as FPGA, because the number of floating-point numbers of processors is fixed, which is easy to cause limited word length effect, the length of the filter coefficients has to be truncated, leading to error accumulation. As far as the filtering effect is concerned, both filters can effectively filter, and the filtering effect is not much different, but it should be noted that the design of the IIR filter must maintain its stability, and the pole of the denominator is within the unit circle.

Guess you like

Origin blog.csdn.net/qq_45362665/article/details/128237476