FFT using CMSIS for non mbed-os for smaller capacity chips with DAC output e.g. F303K8 to display FFT to an Oscilloscope with example to send to MAX7219 LED Array
Dependencies: MAX7219 mbed-dsp mbed
main.cpp
- Committer:
- martinsimpson
- Date:
- 2018-04-13
- Revision:
- 0:6daa40cd81ec
File content as of revision 0:6daa40cd81ec:
#include "mbed.h" /*ADAFruit 8x8 LED Array driver chip SPI */ #include "max7219.h" /* Include arm_math.h mathematic functions */ #include "arm_math.h" /* Include mbed-dsp libraries */ #include "arm_common_tables.h" #include "arm_const_structs.h" #include "math_helper.h" /* FFT settings */ #define SAMPLES 512 /* 256 real party and 256 imaginary parts */ #define FFT_SIZE SAMPLES / 2 /* FFT size is always the same size as we have samples, so 256 in our case */ /* Global variables */ float32_t Input[SAMPLES]; float32_t sampler[SAMPLES]={0}; float32_t Output[FFT_SIZE]; bool trig=0; /*Function Prototypes */ uint16_t convert_bar(uint16_t); void sample(); /* MBED class APIs */ DigitalOut myled(LED1); AnalogIn myADC(A1); AnalogOut myDAC(A3); Ticker timer; /* Other class APIs */ Max7219 max7219(D11, D12, D13, D10);//SPI0_MOSI, SPI0_MISO, SPI0_SCK, SPI0_SS); void sample(){ trig=1; } int main() { uint8_t array[]={0x1F,0x14,0x10,0x00,0x1F,0x14,0x10,0x00,0x10,0x1F,0x10}; //text 'FFT' uint16_t array_size=sizeof(array); int16_t i,j; float maxValue; // Max FFT value is stored here uint32_t maxIndex; // Index in Output array where max value is printf("FFT Example using 32F303K8 DAC output\r\n"); max7219_configuration_t cfg = { .device_number = 1, .decode_mode = 0, .intensity = Max7219::MAX7219_INTENSITY_4, .scan_limit = Max7219::MAX7219_SCAN_8 }; max7219.init_device(cfg); max7219.enable_device(1); max7219.set_display_test(); max7219.clear_display_test(); max7219.display_all_off(); for(j=-8;j<=array_size;j++){ for(i=1;i<=array_size;i++){ max7219.write_digit(1,9-i+j,array[i-1]); } wait_ms(100); max7219.display_all_off(); } //arm_cfft_instance_f32 S; // ARM CFFT module //float maxValue; // Max FFT value is stored here //uint32_t maxIndex; // Index in Output array where max value is while(1) { timer.attach_us(&sample,30); //30us 30,30 250KHz sampling rate ******** for (i = 0; i < SAMPLES; i += 2) { while (trig==0){} trig=0; Input[i] = myADC.read() - 0.5f; //Real part NB removing DC offset Input[i + 1] = 0; //Imaginary Part set to zero } timer.detach(); // Init the Complex FFT module, intFlag = 0, doBitReverse = 1 // NB using predefined arm_cfft_sR_f32_lenXXX, in this case XXX is 256 arm_cfft_f32(&arm_cfft_sR_f32_len256, Input, 0, 1); // Complex Magniture Module put results into Output(Half size of the Input) arm_cmplx_mag_f32(Input, Output, FFT_SIZE); Output[0]=0; //Calculates maxValue and returns corresponding value arm_max_f32(Output, FFT_SIZE, &maxValue, &maxIndex); myDAC=1.0f; //SYNC here!! for Oscillscope at max DAC output for triggering purposes wait_us(20);//All FFT values will be lower since max scaling is 0.9 as below myDAC=0.0f;//set trigger level on oscilloscope between 0.9 to 1.0 (*3.3Volts) i.e. 3.0 to 3.3Volts for (i=2; i<FFT_SIZE/2 ; i++){ myDAC=(Output[i]/maxValue)*0.9f; // All Values scaled to 0.0 to 0.9 for output to DAC // if (Output[i]>0.2){printf("%d %f\r\n",i,(Output[i]/maxValue)*0.9f);} wait_us(10); } myDAC=0.0f; for (i=0; i<9;i++){ max7219.write_digit(1,9-i,convert_bar((uint16_t)(Output[i*16]*2.9f)));// 5.8f } } } // Will take a number (numVal) 0 to 255 and return (converted) the next (lower) 2^n-1 value // to light up all LEDS as a bar graph representation uint16_t convert_bar(uint16_t numVal){ if (numVal>255){return 0;} uint16_t converted = 0; for (uint16_t i=1; i<=256 ; i*=2){ if ((numVal/(i)) >= 1){converted = (i-1);} } return converted; }