Hi all,
First time poster here but have hit a slight roadblock in a university project and am unsure how to continue. I have some coding experience in the past but this is my first time using arduino.
I have an optical heart rate sensor which returns a value and from this value you can see your heart rate (shown in the attached screenshot). For my project i'm mainly concerned with the peaks of the graph as I want to record the time intervals between heart rates however this is difficult as the value which is returned from the heart rate sensor varies greatly depending on how hard it is pressed to your skin.
I intended to use a threshold in the middle (the yellow line - Threshold) and then detect heartbeats whenever the wave crossed this line. In order to generate this threshold, I've used an average for the lowest and highest variables (green - LowTotal and red - HighTotal respectively) and the threshold is the mean of these two lines. However, these lines are not calculating as intended and are offset. The low average is a little above the bottom and the high average is way above at the top.
HighSample[TimersTriggered] = HighestSignal;
LowSample[TimersTriggered] = LowestSignal;
for (int i = 0; i <= ThresholdSamples - 1; i++){
HighTotal += HighSample[i];
}
HighTotal /= ThresholdSamples;
for (int i = 0; i <= ThresholdSamples - 1; i++) {
LowTotal += LowSample[i];
}
LowTotal /= ThresholdSamples;
Threshold = (HighTotal + LowTotal)/2;
I'm unsure as to how to rectify this and also unsure as to whether this method is the best solution for detecting the peaks in the wave.
As I said, this is my first time using arduino and my coding knowledge is a little rusty so any help would be greatly appreciated!
Full Code:
int LED13 = 13; // The on-board Arduion LED
int Signal; // holds the incoming raw data. Signal value can range from 0-1024
int Threshold; // Determine which Signal to "count as a beat", and which to ingore.
int N;
int TimersTriggered = 0;
int HighSample[10];
int LowSample[10];
int HighestSignal = 0;
int LowestSignal = 1000;
const int ThresholdSamples = 10;
int HighTotal;
int LowTotal;
const int RunningAverageCount = 16;
float RunningAverageBuffer[RunningAverageCount];
int NextRunningAverage;
float RunningAverageSignal = 0;
void setup() {
//Threshold = 500; // sets a starting threshold level
pinMode(LED13,OUTPUT); // pin that will blink to your heartbeat!
Serial.begin(9600); // Set's up Serial Communication at certain speed.
}
void loop() {
Signal = analogRead(0);
RunningAverageBuffer[NextRunningAverage++] = Signal;
if (NextRunningAverage >= RunningAverageCount)
{
NextRunningAverage = 0;
}
RunningAverageSignal = 0;
for(int i=0; i< RunningAverageCount; i++)
{
RunningAverageSignal += RunningAverageBuffer[i];
}
RunningAverageSignal /= RunningAverageCount;
if (RunningAverageSignal < LowestSignal){
LowestSignal = RunningAverageSignal;
}
if (RunningAverageSignal > HighestSignal){
HighestSignal = RunningAverageSignal;
}
if(N == 20){
HighSample[TimersTriggered] = HighestSignal;
LowSample[TimersTriggered] = LowestSignal;
for (int i = 0; i <= ThresholdSamples - 1; i++){
HighTotal += HighSample[i];
}
HighTotal /= ThresholdSamples;
for (int i = 0; i <= ThresholdSamples - 1; i++) {
LowTotal += LowSample[i];
}
LowTotal /= ThresholdSamples;
Threshold = (HighTotal + LowTotal)/2;
if(TimersTriggered == 9){
TimersTriggered = 0;
}
N = 0;
HighestSignal = 0;
LowestSignal = 1000;
TimersTriggered++;
}
Serial.print(RunningAverageSignal);
Serial.print(" ");
Serial.print(HighTotal);
Serial.print(" ");
Serial.print(LowTotal);
Serial.print(" ");
Serial.println(Threshold);
N += 1;
delay(10);
}