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-16
- Revision:
- 6:9c5c36d2c0e1
- Parent:
- 5:bbfcd046cd43
- Child:
- 7:cc766c97686a
File content as of revision 6:9c5c36d2c0e1:
#include "mbed.h"
//Testing 
Serial pc (USBTX, USBRX);
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
float const ALPHA = 0.5;     //Aplha value used for filtering
float const OFFSET = 0.2;  //Used to ensure normalised values don't be come negative
float const trigger_high = 0.21;
float const trigger_low = 0.19;
//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= true;
            //Get inital min and max
            max = initialMax();
            min = initialMin();
        }
        return 0.0;
    } else {                                    //Main runtime of program
        float 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
        max = initialMax();
        min = initialMin();
        float trendedData = data - (avg_sum/AVG_LEN);
        float offsetData = trendedData+OFFSET;
        return offsetData; //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
    pc.printf("%f \n \r", processing);
    Aout.write(processing);
    //processed = normalise(processing); //Normalise as per formula
    return processing;
}
bool below_trig_low(float point)   //Check if data goes below low trigger
{
    if(point <= trigger_low) {
        return true;
    }
    return false;
}
bool above_trig_high(float point)   //Check if data goes above high trigger
{
    if(point >= trigger_high) {
        return true;
    }
    return false;
}
void detectPulse(float normalisedData)   //Turn on LED during high part of pulse
{
    // Implementation of hysteresis
    if(triggered) {
        if (below_trig_low(normalisedData)) {
            triggered = false;
            pulse = 0;
        } else {
            pulse = 1;
        }
    } 
    else {
        if (above_trig_high(normalisedData)) {
            triggered = true;
            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
                float 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
    }
}
            
    
