Capstone project files
Dependencies: mbed-dsp mbed capstone_display_2
main.cpp@3:30dcfcf9412c, 2014-04-03 (annotated)
- Committer:
- ryanyuyu
- Date:
- Thu Apr 03 20:30:18 2014 +0000
- Revision:
- 3:30dcfcf9412c
- Parent:
- 2:8ae58834937f
- Child:
- 4:9ee3ae61db7f
Update
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
ryanyuyu | 0:3aae5d23d0db | 1 | #include "mbed.h" |
ryanyuyu | 2:8ae58834937f | 2 | #include "FIR_f32.h" |
ryanyuyu | 0:3aae5d23d0db | 3 | #include "arm_math.h" |
ryanyuyu | 3:30dcfcf9412c | 4 | #include "display.h" |
ryanyuyu | 2:8ae58834937f | 5 | #define f_sampling 2000 //the sampling frequency |
ryanyuyu | 2:8ae58834937f | 6 | #define NumTaps 27 //the number of FIR coefficients |
ryanyuyu | 3:30dcfcf9412c | 7 | #define BlockSize 2048 //the size of the buffer |
ryanyuyu | 3:30dcfcf9412c | 8 | |
ryanyuyu | 3:30dcfcf9412c | 9 | SPI spi(p5, p6, p7); |
ryanyuyu | 3:30dcfcf9412c | 10 | DigitalOut cs(p8); |
ryanyuyu | 3:30dcfcf9412c | 11 | ST7735_LCD disp( p14, p13, p12, p10, p11); //for digital display |
ryanyuyu | 3:30dcfcf9412c | 12 | display lcd(&disp); |
ryanyuyu | 2:8ae58834937f | 13 | |
ryanyuyu | 2:8ae58834937f | 14 | Serial pc(USBTX, USBRX); //USB serial for PC, to be removed later |
ryanyuyu | 2:8ae58834937f | 15 | AnalogIn input(p15); //pin 15 for analog reading |
ryanyuyu | 3:30dcfcf9412c | 16 | AnalogOut waveOut(p18); |
ryanyuyu | 2:8ae58834937f | 17 | float32_t waveform[BlockSize]; //array of input data |
ryanyuyu | 2:8ae58834937f | 18 | float32_t postFilterData[BlockSize]; //array of filtered data |
ryanyuyu | 2:8ae58834937f | 19 | bool fullRead; //whether the MBED has finish |
ryanyuyu | 2:8ae58834937f | 20 | bool waitForNext; |
ryanyuyu | 2:8ae58834937f | 21 | |
ryanyuyu | 2:8ae58834937f | 22 | //the filter coefficients for a band pass filter, consider changing to doubles if not precise enough |
ryanyuyu | 3:30dcfcf9412c | 23 | |
ryanyuyu | 2:8ae58834937f | 24 | float32_t pCoeffs[NumTaps] = |
ryanyuyu | 2:8ae58834937f | 25 | { 0.012000000000000, 0.012462263166161, -0.019562318415964, -0.026175892863747, |
ryanyuyu | 2:8ae58834937f | 26 | 0.031654803781611, 0.050648026372209, -0.032547136829180, -0.070997780956819, |
ryanyuyu | 2:8ae58834937f | 27 | 0.032992306874347, 0.094643188024724, -0.020568171368385, -0.106071176200193, |
ryanyuyu | 2:8ae58834937f | 28 | 0.009515198320277, 0.114090808482376, 0.009515198320275, -0.106071176200193, |
ryanyuyu | 2:8ae58834937f | 29 | -0.020568171368382, 0.094643188024728, 0.032992306874351, -0.070997780956815, |
ryanyuyu | 2:8ae58834937f | 30 | -0.032547136829177, 0.050648026372211, 0.031654803781612, -0.026175892863746, |
ryanyuyu | 2:8ae58834937f | 31 | -0.019562318415964, 0.012462263166161, 0.012000000000000 }; |
ryanyuyu | 3:30dcfcf9412c | 32 | // */ |
ryanyuyu | 3:30dcfcf9412c | 33 | /* |
ryanyuyu | 3:30dcfcf9412c | 34 | float32_t pCoeffs[NumTaps] = |
ryanyuyu | 3:30dcfcf9412c | 35 | { |
ryanyuyu | 3:30dcfcf9412c | 36 | -0.00130297171184699, -0.00456436168827987, -0.00757978930408609, -0.00696944302000657, |
ryanyuyu | 3:30dcfcf9412c | 37 | -0.00100059082174453, 0.00812867271498616, 0.0148953048520266, 0.0137935053264369, |
ryanyuyu | 3:30dcfcf9412c | 38 | 0.00350484996910501, -0.0112195199182290, -0.0216305356563913, -0.0202538386423356, |
ryanyuyu | 3:30dcfcf9412c | 39 | -0.00609419278464673, 0.0137348990478646, 0.0275645559768492, 0.0261107576153156, |
ryanyuyu | 3:30dcfcf9412c | 40 | 0.00866220574766616, -0.0156131009924596, -0.0324957126350438, -0.0311514181527343, |
ryanyuyu | 3:30dcfcf9412c | 41 | -0.0110879396617141, 0.0168179120126559, 0.0362758644669149, 0.0352058948414930, |
ryanyuyu | 3:30dcfcf9412c | 42 | 0.0132978095684398, -0.0172706692984796, -0.0386711719606551, -0.0379507530937637, |
ryanyuyu | 3:30dcfcf9412c | 43 | -0.0149419841919419, 0.0172996706397712, 0.0400000000000000, 0.0397279151377323, |
ryanyuyu | 3:30dcfcf9412c | 44 | 0.0164353142069562, -0.0164055618588934, -0.0396949785867063, -0.0399629114640568, |
ryanyuyu | 3:30dcfcf9412c | 45 | -0.0172605211576678, 0.0149790280104299, 0.0379815311949588, 0.0386933807609119, |
ryanyuyu | 3:30dcfcf9412c | 46 | 0.0172844840085185, -0.0132904115318555, -0.0352024033389307, -0.0362742608690452, |
ryanyuyu | 3:30dcfcf9412c | 47 | -0.0168170401765007, 0.0110885383139611, 0.0311518509994083, 0.0324959946809230, |
ryanyuyu | 3:30dcfcf9412c | 48 | 0.0156132578212073, -0.00866213238945794, -0.0261107291487171, -0.0275645472357883, |
ryanyuyu | 3:30dcfcf9412c | 49 | -0.0137348973043660, 0.00609419268963993, 0.0202538383407381, 0.0216305354798053, |
ryanyuyu | 3:30dcfcf9412c | 50 | 0.0112195198475825, -0.00350484999121515, -0.0137935053321021, -0.0148953048532365, |
ryanyuyu | 3:30dcfcf9412c | 51 | -0.00812867271519995, 0.00100059082171422, 0.00696944302000319, 0.00757978930408577, |
ryanyuyu | 3:30dcfcf9412c | 52 | 0.00456436168827984, 0.00130297171184699 |
ryanyuyu | 3:30dcfcf9412c | 53 | }; |
ryanyuyu | 3:30dcfcf9412c | 54 | //*/ |
ryanyuyu | 2:8ae58834937f | 55 | float32_t pState[NumTaps + BlockSize - 1]; |
ryanyuyu | 2:8ae58834937f | 56 | |
ryanyuyu | 2:8ae58834937f | 57 | |
ryanyuyu | 2:8ae58834937f | 58 | int index_g; //tracks the index for the waveform array |
ryanyuyu | 0:3aae5d23d0db | 59 | |
ryanyuyu | 2:8ae58834937f | 60 | |
ryanyuyu | 2:8ae58834937f | 61 | void readPoint() |
ryanyuyu | 2:8ae58834937f | 62 | { |
ryanyuyu | 2:8ae58834937f | 63 | waitForNext = false; |
ryanyuyu | 2:8ae58834937f | 64 | } |
ryanyuyu | 2:8ae58834937f | 65 | |
ryanyuyu | 2:8ae58834937f | 66 | |
ryanyuyu | 2:8ae58834937f | 67 | /** |
ryanyuyu | 2:8ae58834937f | 68 | * This function reads one full set of analog data into the uC |
ryanyuyu | 2:8ae58834937f | 69 | */ |
ryanyuyu | 2:8ae58834937f | 70 | void readSamples() |
ryanyuyu | 2:8ae58834937f | 71 | { |
ryanyuyu | 2:8ae58834937f | 72 | Ticker sampler; //allows for precision data reading |
ryanyuyu | 2:8ae58834937f | 73 | waitForNext = true; |
ryanyuyu | 2:8ae58834937f | 74 | sampler.attach_us(&readPoint, (int) (1000000/f_sampling) ); //read in data according the sampling freq |
ryanyuyu | 2:8ae58834937f | 75 | for (int i = 0; i < BlockSize; i++) |
ryanyuyu | 2:8ae58834937f | 76 | { |
ryanyuyu | 2:8ae58834937f | 77 | while (waitForNext); //wait until the ticker calls for the next sample |
ryanyuyu | 2:8ae58834937f | 78 | waveform[i] = input.read(); |
ryanyuyu | 2:8ae58834937f | 79 | waitForNext = true; |
ryanyuyu | 2:8ae58834937f | 80 | } |
ryanyuyu | 2:8ae58834937f | 81 | sampler.detach(); |
ryanyuyu | 2:8ae58834937f | 82 | } |
ryanyuyu | 3:30dcfcf9412c | 83 | |
ryanyuyu | 3:30dcfcf9412c | 84 | void outputWaveform() |
ryanyuyu | 3:30dcfcf9412c | 85 | { |
ryanyuyu | 3:30dcfcf9412c | 86 | Ticker outputter; |
ryanyuyu | 3:30dcfcf9412c | 87 | waitForNext = true; |
ryanyuyu | 3:30dcfcf9412c | 88 | outputter.attach_us(&readPoint, (int) (1000000/f_sampling) ); //output data according the sampling freq |
ryanyuyu | 3:30dcfcf9412c | 89 | for (int i = 0; i < BlockSize; i++) |
ryanyuyu | 3:30dcfcf9412c | 90 | { |
ryanyuyu | 3:30dcfcf9412c | 91 | while (waitForNext); //wait until the ticker calls for the next data point |
ryanyuyu | 3:30dcfcf9412c | 92 | waveOut.write(postFilterData[i]); |
ryanyuyu | 3:30dcfcf9412c | 93 | waitForNext = true; |
ryanyuyu | 3:30dcfcf9412c | 94 | } |
ryanyuyu | 3:30dcfcf9412c | 95 | outputter.detach(); |
ryanyuyu | 3:30dcfcf9412c | 96 | } |
ryanyuyu | 3:30dcfcf9412c | 97 | |
ryanyuyu | 3:30dcfcf9412c | 98 | int setPot(int wiperNo, float kOhms) |
ryanyuyu | 3:30dcfcf9412c | 99 | { |
ryanyuyu | 3:30dcfcf9412c | 100 | //257 steps (8 bits + 1), see section 7.0 for SPI instructions |
ryanyuyu | 3:30dcfcf9412c | 101 | float Rmax = 100000; |
ryanyuyu | 3:30dcfcf9412c | 102 | spi.frequency(2000000); |
ryanyuyu | 3:30dcfcf9412c | 103 | spi.format(16, 0); //16 bits, mode b00 |
ryanyuyu | 3:30dcfcf9412c | 104 | float ratio = kOhms * 1000.0 / Rmax; |
ryanyuyu | 3:30dcfcf9412c | 105 | if (ratio > 1) ratio = 1; |
ryanyuyu | 3:30dcfcf9412c | 106 | if (ratio < 0) ratio = 0; |
ryanyuyu | 3:30dcfcf9412c | 107 | int dataBits = (int) (ratio * 0x100); |
ryanyuyu | 3:30dcfcf9412c | 108 | int command = wiperNo << 12; //setting the Address and Command bits |
ryanyuyu | 3:30dcfcf9412c | 109 | command += dataBits; //add in the digital setting |
ryanyuyu | 3:30dcfcf9412c | 110 | spi.write(command); |
ryanyuyu | 3:30dcfcf9412c | 111 | return command; |
ryanyuyu | 3:30dcfcf9412c | 112 | } |
ryanyuyu | 3:30dcfcf9412c | 113 | |
ryanyuyu | 3:30dcfcf9412c | 114 | float32_t rms() |
ryanyuyu | 3:30dcfcf9412c | 115 | { |
ryanyuyu | 3:30dcfcf9412c | 116 | float32_t rms = 0; |
ryanyuyu | 3:30dcfcf9412c | 117 | for(int i = 0; i < BlockSize; i++) |
ryanyuyu | 3:30dcfcf9412c | 118 | { |
ryanyuyu | 3:30dcfcf9412c | 119 | rms += postFilterData[i]*postFilterData[i]; |
ryanyuyu | 3:30dcfcf9412c | 120 | } |
ryanyuyu | 3:30dcfcf9412c | 121 | return sqrt(rms/BlockSize); |
ryanyuyu | 3:30dcfcf9412c | 122 | } |
ryanyuyu | 2:8ae58834937f | 123 | |
ryanyuyu | 0:3aae5d23d0db | 124 | |
ryanyuyu | 0:3aae5d23d0db | 125 | int main() { |
ryanyuyu | 2:8ae58834937f | 126 | //to initialize the filter stuff use init functions (see line 89 in the arm_fir_f32.c file for documentation) |
ryanyuyu | 2:8ae58834937f | 127 | //the initialization function is in a seperate file called arm_fir_init_f32.c |
ryanyuyu | 2:8ae58834937f | 128 | |
ryanyuyu | 2:8ae58834937f | 129 | /* |
ryanyuyu | 2:8ae58834937f | 130 | * <code>pState</code> points to a state array of size <code>numTaps + blockSize - 1</code>. |
ryanyuyu | 2:8ae58834937f | 131 | * Samples in the state buffer are stored in the following order. |
ryanyuyu | 2:8ae58834937f | 132 | * \par |
ryanyuyu | 2:8ae58834937f | 133 | * <pre> |
ryanyuyu | 2:8ae58834937f | 134 | * {x[n-numTaps+1], x[n-numTaps], x[n-numTaps-1], x[n-numTaps-2]....x[0], x[1], ..., x[blockSize-1]} |
ryanyuyu | 2:8ae58834937f | 135 | * </pre> |
ryanyuyu | 2:8ae58834937f | 136 | * \par |
ryanyuyu | 2:8ae58834937f | 137 | |
ryanyuyu | 2:8ae58834937f | 138 | */ |
ryanyuyu | 2:8ae58834937f | 139 | arm_fir_instance_f32* filter = new arm_fir_instance_f32(); |
ryanyuyu | 2:8ae58834937f | 140 | int state = 0; |
ryanyuyu | 2:8ae58834937f | 141 | uint16_t numTaps = NumTaps; |
ryanyuyu | 2:8ae58834937f | 142 | uint32_t blockSize = BlockSize; |
ryanyuyu | 3:30dcfcf9412c | 143 | char buffer[32]; //for debugging scanf things |
ryanyuyu | 3:30dcfcf9412c | 144 | char* outputString; |
ryanyuyu | 3:30dcfcf9412c | 145 | float32_t estimate = 0; |
ryanyuyu | 2:8ae58834937f | 146 | while(1) |
ryanyuyu | 2:8ae58834937f | 147 | { |
ryanyuyu | 2:8ae58834937f | 148 | //pc.printf("While loop\n\r"); |
ryanyuyu | 2:8ae58834937f | 149 | switch(state) |
ryanyuyu | 2:8ae58834937f | 150 | { |
ryanyuyu | 2:8ae58834937f | 151 | case 0: //initialization |
ryanyuyu | 1:4fe83f71b889 | 152 | |
ryanyuyu | 2:8ae58834937f | 153 | //pc.printf("pre-filter init\n\r"); |
ryanyuyu | 2:8ae58834937f | 154 | arm_fir_init_f32(filter, numTaps, pCoeffs, pState, blockSize); |
ryanyuyu | 2:8ae58834937f | 155 | //pc.printf("Pre-attachment"); |
ryanyuyu | 3:30dcfcf9412c | 156 | spi.frequency(1000000); |
ryanyuyu | 2:8ae58834937f | 157 | state = 1; |
ryanyuyu | 2:8ae58834937f | 158 | pc.printf("Done with init.\n\r"); |
ryanyuyu | 2:8ae58834937f | 159 | break; |
ryanyuyu | 2:8ae58834937f | 160 | |
ryanyuyu | 2:8ae58834937f | 161 | case 1: //read data, take samples |
ryanyuyu | 2:8ae58834937f | 162 | pc.printf("Reading data.\n\r"); |
ryanyuyu | 2:8ae58834937f | 163 | readSamples(); |
ryanyuyu | 3:30dcfcf9412c | 164 | state = 3; |
ryanyuyu | 2:8ae58834937f | 165 | break; |
ryanyuyu | 2:8ae58834937f | 166 | |
ryanyuyu | 3:30dcfcf9412c | 167 | case 2: //printout to pc connection or other output debugging |
ryanyuyu | 2:8ae58834937f | 168 | //pc.printf("into print\n\r"); |
ryanyuyu | 2:8ae58834937f | 169 | /* |
ryanyuyu | 2:8ae58834937f | 170 | for (int i = 0; i < BlockSize; i++) |
ryanyuyu | 2:8ae58834937f | 171 | { |
ryanyuyu | 2:8ae58834937f | 172 | pc.printf("Waveform contents:%f\n\r", waveform[i]); |
ryanyuyu | 2:8ae58834937f | 173 | } |
ryanyuyu | 2:8ae58834937f | 174 | */ |
ryanyuyu | 3:30dcfcf9412c | 175 | for (int i = 0; i < 10; i++) outputWaveform(); |
ryanyuyu | 3:30dcfcf9412c | 176 | wait_ms(500); |
ryanyuyu | 3:30dcfcf9412c | 177 | state = 1; |
ryanyuyu | 2:8ae58834937f | 178 | break; |
ryanyuyu | 2:8ae58834937f | 179 | case 3: //filter? |
ryanyuyu | 2:8ae58834937f | 180 | pc.printf("Filtering?\n\r"); |
ryanyuyu | 2:8ae58834937f | 181 | arm_fir_f32(filter, waveform, postFilterData, blockSize); |
ryanyuyu | 3:30dcfcf9412c | 182 | state = 2; |
ryanyuyu | 2:8ae58834937f | 183 | break; |
ryanyuyu | 2:8ae58834937f | 184 | case 4: //FFT? |
ryanyuyu | 2:8ae58834937f | 185 | break; |
ryanyuyu | 2:8ae58834937f | 186 | case 5: //output, write to display and PWM tone |
ryanyuyu | 3:30dcfcf9412c | 187 | sprintf(outputString, "RMS = %f", estimate); |
ryanyuyu | 3:30dcfcf9412c | 188 | lcd.print(outputString); |
ryanyuyu | 3:30dcfcf9412c | 189 | state = 1; |
ryanyuyu | 2:8ae58834937f | 190 | break; |
ryanyuyu | 3:30dcfcf9412c | 191 | case 6: //calculate the average voltage maybe depreciated |
ryanyuyu | 3:30dcfcf9412c | 192 | /* |
ryanyuyu | 3:30dcfcf9412c | 193 | * |
ryanyuyu | 3:30dcfcf9412c | 194 | * |
ryanyuyu | 3:30dcfcf9412c | 195 | |
ryanyuyu | 2:8ae58834937f | 196 | double sum = 0; |
ryanyuyu | 2:8ae58834937f | 197 | for (int i = 0; i < BlockSize; i++) sum += postFilterData[i]; |
ryanyuyu | 2:8ae58834937f | 198 | double average = sum/BlockSize*3.3; //*3.3 V_ref (array stored as fractions of V_ref) |
ryanyuyu | 2:8ae58834937f | 199 | pc.printf("Average = %f\n\r", average); |
ryanyuyu | 2:8ae58834937f | 200 | wait_ms(500); |
ryanyuyu | 3:30dcfcf9412c | 201 | state = 2; |
ryanyuyu | 3:30dcfcf9412c | 202 | */ |
ryanyuyu | 3:30dcfcf9412c | 203 | estimate = rms(); |
ryanyuyu | 3:30dcfcf9412c | 204 | pc.printf("RMS = %f", estimate); |
ryanyuyu | 3:30dcfcf9412c | 205 | state = 5; |
ryanyuyu | 3:30dcfcf9412c | 206 | break; |
ryanyuyu | 3:30dcfcf9412c | 207 | case 7: //estimate amplitude |
ryanyuyu | 3:30dcfcf9412c | 208 | pc.printf("Into estimation\n\r"); |
ryanyuyu | 3:30dcfcf9412c | 209 | int peaks = 0; |
ryanyuyu | 3:30dcfcf9412c | 210 | float sum = 0.0; |
ryanyuyu | 3:30dcfcf9412c | 211 | float prev, current, next; |
ryanyuyu | 3:30dcfcf9412c | 212 | for (int i = 0+1; i < BlockSize-1; i++) |
ryanyuyu | 3:30dcfcf9412c | 213 | { |
ryanyuyu | 3:30dcfcf9412c | 214 | prev = postFilterData[i-1]; |
ryanyuyu | 3:30dcfcf9412c | 215 | current = postFilterData[i]; |
ryanyuyu | 3:30dcfcf9412c | 216 | next = postFilterData[i+1]; |
ryanyuyu | 3:30dcfcf9412c | 217 | if (prev < current && next < current) //local max |
ryanyuyu | 3:30dcfcf9412c | 218 | { |
ryanyuyu | 3:30dcfcf9412c | 219 | sum += current; |
ryanyuyu | 3:30dcfcf9412c | 220 | peaks++; |
ryanyuyu | 3:30dcfcf9412c | 221 | } |
ryanyuyu | 3:30dcfcf9412c | 222 | } |
ryanyuyu | 3:30dcfcf9412c | 223 | float average = sum/peaks; |
ryanyuyu | 3:30dcfcf9412c | 224 | pc.printf("Average of peaks (scalar) = %f\n\r", average); |
ryanyuyu | 2:8ae58834937f | 225 | state = 1; |
ryanyuyu | 2:8ae58834937f | 226 | break; |
ryanyuyu | 3:30dcfcf9412c | 227 | |
ryanyuyu | 3:30dcfcf9412c | 228 | case 8: //digital pot interfacing and calibration |
ryanyuyu | 3:30dcfcf9412c | 229 | pc.printf("kOhms?\n\r"); |
ryanyuyu | 3:30dcfcf9412c | 230 | pc.scanf("%s", buffer); |
ryanyuyu | 3:30dcfcf9412c | 231 | float value = atof(buffer); |
ryanyuyu | 3:30dcfcf9412c | 232 | pc.printf("Command: %x Scanned:%f\n\r", setPot(0, value), value); |
ryanyuyu | 3:30dcfcf9412c | 233 | wait_ms(250); |
ryanyuyu | 3:30dcfcf9412c | 234 | break; |
ryanyuyu | 2:8ae58834937f | 235 | default: |
ryanyuyu | 2:8ae58834937f | 236 | break; |
ryanyuyu | 2:8ae58834937f | 237 | } |
ryanyuyu | 2:8ae58834937f | 238 | } //end of (infinite) while loop |
ryanyuyu | 0:3aae5d23d0db | 239 | } |