im working on a project and code to tell you what your average heart rate is. ive found a code online to work with the sensor i have. and ive also written my own code based off of other codes ive seen on the internet. i am a beginner with arduino and coding, so any explanation/ help with whats going on would be greatly appreciated. Also, if any of you would be kind enough to put comments on each of the lines to explain what they do or how i can fix it, i would really appreciate it.
Thanks so much,
-I
Ps the first code is the one i got from the internet and the second is one i wrote based on ones i found on the internet
/****************************************************************************/
// Function: This program can be used to measure heart rate, the lowest
// pulse in the program be set to 30.Use an external interrupt
// to measure it.
// Hardware: Grove - Ear-clip Heart Rate Sensor, Grove - Base Shield,
// Grove - LED
// Arduino IDE: Arduino-1.0
// Author: FrankieChu
// Date: Jan 22, 2013
// Version: v1.0
// by www.seeedstudio.com
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
//
/******************************************************************************/
#define LED 4//indicator, Grove - LED is connected with D4 of Arduino
boolean led_state = LOW;//state of LED, each time an external interrupt
//will change the state of LED
unsigned char counter;
unsigned long temp[21];
unsigned long sub;
bool data_effect=true;
unsigned int heart_rate;//the measurement result of heart rate
const int max_heartpluse_duty = 2000;//you can change it follow your system's request.
//2000 means 2 seconds. System return error
//if the duty overtrip 2 second.
void setup()
{
pinMode(LED, OUTPUT);
Serial.begin(9600);
Serial.println("Please ready your chest belt.");
delay(5000);
arrayInit();
Serial.println("Heart rate test begin.");
attachInterrupt(0, interrupt, RISING);//set interrupt 0,digital port 2
}
void loop()
{
digitalWrite(LED, led_state);//Update the state of the indicator
}
/*Function: calculate the heart rate*/
void sum()
{
if(data_effect)
{
heart_rate=1200000/(temp[20]-temp[0]);//60*20*1000/20_total_time
Serial.print("Heart_rate_is:\t");
Serial.println(heart_rate);
}
data_effect=1;//sign bit
}
/*Function: Interrupt service routine.Get the sigal from the external interrupt*/
void interrupt()
{
temp[counter]=millis();
Serial.println(counter,DEC);
Serial.println(temp[counter]);
switch(counter)
{
case 0:
sub=temp[counter]-temp[20];
Serial.println(sub);
break;
default:
sub=temp[counter]-temp[counter-1];
Serial.println(sub);
break;
}
if(sub>max_heartpluse_duty)//set 2 seconds as max heart pluse duty
{
data_effect=0;//sign bit
counter=0;
Serial.println("Heart rate measure error,test will restart!" );
arrayInit();
}
if (counter==20&&data_effect)
{
counter=0;
sum();
}
else if(counter!=20&&data_effect)
counter++;
else
{
counter=0;
data_effect=1;
}
}
/*Function: Initialization for the array(temp)*/
void arrayInit()
{
for(unsigned char i=0;i < 20;i ++)
{
temp[i]=0;
}
temp[20]=millis();
}
unsigned long t1 = 0;
unsigned long t2 = 0;
unsigned long counter = 0; // count interrupts = beats
unsigned long secsElapsed = 0; // time for 60 beats
unsigned long myCount = 0; // heart beat count so far
float BPM = 0; // instantaneous rate
float ABPM = 0;// ave over 30 beats
boolean beatDetect = false;
boolean beats = false;
void setup()
{
Serial.begin(9600);
Serial.println("Please ready your ear clip.");
delay(2000);
Serial.println("Heart rate test begin.");// debug
t1 = millis();
attachInterrupt(0, interrupt, RISING);//set interrupt 0, digital pin 2 -
attachInterrupt(1, second, RISING);
}
void loop(){
if (beatDetect == true){
if (counter >= 20)
{
Serial.print("Your average heartrate is:");
ABPM = BPM;
Serial.println(ABPM);
}
counter = counter +1;
t2 = millis();
myCount = counter; // this is the amount of heartbeats
// that have occurred
secsElapsed = (t2- t1) / 1000;
BPM = (float(myCount) / float(secsElapsed)) * 60;
beatDetect = false; // resets for the next interrupt
// to occur
} // end of the beatDetect
} //end of the void loop
void interrupt ()
{
beatDetect = true;
}
void second (){
beats = true;
if (beats == true)
{
Serial.println("BEAT");
}
}
First things first: you need to put that code in code tags
so that
{
it
}
looks like
this.
There's a genuine reason for that: scroll through your code and you'll see it changes to italics halfway. That's because the [] with an i inside which is an array index in your code has been interpreted by the browser as a switch ti italics.
So sort that by editing the first post then folks will be inclined to look at the code. Code tags are inserted with the icon that looks like a scroll with <> inside, above the icon.
That's cool, well done. I was just about to post and say that you didn't actually say what was wrong with it in the first place, so nobody but you could have fixed it.
Well my problem is understanding what each line means and does, so what i really need help with is an explanation. Would you be able to explain what some of the more complicated lines do and mean?
I actually do understand what an interrupt and have written codes with them before. Its some of the other lines in the code i found online that i dont understand. Am i being clear enough on what i need explaining for? I know it is a lot to ask for, but line by line explanations for the code i found online would be very much appreciated
What exactly is rule #1? im new to arduino, i dont know all of this terminology yet.
Let me clarify what im asking for, the second program i originally posted, is what i really need help with. First thing i need help with is understanding the function of each line and how it affects the program, second is how can i change this program so that it prints to the serial monitor what the average heart rate is over 15 minutes.
An ISR is an interrupt service routine. Your code defines two interrupt service routines.
An ISR is supposed to be very fast. There are some things you can do in an ISR, and some things you can't. Using delay() is something you can't do. Serial.print() is something that you should not do. Sending serial data requires that interrupts be enabled. They are not while your interrupt service routine is processing an interrupt.
First thing i need help with is understanding the function of each line
There is a reference page. YOU need to spend time there. If, after reading the reference documentation, you don't understand something, ask about a line or two. We are not in the business of explaining all the code to you.
second is how can i change this program so that it prints to the serial monitor what the average heart rate is over 15 minutes.
Simple. Count the number of beats that happen in 15 minutes, and print the value.
If you want to (and you should) print the heart rate more often, and compute the average over 15 minutes, that is a different story. Once you know how to compute the heart rate at any given time, adding that value to a running total, and then dividing by the number of values accumulated over 15 minutes (or one minute or three weeks) is easy.
I have been trying to familiarize myself with the reference. Its how i taught myself how to code ( not anywhere close to an expert, im just a high school student).
do you know of a program or can you help my modify my program so that the arduino counts how many interrupts have been detected on 0, and then average that amount out over a period of 15 minutes?
Is that better ? (referring to the code below)
unsigned long t1 = 0;
unsigned long t2 = 0;
unsigned long counter = 0; // count interrupts = beats
unsigned long secsElapsed = 0; // time for 60 beats
unsigned long myCount = 0; // heart beat count so far
float BPM = 0; // instantaneous rate
float ABPM = 0;// ave over 30 beats
boolean beatDetect = false;
boolean beats = false;
void setup()
{
Serial.begin(9600);
Serial.println("Please ready your ear clip.");
delay(2000);
Serial.println("Heart rate test begin.");// debug
t1 = millis();
attachInterrupt(0, interrupt, RISING);//set interrupt 0, digital pin 2 -
attachInterrupt(1, second, RISING);
}
void loop(){
if (beatDetect == true){
if (counter >= 20)
{
Serial.print("Your average heartrate is:");
ABPM = BPM;
Serial.println(ABPM);
}
counter = counter +1;
t2 = millis();
myCount = counter; // this is the amount of heartbeats
// that have occurred
secsElapsed = (t2- t1) / 1000;
BPM = (float(myCount) / float(secsElapsed)) * 60;
beatDetect = false; // resets for the next interrupt
// to occur
} // end of the beatDetect
} //end of the void loop
void interrupt ()
{
beatDetect = true;
}
All that your interrupt handler does is not that a beat happened.
The poorly named second interrupt handler is missing, so I could only guess at what it does. I don't play guessing games.
But, forget about HOW to write the code for now. Do you understand the steps needed for YOU to determine the average over 15 minutes, given that you know the average for some subset of that time?
No, i dont quite understand how to average the interrupts over a 15 minute block. I found a code online for a heartbeat sensor and i tried to modify to what i would like for it to do. Right now the code finds the average heart rate for 20 interrupts that it counts, which is twenty heartbeats. I dont know how to change this so that it gives me an average for every 15 minutes. I guess what i really need it to do is count how many interrupts/heartbeats it detects in one minute, do this for 15 minutes and then average it out.
Right now the code finds the average heart rate for 20 interrupts that it counts, which is twenty heartbeats.
So, you know how long that took, because you print the average when the 2th heartbeat is detected. Simply add the number of beats to one variable, and the time to another. When the time gets to 15 minutes, you know how many beats happened. It's simple arithmetic to determine the average.
Well the amount of time that takes will vary depending on the persons heart rate. If im monitoring a persons heartrate while they're running compared to someone who is not active and is sitting, the amount of time it will take to county twenty interrupts/ heartbeats will change.
It shouldn't take a rocket scientist to figure out then that if you have 20 beats in x minutes, then the average is goind to be 20 / x.
He/she isn't getting 20 beats in x minutes. He/she is getting 20 beats in some much shorter period of time.
However that period of time is known. Adding up the periods of time, until the total reaches 15 minutes, and counting the number of 20 beat increments WILL give the average beats/minute over a 15 minute period.
Yes, thats true. But the amount of time that it will take for 20 beats to occur is going to always change. Thats what i need help with programing. Averaging the beats that occur in one minute over a 15 minuite interval