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]); } */