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
main.cpp
- Committer:
- 2236693B
- Date:
- 2018-02-15
- Revision:
- 2:319575416324
- Parent:
- 1:4351b05b1685
- Child:
- 3:c61f5ff0f916
File content as of revision 2:319575416324:
#include "mbed.h" DigitalOut pulse(LED1); AnalogIn Ain(PTB1); AnalogOut Aout(PTE30); 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 float const trigger_high = 0.8; float const trigger_low = 0.6; //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 avg_sum = 0; //Sum of most recent 160 values //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 initialMin() //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 initialMax() //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 (data/max-min); } float filter(float data, float normalisedData) //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 (!intialised) { // 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 intialised= false; //Get inital min and max max = initialMax(); min = initialMin(); } 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_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 = initialMax(); min = initialMin(); } //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) { triggered = 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)) { pulse = 0; } else { pulse = 1; } } else if (!triggered) { if (above_trig_high(normalisedData)) { pulse = 1; } else { pulse = 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 int 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 } }