FFT_BUENA

Dependencies:   FastAnalogIn HSI2RGBW_PWM NVIC_set_all_priorities mbed-dsp mbed

Fork of KL25Z_FFT_Demo by Frank Vannieuwkerke

Committer:
oscarmtzman
Date:
Thu Apr 30 00:34:09 2015 +0000
Revision:
8:391e30708e7c
Parent:
7:18e9a56bef9a
FFT_COMPLETA

Who changed what in which revision?

UserRevisionLine numberNew contents of line
frankvnk 0:0c037aff5039 1 #include "mbed.h"
frankvnk 0:0c037aff5039 2 #include "NVIC_set_all_priorities.h"
frankvnk 0:0c037aff5039 3 #include <ctype.h>
frankvnk 0:0c037aff5039 4 #include "arm_math.h"
frankvnk 2:035d551759a5 5 #include "arm_const_structs.h"
frankvnk 0:0c037aff5039 6 #include "hsi2rgbw_pwm.h"
frankvnk 1:736b34e0f484 7 #include "FastAnalogIn.h"
frankvnk 0:0c037aff5039 8
oscarmtzman 8:391e30708e7c 9 DigitalOut led1(PTA2);
oscarmtzman 5:6caecff3094d 10 DigitalOut led2(PTC0);
oscarmtzman 5:6caecff3094d 11 DigitalOut led3(PTC3);
oscarmtzman 5:6caecff3094d 12 DigitalOut led4(PTC4);
oscarmtzman 5:6caecff3094d 13 DigitalOut led5(PTC5);
oscarmtzman 5:6caecff3094d 14 DigitalOut led6(PTC6);
oscarmtzman 5:6caecff3094d 15 DigitalOut led7(PTC10);
oscarmtzman 5:6caecff3094d 16 DigitalOut led8(PTC11);
oscarmtzman 6:17a42dc976bb 17 AnalogIn pot(A0);
oscarmtzman 5:6caecff3094d 18
oscarmtzman 6:17a42dc976bb 19 float pulso=0;
oscarmtzman 6:17a42dc976bb 20 int fmin=50;
oscarmtzman 5:6caecff3094d 21 int fmax=120;
oscarmtzman 5:6caecff3094d 22 float sum=(fmax-fmin)/8;
oscarmtzman 5:6caecff3094d 23
frankvnk 0:0c037aff5039 24 Serial pc(USBTX, USBRX);
frankvnk 0:0c037aff5039 25
oscarmtzman 4:a6130c61c228 26 float pulsocalculado=0;
frankvnk 0:0c037aff5039 27
oscarmtzman 4:a6130c61c228 28 float qrs2[512]= {0};
oscarmtzman 4:a6130c61c228 29 float fs=102.4;
oscarmtzman 4:a6130c61c228 30 float ts=1/fs;
oscarmtzman 4:a6130c61c228 31 int tiempo=5;
oscarmtzman 4:a6130c61c228 32 float pi=3.1416;
oscarmtzman 6:17a42dc976bb 33 float l=0;
oscarmtzman 6:17a42dc976bb 34 float b=0;
oscarmtzman 4:a6130c61c228 35 float a=1.6;
oscarmtzman 4:a6130c61c228 36 int n=100;
oscarmtzman 6:17a42dc976bb 37 float qrs1=0;
oscarmtzman 6:17a42dc976bb 38
frankvnk 0:0c037aff5039 39
frankvnk 0:0c037aff5039 40 #ifndef RGBW_ext
frankvnk 0:0c037aff5039 41 // HSI to RGB conversion with direct output to PWM channels - on-board RGB LED
frankvnk 0:0c037aff5039 42 hsi2rgbw_pwm led(LED_RED, LED_GREEN, LED_BLUE);
frankvnk 0:0c037aff5039 43 #else
frankvnk 0:0c037aff5039 44 // HSI to RGBW conversion with direct output to external PWM channels - RGBW LED
frankvnk 0:0c037aff5039 45 hsi2rgbw_pwm led(PTD4, PTA12, PTA4, PTA5); //Red, Green, Blue, White
frankvnk 0:0c037aff5039 46 #endif
frankvnk 0:0c037aff5039 47
frankvnk 0:0c037aff5039 48 // Dummy ISR for disabling NMI on PTA4 - !! DO NOT REMOVE THIS !!
frankvnk 0:0c037aff5039 49 // More info at https://mbed.org/questions/1387/How-can-I-access-the-FTFA_FOPT-register-/
oscarmtzman 4:a6130c61c228 50 extern "C" void NMI_Handler()
oscarmtzman 4:a6130c61c228 51 {
frankvnk 0:0c037aff5039 52 DigitalIn test(PTA4);
frankvnk 0:0c037aff5039 53 }
frankvnk 0:0c037aff5039 54
frankvnk 0:0c037aff5039 55
frankvnk 0:0c037aff5039 56 ////////////////////////////////////////////////////////////////////////////////
frankvnk 0:0c037aff5039 57 // CONFIGURATION
frankvnk 0:0c037aff5039 58 // These values can be changed to alter the behavior of the spectrum display.
frankvnk 0:0c037aff5039 59 // KL25Z limitations
frankvnk 0:0c037aff5039 60 // -----------------
frankvnk 0:0c037aff5039 61 // - When used with the Spectrogram python script :
frankvnk 0:0c037aff5039 62 // There is a substantial time lag between the music and the screen output.
frankvnk 2:035d551759a5 63 // Max allowed SAMPLE_RATE_HZ is 40000
frankvnk 2:035d551759a5 64 // Max allowed FFT_SIZE is 64
frankvnk 0:0c037aff5039 65 ////////////////////////////////////////////////////////////////////////////////
frankvnk 0:0c037aff5039 66
frankvnk 2:035d551759a5 67 int SLOWDOWN = 4; // Create an optical delay in spectrumLoop - useful when only one RGB led is used.
oscarmtzman 4:a6130c61c228 68 // Only active when nonzero.
oscarmtzman 4:a6130c61c228 69 // A value >= 1000 and <= 1000 + PIXEL_COUNT fixes the output to a single frequency
oscarmtzman 4:a6130c61c228 70 // window = a single color.
frankvnk 0:0c037aff5039 71 int SAMPLE_RATE_HZ = 40000; // Sample rate of the audio in hertz.
frankvnk 2:035d551759a5 72 float SPECTRUM_MIN_DB = 30.0; // Audio intensity (in decibels) that maps to low LED brightness.
frankvnk 1:736b34e0f484 73 float SPECTRUM_MAX_DB = 80.0; // Audio intensity (in decibels) that maps to high LED brightness.
frankvnk 0:0c037aff5039 74 int LEDS_ENABLED = 1; // Control if the LED's should display the spectrum or not. 1 is true, 0 is false.
oscarmtzman 4:a6130c61c228 75 // Useful for turning the LED display on and off with commands from the serial port.
oscarmtzman 4:a6130c61c228 76 const int FFT_SIZE = 512; // Size of the FFT.
frankvnk 1:736b34e0f484 77 const int PIXEL_COUNT = 32; // Number of pixels. You should be able to increase this without
oscarmtzman 4:a6130c61c228 78 // any other changes to the program.
frankvnk 0:0c037aff5039 79 const int MAX_CHARS = 65; // Max size of the input command buffer
frankvnk 0:0c037aff5039 80
frankvnk 0:0c037aff5039 81 ////////////////////////////////////////////////////////////////////////////////
frankvnk 0:0c037aff5039 82 // INTERNAL STATE
frankvnk 0:0c037aff5039 83 // These shouldn't be modified unless you know what you're doing.
frankvnk 0:0c037aff5039 84 ////////////////////////////////////////////////////////////////////////////////
frankvnk 2:035d551759a5 85 const static arm_cfft_instance_f32 *S;
frankvnk 0:0c037aff5039 86 Ticker samplingTimer;
frankvnk 0:0c037aff5039 87 float samples[FFT_SIZE*2];
frankvnk 0:0c037aff5039 88 float magnitudes[FFT_SIZE];
frankvnk 0:0c037aff5039 89 int sampleCounter = 0;
frankvnk 0:0c037aff5039 90 char commandBuffer[MAX_CHARS];
frankvnk 0:0c037aff5039 91 float frequencyWindow[PIXEL_COUNT+1];
frankvnk 0:0c037aff5039 92 float hues[PIXEL_COUNT];
frankvnk 0:0c037aff5039 93 bool commandRecv = 0;
frankvnk 0:0c037aff5039 94 ////////////////////////////////////////////////////////////////////////////////
frankvnk 0:0c037aff5039 95 // UTILITY FUNCTIONS
frankvnk 0:0c037aff5039 96 ////////////////////////////////////////////////////////////////////////////////
frankvnk 0:0c037aff5039 97
oscarmtzman 4:a6130c61c228 98 void rxisr()
oscarmtzman 4:a6130c61c228 99 {
frankvnk 0:0c037aff5039 100 char c = pc.getc();
frankvnk 0:0c037aff5039 101 // Add any characters that aren't the end of a command (semicolon) to the input buffer.
frankvnk 0:0c037aff5039 102 if (c != ';') {
frankvnk 0:0c037aff5039 103 c = toupper(c);
frankvnk 0:0c037aff5039 104 strncat(commandBuffer, &c, 1);
frankvnk 0:0c037aff5039 105 } else {
frankvnk 0:0c037aff5039 106 // Parse the command because an end of command token was encountered.
frankvnk 0:0c037aff5039 107 commandRecv = 1;
frankvnk 0:0c037aff5039 108 }
frankvnk 0:0c037aff5039 109 }
frankvnk 0:0c037aff5039 110
frankvnk 0:0c037aff5039 111 // Compute the average magnitude of a target frequency window vs. all other frequencies.
frankvnk 0:0c037aff5039 112 void windowMean(float* magnitudes, int lowBin, int highBin, float* windowMean, float* otherMean)
frankvnk 0:0c037aff5039 113 {
frankvnk 0:0c037aff5039 114 *windowMean = 0;
frankvnk 0:0c037aff5039 115 *otherMean = 0;
frankvnk 0:0c037aff5039 116 // Notice the first magnitude bin is skipped because it represents the
frankvnk 0:0c037aff5039 117 // average power of the signal.
frankvnk 0:0c037aff5039 118 for (int i = 1; i < FFT_SIZE/2; ++i) {
frankvnk 0:0c037aff5039 119 if (i >= lowBin && i <= highBin) {
frankvnk 0:0c037aff5039 120 *windowMean += magnitudes[i];
frankvnk 0:0c037aff5039 121 } else {
frankvnk 0:0c037aff5039 122 *otherMean += magnitudes[i];
frankvnk 0:0c037aff5039 123 }
frankvnk 0:0c037aff5039 124 }
frankvnk 0:0c037aff5039 125 *windowMean /= (highBin - lowBin) + 1;
frankvnk 0:0c037aff5039 126 *otherMean /= (FFT_SIZE / 2 - (highBin - lowBin));
frankvnk 0:0c037aff5039 127 }
frankvnk 0:0c037aff5039 128
frankvnk 0:0c037aff5039 129 // Convert a frequency to the appropriate FFT bin it will fall within.
frankvnk 0:0c037aff5039 130 int frequencyToBin(float frequency)
frankvnk 0:0c037aff5039 131 {
frankvnk 0:0c037aff5039 132 float binFrequency = float(SAMPLE_RATE_HZ) / float(FFT_SIZE);
frankvnk 0:0c037aff5039 133 return int(frequency / binFrequency);
frankvnk 0:0c037aff5039 134 }
frankvnk 0:0c037aff5039 135
frankvnk 0:0c037aff5039 136
frankvnk 0:0c037aff5039 137 ////////////////////////////////////////////////////////////////////////////////
frankvnk 0:0c037aff5039 138 // SPECTRUM DISPLAY FUNCTIONS
frankvnk 0:0c037aff5039 139 ///////////////////////////////////////////////////////////////////////////////
frankvnk 0:0c037aff5039 140
frankvnk 0:0c037aff5039 141 void spectrumSetup()
frankvnk 0:0c037aff5039 142 {
frankvnk 0:0c037aff5039 143 // Set the frequency window values by evenly dividing the possible frequency
frankvnk 0:0c037aff5039 144 // spectrum across the number of neo pixels.
frankvnk 0:0c037aff5039 145 float windowSize = (SAMPLE_RATE_HZ / 2.0) / float(PIXEL_COUNT);
frankvnk 0:0c037aff5039 146 for (int i = 0; i < PIXEL_COUNT+1; ++i) {
frankvnk 0:0c037aff5039 147 frequencyWindow[i] = i*windowSize;
frankvnk 0:0c037aff5039 148 }
frankvnk 0:0c037aff5039 149 // Evenly spread hues across all pixels.
frankvnk 0:0c037aff5039 150 for (int i = 0; i < PIXEL_COUNT; ++i) {
frankvnk 0:0c037aff5039 151 hues[i] = 360.0*(float(i)/float(PIXEL_COUNT-1));
frankvnk 0:0c037aff5039 152 }
frankvnk 0:0c037aff5039 153 }
frankvnk 0:0c037aff5039 154
frankvnk 0:0c037aff5039 155 void spectrumLoop()
frankvnk 0:0c037aff5039 156 {
frankvnk 0:0c037aff5039 157 // Update each LED based on the intensity of the audio
frankvnk 0:0c037aff5039 158 // in the associated frequency window.
frankvnk 0:0c037aff5039 159 static int SLrpt = 0, SLpixcnt = 0;
frankvnk 0:0c037aff5039 160 int SLpixend = 0;
frankvnk 0:0c037aff5039 161 float intensity, otherMean;
oscarmtzman 4:a6130c61c228 162 if(SLOWDOWN != 0) {
oscarmtzman 4:a6130c61c228 163 if(SLOWDOWN >= 1000) {
oscarmtzman 4:a6130c61c228 164 if(SLOWDOWN <= (1000 + PIXEL_COUNT-1)) {
frankvnk 0:0c037aff5039 165 SLpixcnt = SLOWDOWN - 1000;
frankvnk 0:0c037aff5039 166 SLrpt = 0;
frankvnk 0:0c037aff5039 167 SLpixend = SLpixcnt + 1;
oscarmtzman 4:a6130c61c228 168 } else
frankvnk 0:0c037aff5039 169 SLOWDOWN = 0;
oscarmtzman 4:a6130c61c228 170 } else {
frankvnk 0:0c037aff5039 171 SLrpt++;
oscarmtzman 4:a6130c61c228 172 if (SLrpt >= SLOWDOWN) {
frankvnk 0:0c037aff5039 173 SLrpt = 0;
frankvnk 0:0c037aff5039 174 SLpixcnt = SLpixcnt < PIXEL_COUNT-1 ? ++SLpixcnt : 0;
frankvnk 0:0c037aff5039 175 }
frankvnk 0:0c037aff5039 176 SLpixend = SLpixcnt + 1;
frankvnk 0:0c037aff5039 177 }
oscarmtzman 4:a6130c61c228 178 } else {
frankvnk 0:0c037aff5039 179 SLpixcnt = 0;
frankvnk 0:0c037aff5039 180 SLrpt = 0;
frankvnk 0:0c037aff5039 181 SLpixend = PIXEL_COUNT;
frankvnk 0:0c037aff5039 182 }
frankvnk 0:0c037aff5039 183 for (int i = SLpixcnt; i < SLpixend; ++i) {
frankvnk 0:0c037aff5039 184 windowMean(magnitudes,
frankvnk 0:0c037aff5039 185 frequencyToBin(frequencyWindow[i]),
frankvnk 0:0c037aff5039 186 frequencyToBin(frequencyWindow[i+1]),
frankvnk 0:0c037aff5039 187 &intensity,
frankvnk 0:0c037aff5039 188 &otherMean);
frankvnk 0:0c037aff5039 189 // Convert intensity to decibels.
oscarmtzman 3:f826669fc0a8 190 intensity = 20.0*log10(intensity); //Modificar
frankvnk 0:0c037aff5039 191 // Scale the intensity and clamp between 0 and 1.0.
frankvnk 0:0c037aff5039 192 intensity -= SPECTRUM_MIN_DB;
frankvnk 0:0c037aff5039 193 intensity = intensity < 0.0 ? 0.0 : intensity;
frankvnk 0:0c037aff5039 194 intensity /= (SPECTRUM_MAX_DB-SPECTRUM_MIN_DB);
frankvnk 0:0c037aff5039 195 intensity = intensity > 1.0 ? 1.0 : intensity;
frankvnk 0:0c037aff5039 196 led.hsi2rgbw(hues[i], 1.0, intensity);
frankvnk 0:0c037aff5039 197 }
frankvnk 0:0c037aff5039 198 }
frankvnk 0:0c037aff5039 199
frankvnk 0:0c037aff5039 200
frankvnk 0:0c037aff5039 201 ////////////////////////////////////////////////////////////////////////////////
frankvnk 0:0c037aff5039 202 // SAMPLING FUNCTIONS
frankvnk 0:0c037aff5039 203 ////////////////////////////////////////////////////////////////////////////////
frankvnk 0:0c037aff5039 204
frankvnk 0:0c037aff5039 205 void samplingCallback()
frankvnk 0:0c037aff5039 206 {
frankvnk 0:0c037aff5039 207 // Read from the ADC and store the sample data
oscarmtzman 4:a6130c61c228 208 samples[sampleCounter] = qrs1+qrs2[(sampleCounter+1)/2];
frankvnk 0:0c037aff5039 209 // Complex FFT functions require a coefficient for the imaginary part of the input.
frankvnk 0:0c037aff5039 210 // Since we only have real data, set this coefficient to zero.
frankvnk 0:0c037aff5039 211 samples[sampleCounter+1] = 0.0;
frankvnk 0:0c037aff5039 212 // Update sample buffer position and stop after the buffer is filled
frankvnk 0:0c037aff5039 213 sampleCounter += 2;
frankvnk 0:0c037aff5039 214 if (sampleCounter >= FFT_SIZE*2) {
frankvnk 0:0c037aff5039 215 samplingTimer.detach();
frankvnk 0:0c037aff5039 216 }
frankvnk 0:0c037aff5039 217 }
frankvnk 0:0c037aff5039 218
frankvnk 0:0c037aff5039 219 void samplingBegin()
frankvnk 0:0c037aff5039 220 {
frankvnk 0:0c037aff5039 221 // Reset sample buffer position and start callback at necessary rate.
frankvnk 0:0c037aff5039 222 sampleCounter = 0;
frankvnk 0:0c037aff5039 223 samplingTimer.attach_us(&samplingCallback, 1000000/SAMPLE_RATE_HZ);
frankvnk 0:0c037aff5039 224 }
frankvnk 0:0c037aff5039 225
frankvnk 0:0c037aff5039 226 bool samplingIsDone()
frankvnk 0:0c037aff5039 227 {
frankvnk 0:0c037aff5039 228 return sampleCounter >= FFT_SIZE*2;
frankvnk 0:0c037aff5039 229 }
frankvnk 0:0c037aff5039 230
frankvnk 0:0c037aff5039 231
frankvnk 0:0c037aff5039 232 ////////////////////////////////////////////////////////////////////////////////
frankvnk 0:0c037aff5039 233 // COMMAND PARSING FUNCTIONS
frankvnk 0:0c037aff5039 234 // These functions allow parsing simple commands input on the serial port.
frankvnk 0:0c037aff5039 235 // Commands allow reading and writing variables that control the device.
frankvnk 0:0c037aff5039 236 //
frankvnk 0:0c037aff5039 237 // All commands must end with a semicolon character.
frankvnk 0:0c037aff5039 238 //
frankvnk 0:0c037aff5039 239 // Example commands are:
frankvnk 0:0c037aff5039 240 // GET SAMPLE_RATE_HZ;
frankvnk 0:0c037aff5039 241 // - Get the sample rate of the device.
frankvnk 0:0c037aff5039 242 // SET SAMPLE_RATE_HZ 400;
frankvnk 0:0c037aff5039 243 // - Set the sample rate of the device to 400 hertz.
frankvnk 0:0c037aff5039 244 //
frankvnk 0:0c037aff5039 245 ////////////////////////////////////////////////////////////////////////////////
frankvnk 0:0c037aff5039 246
frankvnk 0:0c037aff5039 247 void parseCommand(char* command)
frankvnk 0:0c037aff5039 248 {
frankvnk 0:0c037aff5039 249 if (strcmp(command, "GET MAGNITUDES") == 0) {
frankvnk 0:0c037aff5039 250 for (int i = 0; i < FFT_SIZE; ++i) {
frankvnk 0:0c037aff5039 251 printf("%f\r\n", magnitudes[i]);
frankvnk 0:0c037aff5039 252 }
frankvnk 0:0c037aff5039 253 } else if (strcmp(command, "GET SAMPLES") == 0) {
frankvnk 0:0c037aff5039 254 for (int i = 0; i < FFT_SIZE*2; i+=2) {
frankvnk 0:0c037aff5039 255 printf("%f\r\n", samples[i]);
frankvnk 0:0c037aff5039 256 }
frankvnk 0:0c037aff5039 257 } else if (strcmp(command, "GET FFT_SIZE") == 0) {
frankvnk 0:0c037aff5039 258 printf("%d\r\n", FFT_SIZE);
frankvnk 0:0c037aff5039 259 } else if (strcmp(command, "GET SAMPLE_RATE_HZ") == 0) {
frankvnk 0:0c037aff5039 260 printf("%d\r\n", SAMPLE_RATE_HZ);
frankvnk 0:0c037aff5039 261 } else if (strstr(command, "SET SAMPLE_RATE_HZ") != NULL) {
frankvnk 0:0c037aff5039 262 SAMPLE_RATE_HZ = (typeof(SAMPLE_RATE_HZ)) atof(command+(sizeof("SET SAMPLE_RATE_HZ")-1));
frankvnk 0:0c037aff5039 263 } else if (strcmp(command, "GET LEDS_ENABLED") == 0) {
frankvnk 0:0c037aff5039 264 printf("%d\r\n", LEDS_ENABLED);
frankvnk 0:0c037aff5039 265 } else if (strstr(command, "SET LEDS_ENABLED") != NULL) {
frankvnk 0:0c037aff5039 266 LEDS_ENABLED = (typeof(LEDS_ENABLED)) atof(command+(sizeof("SET LEDS_ENABLED")-1));
frankvnk 0:0c037aff5039 267 } else if (strcmp(command, "GET SPECTRUM_MIN_DB") == 0) {
frankvnk 0:0c037aff5039 268 printf("%f\r\n", SPECTRUM_MIN_DB);
frankvnk 0:0c037aff5039 269 } else if (strstr(command, "SET SPECTRUM_MIN_DB") != NULL) {
frankvnk 0:0c037aff5039 270 SPECTRUM_MIN_DB = (typeof(SPECTRUM_MIN_DB)) atof(command+(sizeof("SET SPECTRUM_MIN_DB")-1));
frankvnk 0:0c037aff5039 271 } else if (strcmp(command, "GET SPECTRUM_MAX_DB") == 0) {
frankvnk 0:0c037aff5039 272 printf("%f\r\n", SPECTRUM_MAX_DB);
frankvnk 0:0c037aff5039 273 } else if (strstr(command, "SET SPECTRUM_MAX_DB") != NULL) {
frankvnk 0:0c037aff5039 274 SPECTRUM_MAX_DB = (typeof(SPECTRUM_MAX_DB)) atof(command+(sizeof("SET SPECTRUM_MAX_DB")-1));
frankvnk 0:0c037aff5039 275 } else if (strcmp(command, "GET SLOWDOWN") == 0) {
frankvnk 0:0c037aff5039 276 printf("%d\r\n", SLOWDOWN);
frankvnk 0:0c037aff5039 277 } else if (strstr(command, "SET SLOWDOWN") != NULL) {
frankvnk 0:0c037aff5039 278 SLOWDOWN = (typeof(SLOWDOWN)) atoi(command+(sizeof("SET SLOWDOWN")-1));
frankvnk 0:0c037aff5039 279 }
frankvnk 0:0c037aff5039 280
frankvnk 0:0c037aff5039 281 // Update spectrum display values if sample rate was changed.
frankvnk 0:0c037aff5039 282 if (strstr(command, "SET SAMPLE_RATE_HZ ") != NULL) {
frankvnk 0:0c037aff5039 283 spectrumSetup();
frankvnk 0:0c037aff5039 284 }
frankvnk 0:0c037aff5039 285
frankvnk 0:0c037aff5039 286 // Turn off the LEDs if the state changed.
frankvnk 0:0c037aff5039 287 if (LEDS_ENABLED == 0) {
frankvnk 0:0c037aff5039 288 }
frankvnk 0:0c037aff5039 289 }
frankvnk 0:0c037aff5039 290
frankvnk 0:0c037aff5039 291 void parserLoop()
frankvnk 0:0c037aff5039 292 {
frankvnk 0:0c037aff5039 293 // Process any incoming characters from the serial port
frankvnk 0:0c037aff5039 294 while (pc.readable()) {
frankvnk 0:0c037aff5039 295 char c = pc.getc();
frankvnk 0:0c037aff5039 296 // Add any characters that aren't the end of a command (semicolon) to the input buffer.
frankvnk 0:0c037aff5039 297 if (c != ';') {
frankvnk 0:0c037aff5039 298 c = toupper(c);
frankvnk 0:0c037aff5039 299 strncat(commandBuffer, &c, 1);
frankvnk 0:0c037aff5039 300 } else {
frankvnk 0:0c037aff5039 301 // Parse the command because an end of command token was encountered.
frankvnk 0:0c037aff5039 302 parseCommand(commandBuffer);
frankvnk 0:0c037aff5039 303 // Clear the input buffer
frankvnk 0:0c037aff5039 304 memset(commandBuffer, 0, sizeof(commandBuffer));
frankvnk 0:0c037aff5039 305 }
frankvnk 0:0c037aff5039 306 }
frankvnk 0:0c037aff5039 307 }
frankvnk 0:0c037aff5039 308
frankvnk 0:0c037aff5039 309 ////////////////////////////////////////////////////////////////////////////////
frankvnk 0:0c037aff5039 310 // MAIN FUNCTION
frankvnk 0:0c037aff5039 311 ////////////////////////////////////////////////////////////////////////////////
frankvnk 0:0c037aff5039 312
frankvnk 0:0c037aff5039 313 int main()
frankvnk 0:0c037aff5039 314 {
frankvnk 0:0c037aff5039 315 NVIC_set_all_irq_priorities(1);
frankvnk 0:0c037aff5039 316 NVIC_SetPriority(UART0_IRQn, 0);
frankvnk 0:0c037aff5039 317 // Set up serial port.
oscarmtzman 3:f826669fc0a8 318 pc.baud (9600);
frankvnk 0:0c037aff5039 319 pc.attach(&rxisr);
oscarmtzman 4:a6130c61c228 320
oscarmtzman 4:a6130c61c228 321 float harm[512];
oscarmtzman 4:a6130c61c228 322 int inmax=0,max=0;
oscarmtzman 7:18e9a56bef9a 323
oscarmtzman 6:17a42dc976bb 324 pulso=fmin+(fmax-fmin)*pot.read();
oscarmtzman 6:17a42dc976bb 325 pc.printf("%f\n\n\n",pulso);
oscarmtzman 6:17a42dc976bb 326 l=30/pulso;
oscarmtzman 6:17a42dc976bb 327 b=(2*l)/0.11;
oscarmtzman 6:17a42dc976bb 328 qrs1=(a/(2*b))*(2-b);
oscarmtzman 7:18e9a56bef9a 329
oscarmtzman 4:a6130c61c228 330
oscarmtzman 4:a6130c61c228 331
oscarmtzman 4:a6130c61c228 332 for(int i=1; i<=n; i=i+1) {
oscarmtzman 4:a6130c61c228 333 for(int j=0; j<512; j=j+1) {
oscarmtzman 4:a6130c61c228 334 harm[j]=(((2*b*a)/(i*i*pi*pi))*(1-cos((i*pi)/b)))*cos((i*pi*(j+1)*ts)/l);
oscarmtzman 4:a6130c61c228 335 }
oscarmtzman 4:a6130c61c228 336 for(int k=0; k<512; k=k+1) {
oscarmtzman 4:a6130c61c228 337 qrs2[k]=qrs2[k]+harm[k];
oscarmtzman 4:a6130c61c228 338 }
oscarmtzman 4:a6130c61c228 339 }
oscarmtzman 4:a6130c61c228 340
oscarmtzman 4:a6130c61c228 341
oscarmtzman 4:a6130c61c228 342
oscarmtzman 4:a6130c61c228 343
oscarmtzman 4:a6130c61c228 344
oscarmtzman 4:a6130c61c228 345
oscarmtzman 4:a6130c61c228 346
frankvnk 0:0c037aff5039 347 #ifndef RGBW_ext
frankvnk 0:0c037aff5039 348 led.invertpwm(1); //On-board KL25Z RGB LED uses common anode.
oscarmtzman 4:a6130c61c228 349 #endif
frankvnk 0:0c037aff5039 350 // Clear the input command buffer
frankvnk 0:0c037aff5039 351 memset(commandBuffer, 0, sizeof(commandBuffer));
frankvnk 0:0c037aff5039 352
frankvnk 0:0c037aff5039 353 // Initialize spectrum display
frankvnk 0:0c037aff5039 354 spectrumSetup();
frankvnk 0:0c037aff5039 355
frankvnk 0:0c037aff5039 356 // Begin sampling audio
frankvnk 0:0c037aff5039 357 samplingBegin();
frankvnk 0:0c037aff5039 358
frankvnk 2:035d551759a5 359 // Init arm_ccft_32
oscarmtzman 4:a6130c61c228 360 switch (FFT_SIZE) {
oscarmtzman 4:a6130c61c228 361 case 16:
oscarmtzman 4:a6130c61c228 362 S = & arm_cfft_sR_f32_len16;
oscarmtzman 4:a6130c61c228 363 break;
oscarmtzman 4:a6130c61c228 364 case 32:
oscarmtzman 4:a6130c61c228 365 S = & arm_cfft_sR_f32_len32;
oscarmtzman 4:a6130c61c228 366 break;
oscarmtzman 4:a6130c61c228 367 case 64:
oscarmtzman 4:a6130c61c228 368 S = & arm_cfft_sR_f32_len64;
oscarmtzman 4:a6130c61c228 369 break;
oscarmtzman 4:a6130c61c228 370 case 128:
oscarmtzman 4:a6130c61c228 371 S = & arm_cfft_sR_f32_len128;
oscarmtzman 4:a6130c61c228 372 break;
oscarmtzman 4:a6130c61c228 373 case 256:
oscarmtzman 4:a6130c61c228 374 S = & arm_cfft_sR_f32_len256;
oscarmtzman 4:a6130c61c228 375 break;
oscarmtzman 4:a6130c61c228 376 case 512:
oscarmtzman 4:a6130c61c228 377 S = & arm_cfft_sR_f32_len512;
oscarmtzman 4:a6130c61c228 378 break;
oscarmtzman 4:a6130c61c228 379 case 1024:
oscarmtzman 4:a6130c61c228 380 S = & arm_cfft_sR_f32_len1024;
oscarmtzman 4:a6130c61c228 381 break;
oscarmtzman 4:a6130c61c228 382 case 2048:
oscarmtzman 4:a6130c61c228 383 S = & arm_cfft_sR_f32_len2048;
oscarmtzman 4:a6130c61c228 384 break;
oscarmtzman 4:a6130c61c228 385 case 4096:
oscarmtzman 4:a6130c61c228 386 S = & arm_cfft_sR_f32_len4096;
oscarmtzman 4:a6130c61c228 387 break;
frankvnk 2:035d551759a5 388 }
frankvnk 2:035d551759a5 389
frankvnk 0:0c037aff5039 390 while(1) {
frankvnk 0:0c037aff5039 391 // Calculate FFT if a full sample is available.
oscarmtzman 7:18e9a56bef9a 392
oscarmtzman 7:18e9a56bef9a 393
oscarmtzman 7:18e9a56bef9a 394 if(abs(fmin+(fmax-fmin)*pot.read()-pulso)>.5) {
oscarmtzman 7:18e9a56bef9a 395 wait(2);
oscarmtzman 7:18e9a56bef9a 396 pulso=fmin+(fmax-fmin)*pot.read();
oscarmtzman 7:18e9a56bef9a 397 pc.printf("\n\n\n%f\n\n\n",pulso);
oscarmtzman 7:18e9a56bef9a 398 l=30/pulso;
oscarmtzman 7:18e9a56bef9a 399 b=(2*l)/0.11;
oscarmtzman 7:18e9a56bef9a 400 qrs1=(a/(2*b))*(2-b);
oscarmtzman 7:18e9a56bef9a 401
oscarmtzman 7:18e9a56bef9a 402 for(int i=1; i<=n; i=i+1) {
oscarmtzman 7:18e9a56bef9a 403 for(int j=0; j<512; j=j+1) {
oscarmtzman 7:18e9a56bef9a 404 harm[j]=(((2*b*a)/(i*i*pi*pi))*(1-cos((i*pi)/b)))*cos((i*pi*(j+1)*ts)/l);
oscarmtzman 7:18e9a56bef9a 405 }
oscarmtzman 7:18e9a56bef9a 406 for(int k=0; k<512; k=k+1) {
oscarmtzman 7:18e9a56bef9a 407 qrs2[k]=qrs2[k]+harm[k];
oscarmtzman 7:18e9a56bef9a 408 }
oscarmtzman 7:18e9a56bef9a 409 }
oscarmtzman 7:18e9a56bef9a 410 // Begin sampling audio
oscarmtzman 7:18e9a56bef9a 411 samplingBegin();
oscarmtzman 7:18e9a56bef9a 412 }
oscarmtzman 7:18e9a56bef9a 413
oscarmtzman 7:18e9a56bef9a 414
frankvnk 0:0c037aff5039 415 if (samplingIsDone()) {
oscarmtzman 4:a6130c61c228 416
oscarmtzman 4:a6130c61c228 417
frankvnk 0:0c037aff5039 418 // Run FFT on sample data.
frankvnk 2:035d551759a5 419 // Run FFT on sample data.
frankvnk 2:035d551759a5 420 arm_cfft_f32(S, samples, 0, 1);
frankvnk 0:0c037aff5039 421 // Calculate magnitude of complex numbers output by the FFT.
frankvnk 0:0c037aff5039 422 arm_cmplx_mag_f32(samples, magnitudes, FFT_SIZE);
oscarmtzman 4:a6130c61c228 423
oscarmtzman 4:a6130c61c228 424
oscarmtzman 7:18e9a56bef9a 425
oscarmtzman 4:a6130c61c228 426 for(int i=1; i<FFT_SIZE/2; i=i+1) {
oscarmtzman 7:18e9a56bef9a 427 if(magnitudes[i]>max&&abs(fs/(FFT_SIZE-1)*i*60-pulso)<8) {
oscarmtzman 4:a6130c61c228 428 max=magnitudes[i];
oscarmtzman 4:a6130c61c228 429 inmax=i;
oscarmtzman 4:a6130c61c228 430 }
oscarmtzman 4:a6130c61c228 431 }
oscarmtzman 4:a6130c61c228 432
oscarmtzman 4:a6130c61c228 433 pulsocalculado=fs/(FFT_SIZE-1)*inmax*60;
oscarmtzman 4:a6130c61c228 434 pc.printf("%f\n",pulsocalculado);
oscarmtzman 7:18e9a56bef9a 435
oscarmtzman 7:18e9a56bef9a 436 if (pulsocalculado<(fmin+sum)) {
oscarmtzman 7:18e9a56bef9a 437 led1=1;
oscarmtzman 7:18e9a56bef9a 438 led2=0;
oscarmtzman 7:18e9a56bef9a 439 led3=0;
oscarmtzman 7:18e9a56bef9a 440 led4=0;
oscarmtzman 7:18e9a56bef9a 441 led5=0;
oscarmtzman 7:18e9a56bef9a 442 led6=0;
oscarmtzman 7:18e9a56bef9a 443 led7=0;
oscarmtzman 7:18e9a56bef9a 444 led8=0;
oscarmtzman 7:18e9a56bef9a 445 }
oscarmtzman 7:18e9a56bef9a 446 if (pulsocalculado>=(fmin+sum)&&pulsocalculado<(fmin+2*sum)) {
oscarmtzman 7:18e9a56bef9a 447 led1=1;
oscarmtzman 7:18e9a56bef9a 448 led2=1;
oscarmtzman 7:18e9a56bef9a 449 led3=0;
oscarmtzman 7:18e9a56bef9a 450 led4=0;
oscarmtzman 7:18e9a56bef9a 451 led5=0;
oscarmtzman 7:18e9a56bef9a 452 led6=0;
oscarmtzman 7:18e9a56bef9a 453 led7=0;
oscarmtzman 7:18e9a56bef9a 454 led8=0;
oscarmtzman 7:18e9a56bef9a 455 }
oscarmtzman 7:18e9a56bef9a 456 if (pulsocalculado>=(fmin+2*sum)&&pulsocalculado<(fmin+3*sum)) {
oscarmtzman 7:18e9a56bef9a 457 led1=1;
oscarmtzman 7:18e9a56bef9a 458 led2=1;
oscarmtzman 7:18e9a56bef9a 459 led3=1;
oscarmtzman 7:18e9a56bef9a 460 led4=0;
oscarmtzman 7:18e9a56bef9a 461 led5=0;
oscarmtzman 7:18e9a56bef9a 462 led6=0;
oscarmtzman 7:18e9a56bef9a 463 led7=0;
oscarmtzman 7:18e9a56bef9a 464 led8=0;
oscarmtzman 7:18e9a56bef9a 465 }
oscarmtzman 7:18e9a56bef9a 466 if (pulsocalculado>=(fmin+3*sum)&&pulsocalculado<(fmin+4*sum)) {
oscarmtzman 7:18e9a56bef9a 467 led1=1;
oscarmtzman 7:18e9a56bef9a 468 led2=1;
oscarmtzman 7:18e9a56bef9a 469 led3=1;
oscarmtzman 7:18e9a56bef9a 470 led4=1;
oscarmtzman 7:18e9a56bef9a 471 led5=0;
oscarmtzman 7:18e9a56bef9a 472 led6=0;
oscarmtzman 7:18e9a56bef9a 473 led7=0;
oscarmtzman 7:18e9a56bef9a 474 led8=0;
oscarmtzman 7:18e9a56bef9a 475 }
oscarmtzman 7:18e9a56bef9a 476 if (pulsocalculado>=(fmin+4*sum)&&pulsocalculado<(fmin+5*sum)) {
oscarmtzman 7:18e9a56bef9a 477 led1=1;
oscarmtzman 7:18e9a56bef9a 478 led2=1;
oscarmtzman 7:18e9a56bef9a 479 led3=1;
oscarmtzman 7:18e9a56bef9a 480 led4=1;
oscarmtzman 7:18e9a56bef9a 481 led5=1;
oscarmtzman 7:18e9a56bef9a 482 led6=0;
oscarmtzman 7:18e9a56bef9a 483 led7=0;
oscarmtzman 7:18e9a56bef9a 484 led8=0;
oscarmtzman 7:18e9a56bef9a 485 }
oscarmtzman 7:18e9a56bef9a 486 if (pulsocalculado>=(fmin+5*sum)&&pulsocalculado<(fmin+6*sum)) {
oscarmtzman 7:18e9a56bef9a 487 led1=1;
oscarmtzman 7:18e9a56bef9a 488 led2=1;
oscarmtzman 7:18e9a56bef9a 489 led3=1;
oscarmtzman 7:18e9a56bef9a 490 led4=1;
oscarmtzman 7:18e9a56bef9a 491 led5=1;
oscarmtzman 7:18e9a56bef9a 492 led6=1;
oscarmtzman 7:18e9a56bef9a 493 led7=0;
oscarmtzman 7:18e9a56bef9a 494 led8=0;
oscarmtzman 7:18e9a56bef9a 495 }
oscarmtzman 7:18e9a56bef9a 496 if (pulsocalculado>=(fmin+6*sum)&&pulsocalculado<(fmin+7*sum)) {
oscarmtzman 7:18e9a56bef9a 497 led1=1;
oscarmtzman 7:18e9a56bef9a 498 led2=1;
oscarmtzman 7:18e9a56bef9a 499 led3=1;
oscarmtzman 7:18e9a56bef9a 500 led4=1;
oscarmtzman 7:18e9a56bef9a 501 led5=1;
oscarmtzman 7:18e9a56bef9a 502 led6=1;
oscarmtzman 7:18e9a56bef9a 503 led7=1;
oscarmtzman 7:18e9a56bef9a 504 led8=0;
oscarmtzman 7:18e9a56bef9a 505 }
oscarmtzman 7:18e9a56bef9a 506 if (pulsocalculado>=(fmin+7*sum)) {
oscarmtzman 7:18e9a56bef9a 507 led1=1;
oscarmtzman 7:18e9a56bef9a 508 led2=1;
oscarmtzman 7:18e9a56bef9a 509 led3=1;
oscarmtzman 7:18e9a56bef9a 510 led4=1;
oscarmtzman 7:18e9a56bef9a 511 led5=1;
oscarmtzman 7:18e9a56bef9a 512 led6=1;
oscarmtzman 7:18e9a56bef9a 513 led7=1;
oscarmtzman 7:18e9a56bef9a 514 led8=1;
oscarmtzman 7:18e9a56bef9a 515 }
oscarmtzman 7:18e9a56bef9a 516
oscarmtzman 4:a6130c61c228 517 inmax=0;
oscarmtzman 7:18e9a56bef9a 518 max=0;
frankvnk 0:0c037aff5039 519
frankvnk 0:0c037aff5039 520 if (LEDS_ENABLED == 1) {
frankvnk 0:0c037aff5039 521 spectrumLoop();
frankvnk 0:0c037aff5039 522 }
frankvnk 0:0c037aff5039 523
frankvnk 0:0c037aff5039 524 // Restart audio sampling.
frankvnk 0:0c037aff5039 525 samplingBegin();
frankvnk 0:0c037aff5039 526 }
frankvnk 0:0c037aff5039 527
frankvnk 0:0c037aff5039 528 // Parse any pending commands.
frankvnk 0:0c037aff5039 529 if(commandRecv) {
frankvnk 0:0c037aff5039 530 // pc.attach(NULL);
frankvnk 0:0c037aff5039 531 parseCommand(commandBuffer);
frankvnk 0:0c037aff5039 532 commandRecv = 0;
frankvnk 0:0c037aff5039 533 // Clear the input buffer
frankvnk 0:0c037aff5039 534 memset(commandBuffer, 0, sizeof(commandBuffer));
frankvnk 0:0c037aff5039 535 // pc.attach(&rxisr);
frankvnk 0:0c037aff5039 536 }
frankvnk 0:0c037aff5039 537 }
frankvnk 0:0c037aff5039 538 }