Capstone project files
Dependencies: mbed-dsp mbed capstone_display_2
Diff: main.cpp
- Revision:
- 4:9ee3ae61db7f
- Parent:
- 3:30dcfcf9412c
- Child:
- 5:bc45ed158abf
diff -r 30dcfcf9412c -r 9ee3ae61db7f main.cpp --- a/main.cpp Thu Apr 03 20:30:18 2014 +0000 +++ b/main.cpp Tue Apr 15 20:27:43 2014 +0000 @@ -3,24 +3,38 @@ #include "arm_math.h" #include "display.h" #define f_sampling 2000 //the sampling frequency -#define NumTaps 27 //the number of FIR coefficients -#define BlockSize 2048 //the size of the buffer +#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); -Serial pc(USBTX, USBRX); //USB serial for PC, to be removed later +//-------------------- signal-related stuff AnalogIn input(p15); //pin 15 for analog reading -AnalogOut waveOut(p18); 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 filter coefficients for a band pass filter, consider changing to doubles if not precise enough +//-------------------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, @@ -29,7 +43,26 @@ -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] = { @@ -52,12 +85,14 @@ 0.00456436168827984, 0.00130297171184699 }; //*/ -float32_t pState[NumTaps + BlockSize - 1]; + -int index_g; //tracks the index for the waveform array +/* + This is a helper function for precision timing of Tickers +*/ void readPoint() { waitForNext = false; @@ -81,7 +116,13 @@ sampler.detach(); } -void outputWaveform() +/** + 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; @@ -89,13 +130,20 @@ for (int i = 0; i < BlockSize; i++) { while (waitForNext); //wait until the ticker calls for the next data point - waveOut.write(postFilterData[i]); + waveOut.write(array[i]); waitForNext = true; } outputter.detach(); } -int setPot(int wiperNo, float kOhms) +/* + 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; @@ -106,42 +154,68 @@ 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 digital setting + command += dataBits; //add in the data bits (digital settings) spi.write(command); return command; } -float32_t rms() +/* + 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 += postFilterData[i]*postFilterData[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() { - //to initialize the filter stuff use init functions (see line 89 in the arm_fir_f32.c file for documentation) - //the initialization function is in a seperate file called arm_fir_init_f32.c + //arm_iir_lattice_instance_f32* filter1 = new arm_iir_lattice_instance_f32(); + arm_fir_instance_f32* filter = new arm_fir_instance_f32(); + float* history; - /* -* <code>pState</code> points to a state array of size <code>numTaps + blockSize - 1</code>. -* Samples in the state buffer are stored in the following order. -* \par -* <pre> -* {x[n-numTaps+1], x[n-numTaps], x[n-numTaps-1], x[n-numTaps-2]....x[0], x[1], ..., x[blockSize-1]} -* </pre> -* \par + int state = 0; //which state of the state machine to be in, change to enum if desired - */ - arm_fir_instance_f32* filter = new arm_fir_instance_f32(); - int state = 0; uint16_t numTaps = NumTaps; uint32_t blockSize = BlockSize; char buffer[32]; //for debugging scanf things - char* outputString; + char* outputString; //string to be printed to the LCD display (or other output) float32_t estimate = 0; while(1) { @@ -149,11 +223,13 @@ switch(state) { case 0: //initialization - - //pc.printf("pre-filter init\n\r"); + 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; @@ -165,46 +241,35 @@ break; case 2: //printout to pc connection or other output debugging - //pc.printf("into print\n\r"); - /* - for (int i = 0; i < BlockSize; i++) - { - pc.printf("Waveform contents:%f\n\r", waveform[i]); - } - */ - for (int i = 0; i < 10; i++) outputWaveform(); + + 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); - state = 2; + //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 maybe depreciated - /* - * - * + case 6: //calculate the average voltage - 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; - */ - estimate = rms(); - pc.printf("RMS = %f", estimate); - state = 5; + estimate = rms(postFilterData); + pc.printf("post filter RMS = %f\n\n\r", estimate); + state = 1; + adjustGains(estimate); break; - case 7: //estimate amplitude + case 7: //estimate amplitude using simple peak detection (consider discarding) pc.printf("Into estimation\n\r"); int peaks = 0; float sum = 0.0; @@ -229,11 +294,51 @@ pc.printf("kOhms?\n\r"); pc.scanf("%s", buffer); float value = atof(buffer); - pc.printf("Command: %x Scanned:%f\n\r", setPot(0, value), value); + 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]); + } + */