Team S - EDP 2 / Mbed 2 deprecated modular_signal_processing

Dependencies:   mbed

Fork of modular_signal_processing by Conor Begley

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
    }
}