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 21:01:54 2018 +0000
Revision:
2:319575416324
Parent:
1:4351b05b1685
Child:
3:c61f5ff0f916
Fixes compile time errors

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