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

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 #include "mbed.h"
00002 /*ADAFruit 8x8 LED Array driver chip SPI */
00003 #include "max7219.h"
00004 /* Include arm_math.h mathematic functions */
00005 #include "arm_math.h"
00006 /* Include mbed-dsp libraries */
00007 #include "arm_common_tables.h"
00008 #include "arm_const_structs.h"
00009 #include "math_helper.h"
00010 
00011 /* FFT settings */
00012 #define SAMPLES                 512             /* 256 real party and 256 imaginary parts */
00013 #define FFT_SIZE                SAMPLES / 2     /* FFT size is always the same size as we have samples, so 256 in our case */
00014 
00015 /* Global variables */
00016 float32_t Input[SAMPLES];
00017 float32_t sampler[SAMPLES]={0};
00018 float32_t Output[FFT_SIZE];
00019 bool      trig=0;
00020 
00021 /*Function Prototypes */
00022 uint16_t convert_bar(uint16_t);
00023 void sample();
00024 
00025 /* MBED class APIs */
00026 DigitalOut myled(LED1);
00027 AnalogIn   myADC(A1);
00028 AnalogOut  myDAC(A3);
00029 Ticker     timer;
00030 
00031 /* Other class APIs */
00032 Max7219 max7219(D11, D12, D13, D10);//SPI0_MOSI, SPI0_MISO, SPI0_SCK, SPI0_SS);
00033 
00034 void sample(){
00035     trig=1;
00036     }
00037     
00038 int main() {
00039 
00040     uint8_t  array[]={0x1F,0x14,0x10,0x00,0x1F,0x14,0x10,0x00,0x10,0x1F,0x10}; //text 'FFT'
00041     uint16_t array_size=sizeof(array);
00042     int16_t  i,j;
00043     float maxValue;            // Max FFT value is stored here
00044     uint32_t maxIndex;         // Index in Output array where max value is
00045     
00046     printf("FFT Example using 32F303K8 DAC output\r\n");
00047     
00048     max7219_configuration_t cfg = {
00049          .device_number = 1,
00050          .decode_mode = 0,
00051          .intensity = Max7219::MAX7219_INTENSITY_4,
00052          .scan_limit = Max7219::MAX7219_SCAN_8
00053      };
00054 
00055      max7219.init_device(cfg);
00056      max7219.enable_device(1);
00057      max7219.set_display_test();
00058      max7219.clear_display_test();
00059      max7219.display_all_off();
00060    
00061      for(j=-8;j<=array_size;j++){
00062         for(i=1;i<=array_size;i++){
00063             max7219.write_digit(1,9-i+j,array[i-1]);
00064         }
00065         wait_ms(100);
00066         max7219.display_all_off();
00067      }
00068 
00069     //arm_cfft_instance_f32 S;   // ARM CFFT module
00070     //float maxValue;            // Max FFT value is stored here
00071     //uint32_t maxIndex;         // Index in Output array where max value is
00072     
00073     while(1) {
00074             timer.attach_us(&sample,30); //30us 30,30 250KHz sampling rate ********
00075 
00076             for (i = 0; i < SAMPLES; i += 2) {
00077                 while (trig==0){}
00078                 trig=0;  
00079                 Input[i] = myADC.read() - 0.5f; //Real part NB removing DC offset
00080                 Input[i + 1] = 0;               //Imaginary Part set to zero
00081             }
00082             timer.detach();
00083             // Init the Complex FFT module, intFlag = 0, doBitReverse = 1
00084             // NB using predefined arm_cfft_sR_f32_lenXXX, in this case XXX is 256
00085             arm_cfft_f32(&arm_cfft_sR_f32_len256, Input, 0, 1);
00086 
00087             // Complex Magniture Module put results into Output(Half size of the Input)
00088             arm_cmplx_mag_f32(Input, Output, FFT_SIZE);
00089         
00090         Output[0]=0;
00091         
00092         
00093             //Calculates maxValue and returns corresponding value
00094             arm_max_f32(Output, FFT_SIZE, &maxValue, &maxIndex);
00095             
00096         
00097             myDAC=1.0f; //SYNC here!! for Oscillscope at max DAC output for triggering purposes
00098             wait_us(20);//All FFT values will be lower since max scaling is 0.9 as below
00099             myDAC=0.0f;//set trigger level on oscilloscope between 0.9 to 1.0 (*3.3Volts) i.e. 3.0 to 3.3Volts
00100         
00101             for (i=2; i<FFT_SIZE/2 ; i++){
00102                 myDAC=(Output[i]/maxValue)*0.9f; // All Values scaled to 0.0 to 0.9 for output to DAC
00103             //    if (Output[i]>0.2){printf("%d %f\r\n",i,(Output[i]/maxValue)*0.9f);}
00104                 wait_us(10);
00105             }
00106             myDAC=0.0f;
00107 
00108             for (i=0; i<9;i++){
00109                 max7219.write_digit(1,9-i,convert_bar((uint16_t)(Output[i*16]*2.9f)));//  5.8f
00110             }
00111         }
00112 }
00113 
00114 // Will take a number (numVal) 0 to 255 and return (converted) the next (lower) 2^n-1 value
00115 // to light up all LEDS as a bar graph representation
00116 uint16_t convert_bar(uint16_t numVal){
00117     if (numVal>255){return 0;} 
00118     uint16_t converted = 0;
00119         for (uint16_t i=1; i<=256 ; i*=2){
00120             if ((numVal/(i)) >= 1){converted = (i-1);}
00121             }
00122     return converted;   
00123 }