Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: mbed
Fork of modular_signal_processing by
Diff: main.cpp
- Revision:
- 0:3ff1d169670e
- Child:
- 1:4351b05b1685
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Thu Feb 15 20:27:50 2018 +0000 @@ -0,0 +1,197 @@ +#include "mbed.h" + +DigitalOut pulse(LED1); + +bool dataReady = false; //Data ready to be processed flag +bool intialised = false; //Setup during first two pulses +bool triggered = false //Represntative if rising edge has been detected + +//Constants +int const AVG_LEN = 160; //Lenght of Avg length buffer +int const BUFF_LEN = 20; //Length of sample buffer +int const ALPHA = 0.5; //Aplha value used for filtering +int const OFFSET = 0.2; //Used to ensure normalised values don't be come negative + +//Buffers +float sample_buffer[BUFF_LEN] = {}; //Circular array storing values from sample interupt +//float local_buffer[BUFF_LEN] = {}; +float avg_buffer[AVG_LEN] = {}; //circular array containing most recent 160 values + +//Averageing values +float running_avg_sum = 0; //Sum of most recent 160 values +float running_avg; //Sum of most recent 160 values (two pulses) + +//Sample Buffer pointers +int read = 0; +int write = 0; +//int counter = 0; //Keeps track of number of data values read in + +//Avg buffer pointer +int avg_write = 0; + +//Running max and min +float max; +float min; + +Ticker sampler; + + +void sampling () //Sample Signal +{ + float sample = Ain.read(); + sample_buffer[write++] = sample; + write = write%(BUFF_LEN); //Ensure buffer pointer rolls over i.e circular buffer + count ++ + + //if (count = 10) { + dataReady = true; + //count = 0; + //} + +float intial_min() //Get min value of first two pulses data +{ + int min = avg_buffer[0]; + for (int i = 0; i < AVG_LEN; i++) { + if (avg_buffer[i] < min) { + min = avg_buffer[i]; + } + } + return min; +} + +float inital_max() //Get max value of first two pulse data +{ + int max = avg_buffer[0]; + for (int i = 0; i < AVG_LEN; i++) { + if (avg_buffer[i] > max) { + max = avg_buffer[i]; + } + } + return max; +} + +float normalise(float data) { //Centralise data + // Implement scaling later + return (point/max-min) +} + +float filter(float data, float normalised) { //Digital low plasss filter + return data*alpha + (1-alpha)*normalisedData; // X = alpha*x + (1-alpha)prevX + +float average (float data) { //Calcualte new average and remove value from signal + if (!initialised) { // Gathering data for first two intial pulses + avg_buffer[avg_write++] = data; + avg_write = (avg_write) % AVG_LEN; //Ensure avg_write pointer wraps around + avg_sum += data; //Update running sum + } + + if (avg_write == 0) { //First 160 values have been added to buffer + first = false; + + //Get inital min and max + max = inital_max(); + min = inital_min(); + + } + + return 0.0; + } + else { //Main runtime of program + int old_data = avg_buffer[avg_write]; // oldest value + avg_buffer[avg_write] = data; // over write oldest value with new data + avg_sum = avg_sum - old_data + data; //Update running sum to contain most recent 160 values + + avg_write%AVG_LEN; //Ensure avg_write wraps around + + if (avg_write == 1) { //160 new values have been added to buffer + + //Get reinitalise min and max + max = inital_max(); + min = inital_min(); + } + + + //Otherwise Check if new data sets new max + else if (data > max) { + max = data; + } + + //Or check if new data sets new max + else if (data < min) { + min = data; + + + } + + return data - avg_sum/AVG_LEN + OFFSET; //Remove trendline + } +} + +float processData(float data, float normalisedData) { //Normalise and filter signal + float processing, processed; + processing = average(data); //Remove runnning average + processing = filter(processing, normalisedData); //Low pass filter signal + processed = normalise(processing) //Normalise as per formula + return processed; +} + +bool above_trig_low(float point) //Check if data goes below low trigger +{ + if(point <= trigger_low) { + triggered = false; + return true; + } + return false; +} + +bool above_trig_high(float point) //Check if data goes above high trigger +{ + if(point >= trigger_high) { + trigger = true; + return true; + } + return false; +} + +void detectPulse(float normalisedData) //Turn on LED during high part of pulse +{ + // Implementation of hysteresis + if(triggered) { + if (above_trig_low(normalisedData)) { + led = 0; + } else { + led = 1; + } + } else if (!triggered) { + if (above_trig_high(normalisedData)) { + led = 1; + } else { + led = 0; + } + } +} + +int main() { + sampler.attach(&sampling, 0.0125); //Sample at 80Hz + float normalisedData = 0; //Data point which has been normalised + + while(1) { + if(dataReady) { //If more data has been sampled + + //int local_write = write //Store local pointer for write pointer + + while(read != write) { //While there is data left in sample buffer + data = sample_buffer[read++]; + read = read%BUFF_LEN; //Ensure read pointer rolls around in sample buffer + normalisedData = processData(data, normalisedData); + + if(intialised) { //Passed first two pulse + detectPulse(normalisedData) + } + } + + dataReady = false; + } + + //Implement write to display +}