Capstone project files

Dependencies:   mbed-dsp mbed capstone_display_2

main.cpp

Committer:
ryanyuyu
Date:
2014-04-15
Revision:
4:9ee3ae61db7f
Parent:
3:30dcfcf9412c
Child:
5:bc45ed158abf

File content as of revision 4:9ee3ae61db7f:

#include "mbed.h"
#include "FIR_f32.h"
#include "arm_math.h"
#include "display.h"
#define f_sampling 2000 //the sampling frequency
#define NumTaps 27      //the number of filter coefficients
#define BlockSize 512  //the size of the buffer

Serial pc(USBTX, USBRX); //USB serial for PC, to be removed later
AnalogOut waveOut(p18); //for debugging

//--------------------  SPI communication
SPI spi(p5, p6, p7);
DigitalOut cs(p8);

//--------------------  LCD display
ST7735_LCD disp( p14, p13, p12, p10, p11); //for digital display
display lcd(&disp);

//--------------------  signal-related stuff
AnalogIn input(p15); //pin 15 for analog reading
float32_t waveform[BlockSize]; //array of input data
float32_t postFilterData[BlockSize]; //array of filtered data
bool fullRead; //whether the MBED has finish
bool waitForNext;
int index_g; //tracks the index for the waveform array

//-------------------the tuning constants for distance calculation
float minThreshold;
float maxThreshold;
float gain1;
float gain2;
float c1;
float c2;
float c3;

//------------------------the filter coefficients for FIR filter
float32_t pCoeffs[NumTaps] = 
                {    0.012000000000000,   0.012462263166161,  -0.019562318415964,  -0.026175892863747,
                     0.031654803781611,   0.050648026372209,  -0.032547136829180,  -0.070997780956819,
                     0.032992306874347,   0.094643188024724,  -0.020568171368385,  -0.106071176200193,
                     0.009515198320277,   0.114090808482376,   0.009515198320275,  -0.106071176200193,
                    -0.020568171368382,   0.094643188024728,   0.032992306874351,  -0.070997780956815,
                    -0.032547136829177,   0.050648026372211,   0.031654803781612,  -0.026175892863746,
                    -0.019562318415964,   0.012462263166161,   0.012000000000000                        };
float32_t pState[NumTaps + BlockSize - 1];
//                    */


//-----------------------IIR stuff (if needed)
/*
float32_t pkCoeffs[NumTaps] = 
    {
        1,-2.496708288,3.17779085,-2.022333713,0.6561,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
    };
    
float32_t pvCoeffs[NumTaps] =
    {
        0.0000556000,0.0002167120,0.0004326320,0.0005056930,0.0002111890,-0.0004911030,-0.0013071920,-0.0017060250,-0.0012444070,0.0000684000,0.0016603140,0.0026622100,0.0024306750,0.0009787140,-0.0009787140,-0.0024306750,-0.0026622100,-0.0016603140,-0.0000684000,0.0012444070,0.0017060250,0.0013071920,0.0004911030,-0.0002111890,-0.0005056930,-0.0004326320,-0.0002167120,-0.0000556000
    };
float32_t pState[NumTaps + BlockSize];
//*/


//--------------------------------if needed, the 4kHz FIR filter
/*
float32_t pCoeffs[NumTaps] = 
{
    -0.00130297171184699,    -0.00456436168827987,    -0.00757978930408609,    -0.00696944302000657,
        -0.00100059082174453,    0.00812867271498616, 0.0148953048520266,  0.0137935053264369,
          0.00350484996910501, -0.0112195199182290, -0.0216305356563913, -0.0202538386423356,
           -0.00609419278464673,    0.0137348990478646,  0.0275645559768492,  0.0261107576153156,
             0.00866220574766616, -0.0156131009924596, -0.0324957126350438, -0.0311514181527343,
              -0.0110879396617141, 0.0168179120126559,  0.0362758644669149,  0.0352058948414930,
               0.0132978095684398,  -0.0172706692984796, -0.0386711719606551, -0.0379507530937637,
                -0.0149419841919419, 0.0172996706397712,  0.0400000000000000,  0.0397279151377323,
                  0.0164353142069562,  -0.0164055618588934, -0.0396949785867063, -0.0399629114640568,
                   -0.0172605211576678, 0.0149790280104299,  0.0379815311949588,  0.0386933807609119,
                     0.0172844840085185,  -0.0132904115318555, -0.0352024033389307, -0.0362742608690452,
                      -0.0168170401765007, 0.0110885383139611,  0.0311518509994083,  0.0324959946809230,
                        0.0156132578212073,  -0.00866213238945794,    -0.0261107291487171, -0.0275645472357883,
                         -0.0137348973043660, 0.00609419268963993, 0.0202538383407381,  0.0216305354798053,
                           0.0112195198475825,  -0.00350484999121515,    -0.0137935053321021, -0.0148953048532365,
                            -0.00812867271519995,    0.00100059082171422, 0.00696944302000319, 0.00757978930408577,
                             0.00456436168827984, 0.00130297171184699
    };
    //*/


                    


/*
    This is a helper function for precision timing of Tickers
*/
void readPoint()
{
    waitForNext = false;    
}


/**
* This function reads one full set of analog data into the uC 
*/
void readSamples()
{
    Ticker sampler; //allows for precision data reading
    waitForNext = true;
    sampler.attach_us(&readPoint, (int) (1000000/f_sampling) ); //read in data according the sampling freq
    for (int i = 0; i < BlockSize; i++)
    {
        while (waitForNext); //wait until the ticker calls for the next sample
        waveform[i] = input.read();
        waitForNext = true;
    }
    sampler.detach();
}

/**
    This function spits out the waveform on the analogOut pin (p18)
    This function will be unused in the final version, but is still usefull for debugging.
    @param array (float32_t *): (array of data) pointer to the data to output over the analogOut pin
    @return none
*/
void outputWaveform(float32_t* array)
{
    Ticker outputter;
    waitForNext = true;
    outputter.attach_us(&readPoint, (int) (1000000/f_sampling) ); //output data according the sampling freq
    for (int i = 0; i < BlockSize; i++)
    {
        while (waitForNext); //wait until the ticker calls for the next data point
        waveOut.write(array[i]);
        waitForNext = true;
    }
    outputter.detach();
}
    
/*
    This method writes to the digital potentiometer (MCP4251)
    @param wiperNo (int): this is the wiper number to write to (either 0 or 1)
    @param kOhms (float): this is the value to set the resistance (in kilo Ohms) between the wiper and terminal B 
        note 
   @return: the integer command actually sent (for debugging)
*/
int setPot(int wiperNo, float kOhms) 
{
    //257 steps (8 bits + 1), see section 7.0 for SPI instructions
    float Rmax = 100000;
    spi.frequency(2000000);
    spi.format(16, 0); //16 bits, mode b00
    float ratio = kOhms * 1000.0 / Rmax;
    if (ratio > 1) ratio = 1;
    if (ratio < 0) ratio = 0;
    int dataBits = (int) (ratio * 0x100);
    int command = wiperNo << 12; //setting the Address and Command bits
    command += dataBits; //add in the data bits (digital settings)
    spi.write(command);    
    return command;
}

/*
    This function calculates the RMS (root mean squared) of an array of float data.
    @param array (float32_t *): the array to calculate RMS from
    @return float_32: the resulting RMS value of the given array
*/
float32_t rms(float32_t* array)
{
    float32_t rms = 0;
    for(int i = 0; i < BlockSize; i++)
    {
        rms += array[i]*array[i];
    }
    //pc.printf("Sum of squares %f\n\r", rms);
    return sqrt(rms/BlockSize);
}

void calibrate()
{
    gain1 = 1.0;
    gain2 = 25.0;
    minThreshold = .0275;
    maxThreshold = .1850;
}

int adjustGains(float estimate)
{
    if (estimate < minThreshold)
    {
        if (gain2 < 100) //post amp not yet maxed
        {
            
        }
        else;
    }
    else if (estimate > maxThreshold)
    {
        
    }
    
}

float estimateDistance(float estimate)
{
    return estimate;
}

int main() {
    //arm_iir_lattice_instance_f32* filter1 = new arm_iir_lattice_instance_f32();
    arm_fir_instance_f32* filter = new arm_fir_instance_f32();
    float* history;    
    
    int state = 0; //which state of the state machine to be in, change to enum if desired
    
    uint16_t numTaps = NumTaps;
    uint32_t blockSize = BlockSize;
    char buffer[32]; //for debugging scanf things
    char* outputString; //string to be printed to the LCD display (or other output)
    float32_t estimate = 0;
    while(1) 
    {
        //pc.printf("While loop\n\r");
        switch(state)
        {
        case 0: //initialization
            calibrate();
            arm_fir_init_f32(filter, numTaps, pCoeffs, pState, blockSize);
            //arm_iir_lattice_init_f32(filter1, numTaps, pkCoeffs, pvCoeffs, pState, blockSize);
            //pc.printf("Pre-attachment");
            spi.frequency(1000000);
            setPot(1, gain1);
            setPot(0, gain2);
            state = 1;
            pc.printf("Done with init.\n\r");
            break;
            
        case 1: //read data, take samples
            pc.printf("Reading data.\n\r");
            readSamples();
            state = 3;
            break;
            
        case 2: //printout to pc connection or other output debugging
            
            for (int i = 0; i < 10; i++) outputWaveform(postFilterData);
            wait_ms(500);
            state = 1;
            break;
        case 3: //filter?
            pc.printf("RMS of waveform = %f\n\r", rms(waveform));
            pc.printf("Filtering?\n\r");
            arm_fir_f32(filter, waveform, postFilterData, blockSize);
            //arm_iir_lattice_f32(filter1, waveform, postFilterData, blockSize);
            state = 6;
            break;
        case 4: //FFT?
            break;
        case 5: //output, write to display and PWM tone
            /*
            sprintf(outputString, "RMS = %f", estimate);
            lcd.print(outputString);
            state = 1;
            //*/
            break;
        case 6: //calculate the average voltage 
            
            estimate = rms(postFilterData);
            pc.printf("post filter RMS = %f\n\n\r", estimate);
            state = 1;
            adjustGains(estimate);
            break;
        case 7: //estimate amplitude using simple peak detection (consider discarding)
            pc.printf("Into estimation\n\r");
            int peaks = 0;
            float sum = 0.0;
            float prev, current, next;
            for (int i = 0+1; i < BlockSize-1; i++)
            {
                prev = postFilterData[i-1];
                current = postFilterData[i];
                next = postFilterData[i+1];
                if (prev < current && next < current) //local max
                {
                    sum += current;
                    peaks++;
                }
            }
            float average = sum/peaks;
            pc.printf("Average of peaks (scalar) = %f\n\r", average);
            state = 1;
            break;
            
        case 8: //digital pot interfacing and calibration
            pc.printf("kOhms?\n\r");
            pc.scanf("%s", buffer);
            float value = atof(buffer);
            pc.printf("Command: %x Scanned:%f\n\r", setPot(1, value), value);
            wait_ms(250);
            state = 8;
            break;
            
        case 9:
            
        case 10: //purely for testing that the digital potentiometer is working.
            pc.printf("Start of loop.\n\r");
            setPot(1,0);
            wait_ms(1000);
            setPot(1,20);
            wait_ms(1000);
            setPot(1,40);
            wait_ms(1000);
            setPot(1,50);
            wait_ms(1000);
            setPot(1, 80);
            wait_ms(1000);
            setPot(1, 100);
            wait_ms(1000);
            state = 10;
            break;
        default:
            break;
        }
    } //end of (infinite) while loop
}


//-----------------------------Unused code, but potentially useful

            /*
            double sum = 0;
            for (int i = 0; i < BlockSize; i++) sum += postFilterData[i];
            double average = sum/BlockSize*3.3;  //*3.3 V_ref (array stored as fractions of V_ref)
            pc.printf("Average = %f\n\r", average);
            wait_ms(500);
            state = 2;
            */
            
            //pc.printf("into print\n\r");
            /*
            for (int i = 0; i < BlockSize; i++)
            {
                pc.printf("Waveform contents:%f\n\r", waveform[i]);
            }
            */