Team S - EDP 2 / Mbed 2 deprecated modular_signal_processing

Dependencies:   mbed

Fork of modular_signal_processing by Conor Begley

Committer:
2236693B
Date:
Sat Mar 03 13:35:40 2018 +0000
Revision:
7:cc766c97686a
Parent:
6:9c5c36d2c0e1
Improved readability with comments

Who changed what in which revision?

UserRevisionLine numberNew contents of line
2236693B 0:3ff1d169670e 1 #include "mbed.h"
2236693B 0:3ff1d169670e 2
2236693B 6:9c5c36d2c0e1 3 //Testing
2236693B 6:9c5c36d2c0e1 4 Serial pc (USBTX, USBRX);
2236693B 6:9c5c36d2c0e1 5
2236693B 0:3ff1d169670e 6 DigitalOut pulse(LED1);
2236693B 2:319575416324 7 AnalogIn Ain(PTB1);
2236693B 2:319575416324 8 AnalogOut Aout(PTE30);
2236693B 0:3ff1d169670e 9
2236693B 0:3ff1d169670e 10 bool dataReady = false; //Data ready to be processed flag
2236693B 0:3ff1d169670e 11 bool intialised = false; //Setup during first two pulses
2236693B 2:319575416324 12 bool triggered = false ; //Represntative if rising edge has been detected
2236693B 0:3ff1d169670e 13
2236693B 0:3ff1d169670e 14 //Constants
2236693B 0:3ff1d169670e 15 int const AVG_LEN = 160; //Lenght of Avg length buffer
2236693B 0:3ff1d169670e 16 int const BUFF_LEN = 20; //Length of sample buffer
2236693B 6:9c5c36d2c0e1 17 float const ALPHA = 0.5; //Aplha value used for filtering
2236693B 6:9c5c36d2c0e1 18 float const OFFSET = 0.2; //Used to ensure normalised values don't be come negative
2236693B 6:9c5c36d2c0e1 19 float const trigger_high = 0.21;
2236693B 6:9c5c36d2c0e1 20 float const trigger_low = 0.19;
2236693B 0:3ff1d169670e 21
2236693B 0:3ff1d169670e 22 //Buffers
2236693B 0:3ff1d169670e 23 float sample_buffer[BUFF_LEN] = {}; //Circular array storing values from sample interupt
2236693B 0:3ff1d169670e 24 //float local_buffer[BUFF_LEN] = {};
2236693B 0:3ff1d169670e 25 float avg_buffer[AVG_LEN] = {}; //circular array containing most recent 160 values
2236693B 0:3ff1d169670e 26
2236693B 0:3ff1d169670e 27 //Averageing values
2236693B 2:319575416324 28 float avg_sum = 0; //Sum of most recent 160 values
2236693B 0:3ff1d169670e 29
2236693B 0:3ff1d169670e 30 //Sample Buffer pointers
2236693B 0:3ff1d169670e 31 int read = 0;
2236693B 0:3ff1d169670e 32 int write = 0;
2236693B 0:3ff1d169670e 33 //int counter = 0; //Keeps track of number of data values read in
2236693B 0:3ff1d169670e 34
2236693B 0:3ff1d169670e 35 //Avg buffer pointer
2236693B 0:3ff1d169670e 36 int avg_write = 0;
2236693B 0:3ff1d169670e 37
2236693B 0:3ff1d169670e 38 //Running max and min
2236693B 0:3ff1d169670e 39 float max;
2236693B 0:3ff1d169670e 40 float min;
2236693B 0:3ff1d169670e 41
2236693B 0:3ff1d169670e 42 Ticker sampler;
2236693B 0:3ff1d169670e 43
2236693B 0:3ff1d169670e 44
2236693B 0:3ff1d169670e 45 void sampling () //Sample Signal
2236693B 0:3ff1d169670e 46 {
2236693B 0:3ff1d169670e 47 float sample = Ain.read();
2236693B 0:3ff1d169670e 48 sample_buffer[write++] = sample;
2236693B 0:3ff1d169670e 49 write = write%(BUFF_LEN); //Ensure buffer pointer rolls over i.e circular buffer
2236693B 2:319575416324 50 //count ++;
2236693B 2:319575416324 51
2236693B 0:3ff1d169670e 52 //if (count = 10) {
2236693B 2:319575416324 53 dataReady = true;
2236693B 2:319575416324 54 //count = 0;
2236693B 0:3ff1d169670e 55 //}
2236693B 2:319575416324 56 }
2236693B 2:319575416324 57
2236693B 7:cc766c97686a 58 float Min() //Get min value of two pulses data
2236693B 0:3ff1d169670e 59 {
2236693B 0:3ff1d169670e 60 int min = avg_buffer[0];
2236693B 0:3ff1d169670e 61 for (int i = 0; i < AVG_LEN; i++) {
2236693B 0:3ff1d169670e 62 if (avg_buffer[i] < min) {
2236693B 0:3ff1d169670e 63 min = avg_buffer[i];
2236693B 0:3ff1d169670e 64 }
2236693B 0:3ff1d169670e 65 }
2236693B 0:3ff1d169670e 66 return min;
2236693B 0:3ff1d169670e 67 }
2236693B 0:3ff1d169670e 68
2236693B 7:cc766c97686a 69 float Max() //Get max value of two pulse data
2236693B 0:3ff1d169670e 70 {
2236693B 0:3ff1d169670e 71 int max = avg_buffer[0];
2236693B 0:3ff1d169670e 72 for (int i = 0; i < AVG_LEN; i++) {
2236693B 0:3ff1d169670e 73 if (avg_buffer[i] > max) {
2236693B 0:3ff1d169670e 74 max = avg_buffer[i];
2236693B 0:3ff1d169670e 75 }
2236693B 0:3ff1d169670e 76 }
2236693B 0:3ff1d169670e 77 return max;
2236693B 0:3ff1d169670e 78 }
2236693B 2:319575416324 79
2236693B 2:319575416324 80 float normalise(float data) //Centralise data
2236693B 2:319575416324 81 {
2236693B 0:3ff1d169670e 82 // Implement scaling later
2236693B 2:319575416324 83 return (data/max-min);
2236693B 2:319575416324 84 }
2236693B 0:3ff1d169670e 85
2236693B 2:319575416324 86 float filter(float data, float normalisedData) //Digital low plasss filter
2236693B 2:319575416324 87 {
2236693B 2:319575416324 88 return data*ALPHA + (1-ALPHA)*normalisedData; // X = alpha*x + (1-alpha)prevX
2236693B 2:319575416324 89 }
2236693B 2:319575416324 90 float average (float data) //Calcualte new average and remove value from signal
2236693B 2:319575416324 91 {
2236693B 2:319575416324 92 if (!intialised) { // Gathering data for first two intial pulses
2236693B 2:319575416324 93 avg_buffer[avg_write++] = data;
2236693B 2:319575416324 94 avg_write = (avg_write) % AVG_LEN; //Ensure avg_write pointer wraps around
2236693B 2:319575416324 95 avg_sum += data; //Update running sum
2236693B 2:319575416324 96
2236693B 0:3ff1d169670e 97 if (avg_write == 0) { //First 160 values have been added to buffer
2236693B 3:c61f5ff0f916 98 intialised= true;
2236693B 2:319575416324 99
2236693B 0:3ff1d169670e 100 //Get inital min and max
2236693B 7:cc766c97686a 101 max = Max();
2236693B 7:cc766c97686a 102 min = Min();
2236693B 2:319575416324 103
2236693B 0:3ff1d169670e 104 }
2236693B 2:319575416324 105
2236693B 0:3ff1d169670e 106 return 0.0;
2236693B 2:319575416324 107 } else { //Main runtime of program
2236693B 6:9c5c36d2c0e1 108 float old_data = avg_buffer[avg_write]; // oldest value
2236693B 0:3ff1d169670e 109 avg_buffer[avg_write] = data; // over write oldest value with new data
2236693B 2:319575416324 110 avg_sum = avg_sum - old_data + data; //Update running sum to contain most recent 160 values
2236693B 2:319575416324 111
2236693B 2:319575416324 112 avg_write = avg_write%AVG_LEN; //Ensure avg_write wraps around
2236693B 2:319575416324 113
2236693B 7:cc766c97686a 114 max = Max();
2236693B 7:cc766c97686a 115 min = Min();
2236693B 6:9c5c36d2c0e1 116 float trendedData = data - (avg_sum/AVG_LEN);
2236693B 6:9c5c36d2c0e1 117 float offsetData = trendedData+OFFSET;
2236693B 6:9c5c36d2c0e1 118 return offsetData; //Remove trendline
2236693B 0:3ff1d169670e 119 }
2236693B 0:3ff1d169670e 120 }
2236693B 0:3ff1d169670e 121
2236693B 2:319575416324 122 float processData(float data, float normalisedData) //Normalise and filter signal
2236693B 2:319575416324 123 {
2236693B 0:3ff1d169670e 124 float processing, processed;
2236693B 0:3ff1d169670e 125 processing = average(data); //Remove runnning average
2236693B 0:3ff1d169670e 126 processing = filter(processing, normalisedData); //Low pass filter signal
2236693B 6:9c5c36d2c0e1 127 pc.printf("%f \n \r", processing);
2236693B 6:9c5c36d2c0e1 128 Aout.write(processing);
2236693B 6:9c5c36d2c0e1 129 //processed = normalise(processing); //Normalise as per formula
2236693B 6:9c5c36d2c0e1 130 return processing;
2236693B 0:3ff1d169670e 131 }
2236693B 2:319575416324 132
2236693B 5:bbfcd046cd43 133 bool below_trig_low(float point) //Check if data goes below low trigger
2236693B 0:3ff1d169670e 134 {
2236693B 0:3ff1d169670e 135 if(point <= trigger_low) {
2236693B 0:3ff1d169670e 136 return true;
2236693B 0:3ff1d169670e 137 }
2236693B 0:3ff1d169670e 138 return false;
2236693B 0:3ff1d169670e 139 }
2236693B 0:3ff1d169670e 140
2236693B 2:319575416324 141 bool above_trig_high(float point) //Check if data goes above high trigger
2236693B 0:3ff1d169670e 142 {
2236693B 0:3ff1d169670e 143 if(point >= trigger_high) {
2236693B 0:3ff1d169670e 144 return true;
2236693B 0:3ff1d169670e 145 }
2236693B 0:3ff1d169670e 146 return false;
2236693B 0:3ff1d169670e 147 }
2236693B 0:3ff1d169670e 148
2236693B 2:319575416324 149 void detectPulse(float normalisedData) //Turn on LED during high part of pulse
2236693B 0:3ff1d169670e 150 {
2236693B 0:3ff1d169670e 151 // Implementation of hysteresis
2236693B 7:cc766c97686a 152 if(triggered) { //Previously bove high trigger
2236693B 7:cc766c97686a 153 if (below_trig_low(normalisedData)) { //If it drops below ,ow trigger point
2236693B 5:bbfcd046cd43 154 triggered = false;
2236693B 2:319575416324 155 pulse = 0;
2236693B 7:cc766c97686a 156 } else { //Still above low trigger
2236693B 2:319575416324 157 pulse = 1;
2236693B 0:3ff1d169670e 158 }
2236693B 5:bbfcd046cd43 159 }
2236693B 7:cc766c97686a 160 else { //Previously below low trigger
2236693B 7:cc766c97686a 161 if (above_trig_high(normalisedData)) {//If it goes above high trigger point
2236693B 5:bbfcd046cd43 162 triggered = true;
2236693B 2:319575416324 163 pulse = 1;
2236693B 7:cc766c97686a 164 } else { //Still below high trigger
2236693B 2:319575416324 165 pulse = 0;
2236693B 0:3ff1d169670e 166 }
2236693B 0:3ff1d169670e 167 }
2236693B 0:3ff1d169670e 168 }
2236693B 0:3ff1d169670e 169
2236693B 2:319575416324 170 int main()
2236693B 2:319575416324 171 {
2236693B 0:3ff1d169670e 172 sampler.attach(&sampling, 0.0125); //Sample at 80Hz
2236693B 0:3ff1d169670e 173 float normalisedData = 0; //Data point which has been normalised
2236693B 4:bfa5feb61689 174
2236693B 0:3ff1d169670e 175 while(1) {
2236693B 0:3ff1d169670e 176 if(dataReady) { //If more data has been sampled
2236693B 0:3ff1d169670e 177 //int local_write = write //Store local pointer for write pointer
2236693B 2:319575416324 178
2236693B 0:3ff1d169670e 179 while(read != write) { //While there is data left in sample buffer
2236693B 6:9c5c36d2c0e1 180 float data = sample_buffer[read++] ;
2236693B 0:3ff1d169670e 181 read = read%BUFF_LEN; //Ensure read pointer rolls around in sample buffer
2236693B 0:3ff1d169670e 182 normalisedData = processData(data, normalisedData);
2236693B 6:9c5c36d2c0e1 183
2236693B 0:3ff1d169670e 184 if(intialised) { //Passed first two pulse
2236693B 2:319575416324 185 detectPulse(normalisedData);
2236693B 0:3ff1d169670e 186 }
2236693B 0:3ff1d169670e 187 }
2236693B 2:319575416324 188
2236693B 0:3ff1d169670e 189 dataReady = false;
2236693B 2:319575416324 190 }
2236693B 2:319575416324 191
2236693B 2:319575416324 192 //Implement write to display
2236693B 0:3ff1d169670e 193 }
2236693B 0:3ff1d169670e 194 }