Cutoff frequency variable LPF, HPF, BPF, and BRF by FIR 160th-order filter.

Dependencies:   UIT_ACM1602NI UITDSP_ADDA mbed UIT_AQM1602

main.cpp

Committer:
MikamiUitOpen
Date:
2015-07-25
Revision:
3:24b6aa1a19ba
Parent:
1:58271fae2e01

File content as of revision 3:24b6aa1a19ba:

//------------------------------------------------------------------------------
// Cutoff frequency variable LPF, HPF, BPF and BRF by FIR 160th-order filter
//      A0: Signal to be filtered
//      A2: Value which controls cutoff frequency
//
//      1: LPF, 3: HPF, 5: BPF, 7: BRF, even: through
// 2015/07/25, Copyright (c) 2015 MIKAMI, Naoki
//------------------------------------------------------------------------------

#include "ADC_Interrupt.hpp"    // for ADC using interrupt
#include "DAC_MCP4921.hpp"      // for DAC MCP4921, MCP4922
using namespace Mikami;

#include "WindowingDesign.hpp"  // for design of FIR filter

// ACM1602Ni を使う場合は次の define 文をコメントにすること
#define AQM1602

#ifdef AQM1602
#include "AQM1602.hpp"
Aqm1602 Lcd_;
#else
#include "ACM1602NI.hpp"
Acm1602Ni Lcd_;
#endif

const int FS_ = 16000;          // Sampling frequency: 16 kHz
ADC_Intr myAdc_(A0, FS_, A1, A2);
DAC_MCP4921 myDac_;

const int ORDER_ = 160;
float hm_[ORDER_/2+1];
float xn_[ORDER_+1];

BusIn sws_(D2, D3, D4, D5);
int sw_;
WindowingDesign design_(ORDER_, FS_);

uint16_t a2_ = 0;   // Inputted data from A2 pin

// Interrupt service routine for ADC
void AdcIsr()
{   
    xn_[0] = myAdc_.Read();     // Read from A0

    myAdc_.Select3rdChannel();  // Select A2   
    myAdc_.SoftStart();         // ADC start for A2 input

    //-----------------------------------------
    // Execute FIR filter
        float yn = hm_[ORDER_/2]*xn_[ORDER_/2];
        for (int k=0; k<ORDER_/2; k++)
            yn = yn + hm_[k]*(xn_[k] + xn_[ORDER_-k]);

        for (int k=ORDER_; k>0; k--)
            xn_[k] = xn_[k-1];  // move input signals
    //-----------------------------------------

    if ((sw_ & 0x01) == 0)
        myDac_.Write(xn_[0]);    // Using no filter
    else
        myDac_.Write(yn);        // Using filter

    // Read value which controls cutoff frequency
    a2_ = myAdc_.ReadWait_u16();

    myAdc_.Select1stChannel();      // Select A0
    myAdc_.ClearPending_EnableIRQ();// Clear pending interrupt
                                    // and enable ADC_IRQn
}

void printfLcdDesign(WindowingDesign::Type pb, char str[], int f1, int f2 = 0);

int main()
{
    myDac_.ScfClockTim3(670000);    // cutoff frequency: 6.7 kHz
    sws_.mode(PullDown);

    // Clear buffer in FIR filter
    for (int n=0; n<=ORDER_; n++)
        xn_[n] = 0;
    myAdc_.SetIntrVec(AdcIsr);  // Assign ISR for ADC interrupt

    float fc1 = 0;
    while (true)
    {
        sw_ = sws_.read();
        if ((sw_ & 0x01) == 0)
        {
            printf("Through\r\n");
            Lcd_.ClearLine(1);
            Lcd_.WriteStringXY("Through         ", 0, 0);
            wait(0.2f);
            Lcd_.ClearLine(0);           
            fc1 = 0;
        }
        else
        {
            // fc: cutoff or center frequency, 200 -- 2000 Hz
            float fc = 1800.0f*(a2_/4095.6f) + 200.0f;

            if (fabs(fc - fc1) > 10.0f)
            {
                fc1 = fc;

                switch (sw_)
                {
                    case 1: printfLcdDesign(design_.LPF, "LPF", fc+0.5f);
                            break;
                    case 3: printfLcdDesign(design_.HPF, "HPF", fc+0.5f);
                            break;
                    case 5: printfLcdDesign(design_.BPF, "BPF", fc-100, fc+100);
                            break;
                    case 7: printfLcdDesign(design_.BRF, "BRF", fc-150, fc+150);
                            break;
                }
            }
        }
        wait(0.1f);
    }
}

void printfLcdDesign(WindowingDesign::Type pb, char str[], int f1, int f2)
{
    printf(((string)str+"\r\n").c_str());
    Lcd_.WriteStringXY(str, 0, 0);
    char strFc[17];
    if (f2 == 0)
    {
        printf("fc = %4d Hz\r\n", f1);
        sprintf(strFc, "fc: %4d Hz", f1);
    }
    else
    {
        printf("fc = %4d, %4d Hz\r\n", f1, f2);
        sprintf(strFc, "fc: %4d,%4d Hz", f1, f2);
    }
    Lcd_.WriteStringXY(strFc, 0, 1);

    design_.Design(ORDER_, pb, f1, f2, hm_);
}