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:41:25 2018 +0000
Revision:
1:4351b05b1685
Parent:
0:3ff1d169670e
Child:
2:319575416324
Fixed trigger points

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