Working code for pc app 12/01/2018 commit

Dependencies:   mbed MS5607 mbed-dsp

Fork of Turrentine_Code by Alex Stokoe

Committer:
AlexStokoe
Date:
Wed Feb 14 10:40:30 2018 +0000
Revision:
9:28366bbbb13a
Parent:
8:206c2ae7f49f
Release to MSA 1.1

Who changed what in which revision?

UserRevisionLine numberNew contents of line
AlexStokoe 0:2c6d81be69d8 1 #include "mbed.h"
intrinseca 3:c80aa39db5bb 2 #include "MS5607SPI.h"
intrinseca 3:c80aa39db5bb 3 #include "arm_math.h"
AlexStokoe 0:2c6d81be69d8 4
AlexStokoe 0:2c6d81be69d8 5 #define M_PI 3.14159265358979323846
AlexStokoe 0:2c6d81be69d8 6
intrinseca 2:3d3e21c907e4 7 #define N_SAMPLES 1024
intrinseca 1:ab3dacbfcde6 8
intrinseca 4:d4804771134a 9 #define PEAK_SEARCH_START 1 //first bin to include in peak search
intrinseca 4:d4804771134a 10 #define PEAK_SEARCH_END 50 //last bin to include in peak search
intrinseca 4:d4804771134a 11 #define SUM_AROUND_PEAK 1 //+/- this many bins
intrinseca 4:d4804771134a 12
intrinseca 4:d4804771134a 13 #define REGRESSION_SLOPE 53.77986f //from Excel fit to test data
intrinseca 4:d4804771134a 14 #define REGRESSION_INTERCEPT -80.07f
intrinseca 4:d4804771134a 15
intrinseca 5:44cfc3e81d1c 16 float thresholds[] = {0.f, 10.f, 30.f, 50.f, 70.f}; //estimated t90 thresholds to turn on LEDs
intrinseca 4:d4804771134a 17
AlexStokoe 0:2c6d81be69d8 18 //mbed class def
AlexStokoe 0:2c6d81be69d8 19 Serial pc(USBTX, USBRX); // tx, rx
intrinseca 3:c80aa39db5bb 20 MS5607SPI pressure_sensor(p5, p6, p7, p8); // mosi, miso, sclk, cs
AlexStokoe 0:2c6d81be69d8 21
intrinseca 5:44cfc3e81d1c 22 #define N_LEDS 4
intrinseca 5:44cfc3e81d1c 23 PwmOut leds[N_LEDS] = {LED1, LED2, LED3, LED4};
AlexStokoe 0:2c6d81be69d8 24
intrinseca 5:44cfc3e81d1c 25 DigitalOut motor(p26);
AlexStokoe 0:2c6d81be69d8 26
intrinseca 3:c80aa39db5bb 27 Timer sample_timer;
intrinseca 3:c80aa39db5bb 28 Timer iter_timer;
AlexStokoe 0:2c6d81be69d8 29
intrinseca 3:c80aa39db5bb 30 float p_data[N_SAMPLES];
intrinseca 3:c80aa39db5bb 31 float p_data_raw[N_SAMPLES];
intrinseca 3:c80aa39db5bb 32 float f_data[N_SAMPLES];
intrinseca 3:c80aa39db5bb 33 float mag_data[N_SAMPLES / 2 + 1];
AlexStokoe 0:2c6d81be69d8 34
intrinseca 1:ab3dacbfcde6 35 unsigned int tData[N_SAMPLES];
AlexStokoe 0:2c6d81be69d8 36
intrinseca 3:c80aa39db5bb 37 arm_rfft_fast_instance_f32 rfft;
AlexStokoe 0:2c6d81be69d8 38
AlexStokoe 0:2c6d81be69d8 39 float duty = 1;
AlexStokoe 9:28366bbbb13a 40 float sampleRate;
AlexStokoe 0:2c6d81be69d8 41
AlexStokoe 0:2c6d81be69d8 42 int round(float number)
AlexStokoe 0:2c6d81be69d8 43 {
AlexStokoe 0:2c6d81be69d8 44 return (number >= 0) ? (int)(number + 0.5) : (int)(number - 0.5);
AlexStokoe 0:2c6d81be69d8 45 }
AlexStokoe 0:2c6d81be69d8 46
intrinseca 1:ab3dacbfcde6 47 int main()
intrinseca 1:ab3dacbfcde6 48 {
intrinseca 3:c80aa39db5bb 49 printf("Turrentine\n");
intrinseca 3:c80aa39db5bb 50
intrinseca 3:c80aa39db5bb 51 //Configure PC serial link
AlexStokoe 0:2c6d81be69d8 52 pc.baud(115200);
intrinseca 3:c80aa39db5bb 53
intrinseca 3:c80aa39db5bb 54 //Configure motor PWM
intrinseca 3:c80aa39db5bb 55 motor = 0;
intrinseca 2:3d3e21c907e4 56
intrinseca 2:3d3e21c907e4 57 printf("Pump On\n");
intrinseca 2:3d3e21c907e4 58 //turn pump on
intrinseca 5:44cfc3e81d1c 59 motor = duty;
intrinseca 2:3d3e21c907e4 60
intrinseca 1:ab3dacbfcde6 61 printf("Start loop\n");
intrinseca 3:c80aa39db5bb 62 int iter_counter = 0; //Iteration counter
intrinseca 3:c80aa39db5bb 63 iter_timer.start();
AlexStokoe 7:1a4bbff83b4d 64 float temperature_raw = pressure_sensor.getRawTemperature();
intrinseca 4:d4804771134a 65 printf("fsmpl titer mean_press fmax sum_peak t90\n");
AlexStokoe 8:206c2ae7f49f 66 int a = 0;
intrinseca 3:c80aa39db5bb 67 //program loop
intrinseca 3:c80aa39db5bb 68 while(1) {
AlexStokoe 7:1a4bbff83b4d 69 temperature_raw = pressure_sensor.getRawTemperature();
AlexStokoe 7:1a4bbff83b4d 70
AlexStokoe 8:206c2ae7f49f 71 while (a<2000){
AlexStokoe 8:206c2ae7f49f 72 pressure_sensor.getRawPressure();
AlexStokoe 8:206c2ae7f49f 73 a++;
AlexStokoe 8:206c2ae7f49f 74 }
AlexStokoe 8:206c2ae7f49f 75 a = 0;
intrinseca 3:c80aa39db5bb 76 sample_timer.reset();
intrinseca 3:c80aa39db5bb 77 sample_timer.start();
AlexStokoe 8:206c2ae7f49f 78
intrinseca 3:c80aa39db5bb 79 //Capture raw pressure samples
intrinseca 1:ab3dacbfcde6 80 for(int i = 0; i < N_SAMPLES; i++) {
intrinseca 3:c80aa39db5bb 81 p_data_raw[i] = pressure_sensor.calculatePressure(pressure_sensor.getRawPressure(), temperature_raw);
intrinseca 3:c80aa39db5bb 82 p_data[i] = p_data_raw[i];
intrinseca 1:ab3dacbfcde6 83 }
intrinseca 3:c80aa39db5bb 84
intrinseca 3:c80aa39db5bb 85 sample_timer.stop();
AlexStokoe 8:206c2ae7f49f 86
AlexStokoe 7:1a4bbff83b4d 87 //Output raw data
AlexStokoe 7:1a4bbff83b4d 88 printf("$RAW\n");
AlexStokoe 7:1a4bbff83b4d 89 for(int i = 0; i < N_SAMPLES; i++) {
AlexStokoe 7:1a4bbff83b4d 90 printf("$%f\n", p_data_raw[i]);
AlexStokoe 7:1a4bbff83b4d 91 //pressure_sensor.calculatePressure(pressure_sensor.getRawPressure(), temperature_raw);
AlexStokoe 7:1a4bbff83b4d 92 }
AlexStokoe 7:1a4bbff83b4d 93 printf("$ENDRAW\n");
AlexStokoe 8:206c2ae7f49f 94
intrinseca 3:c80aa39db5bb 95 //http://www.keil.com/pack/doc/CMSIS/DSP/html/group__RealFFT.html
intrinseca 3:c80aa39db5bb 96 //Compute the RFFT
intrinseca 3:c80aa39db5bb 97 //
intrinseca 3:c80aa39db5bb 98 //p_data is trashed in the process
intrinseca 3:c80aa39db5bb 99 //Result is packaged as [real_0, real_N/2, real_1, imag_1, real_2, imag_2 ... real_N/2-1, imag_N/2-1]
intrinseca 3:c80aa39db5bb 100 arm_rfft_fast_init_f32(&rfft, N_SAMPLES);
intrinseca 3:c80aa39db5bb 101 arm_rfft_fast_f32(&rfft, p_data, f_data, 0);
intrinseca 3:c80aa39db5bb 102
intrinseca 3:c80aa39db5bb 103 //http://www.keil.com/pack/doc/CMSIS/DSP/html/group__cmplx__mag.html
intrinseca 3:c80aa39db5bb 104 //Convert to magntiude, skip over the DC and fundamental terms
intrinseca 3:c80aa39db5bb 105
intrinseca 3:c80aa39db5bb 106 arm_cmplx_mag_f32(&f_data[2], &mag_data[1], (N_SAMPLES / 2) - 1);
intrinseca 3:c80aa39db5bb 107 //Fill in the first and last terms from the first entry in f_data
intrinseca 3:c80aa39db5bb 108 mag_data[0] = f_data[0];
intrinseca 3:c80aa39db5bb 109 mag_data[N_SAMPLES / 2] = f_data[1];
intrinseca 3:c80aa39db5bb 110
intrinseca 3:c80aa39db5bb 111
intrinseca 3:c80aa39db5bb 112
intrinseca 4:d4804771134a 113 //Find peak in spectrum
intrinseca 4:d4804771134a 114 float max_mag = -1;
intrinseca 4:d4804771134a 115 int max_mag_i = -1;
intrinseca 4:d4804771134a 116 for(int i = PEAK_SEARCH_START + SUM_AROUND_PEAK; i < PEAK_SEARCH_END; i++){
intrinseca 4:d4804771134a 117 //printf("%10f ", mag_data[i]);
intrinseca 4:d4804771134a 118 if(mag_data[i] > max_mag) {
intrinseca 4:d4804771134a 119 max_mag_i = i;
intrinseca 4:d4804771134a 120 max_mag = mag_data[i];
intrinseca 4:d4804771134a 121 }
intrinseca 4:d4804771134a 122 }
intrinseca 4:d4804771134a 123 //printf("\n");
intrinseca 4:d4804771134a 124
intrinseca 4:d4804771134a 125 //Sum surrounding
intrinseca 4:d4804771134a 126 float sum = 0.f;
intrinseca 4:d4804771134a 127 for(int i = max_mag_i - SUM_AROUND_PEAK; i < (max_mag_i + SUM_AROUND_PEAK + 1); i++) {
intrinseca 4:d4804771134a 128 sum += mag_data[i];
intrinseca 4:d4804771134a 129 //printf("%10f ", mag_data[i]);
intrinseca 1:ab3dacbfcde6 130 }
intrinseca 3:c80aa39db5bb 131
intrinseca 4:d4804771134a 132 //printf("\n");
intrinseca 4:d4804771134a 133
intrinseca 4:d4804771134a 134 //Scale by N_SAMPLES to recover pressure in Pa
intrinseca 4:d4804771134a 135 sum /= N_SAMPLES;
intrinseca 4:d4804771134a 136
intrinseca 4:d4804771134a 137 //Apply inverse of logarithmic regression from test data
intrinseca 4:d4804771134a 138 float t90 = exp((sum + 80.07) / 53.77986);
intrinseca 4:d4804771134a 139
intrinseca 4:d4804771134a 140
intrinseca 4:d4804771134a 141 //Output iteration data
intrinseca 4:d4804771134a 142 iter_counter++;
AlexStokoe 9:28366bbbb13a 143 sampleRate = 1000000 / (sample_timer.read_us() / N_SAMPLES);
AlexStokoe 9:28366bbbb13a 144 printf("$DATA %.2f,%.2f,%.1f,%.1f,%1.5e,%.1f\n", iter_timer.read(), sampleRate , f_data[0] / N_SAMPLES, (max_mag_i * sampleRate / N_SAMPLES), sum, t90);
intrinseca 3:c80aa39db5bb 145
intrinseca 3:c80aa39db5bb 146 //Set LEDs based on thresholds
intrinseca 5:44cfc3e81d1c 147 for(int i = 0; i < N_LEDS; i++) {
intrinseca 5:44cfc3e81d1c 148 leds[i] = 0;
intrinseca 5:44cfc3e81d1c 149
intrinseca 5:44cfc3e81d1c 150 if(t90 >= thresholds[i + 1]) {
intrinseca 5:44cfc3e81d1c 151 leds[i] = 1;
intrinseca 5:44cfc3e81d1c 152 } else if(i < (N_LEDS - 1)) {
intrinseca 5:44cfc3e81d1c 153 leds[i] = (t90 - thresholds[i]) / (thresholds[i + 1] - thresholds[i]);
intrinseca 5:44cfc3e81d1c 154 }
intrinseca 4:d4804771134a 155 }
intrinseca 3:c80aa39db5bb 156
intrinseca 3:c80aa39db5bb 157 //break;
intrinseca 1:ab3dacbfcde6 158 }
AlexStokoe 0:2c6d81be69d8 159 }