Team S - EDP 2 / Mbed 2 deprecated modular_signal_processing

Dependencies:   mbed

Fork of modular_signal_processing by Conor Begley

Committer:
2236693B
Date:
Thu Feb 15 20:27:50 2018 +0000
Revision:
0:3ff1d169670e
Child:
1:4351b05b1685
New parameterised signal processing

Who changed what in which revision?

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