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-03-03
- Revision:
- 7:cc766c97686a
- Parent:
- 6:9c5c36d2c0e1
File content as of revision 7:cc766c97686a:
#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 Min() //Get min value of 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 Max() //Get max value of 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 = Max();
min = Min();
}
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 = Max();
min = Min();
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) { //Previously bove high trigger
if (below_trig_low(normalisedData)) { //If it drops below ,ow trigger point
triggered = false;
pulse = 0;
} else { //Still above low trigger
pulse = 1;
}
}
else { //Previously below low trigger
if (above_trig_high(normalisedData)) {//If it goes above high trigger point
triggered = true;
pulse = 1;
} else { //Still below high trigger
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
}
}

