Here is a picture of my workbench. No project going on here. It all happens at Cegep where I am currently working on my final project. A energy monitoring dashboard based on TI MSP430. I'll talk about it here soon.
Sunday, January 31, 2010
Wednesday, April 1, 2009
Heart Rate Monitor
The first Arduino's project I am working on: A heart rate monitor. I am using this project to exercices with the Arduino platform and experimenting things with Polar technologies.
I have received the Polar Heart Rate Module from Sparkfun yesterday (http://www.sparkfun.com/commerce/product_info.php?products_id=8660) to replace the Rick Moll's circuit (http://rick.mollprojects.com/hrm/index.html) which is pretty hard to use due to its sensitivity to ambient electromagnetic field(TV, 120V AC cable...) and has a poor range (~30cm). Th module is now more easy to use, the datasheet is pretty clear about the pinout and the connection to a µController. To be able to use coded and non-coded transmitter you only hook-up the HR pin to the interruption output of the Arduino (Digital 2 or 3) which outpout a 1 ms pulse when a pulse is detected without the "coded pulse" as the FPLS pin would do.
Here is my schematic like it was with the Rick Moll's circuit:
Here is my Arduino code which looks to work pretty well with the module:
#define NUMREADINGS 4
#define DEADTIME 2000
int D3 = 3, D4 = 4, D5 =5, D6 = 6, D7 = 7, D8 = 8;
volatile int onetime;
volatile unsigned long beats = 0, lastTime, period;
int readings[NUMREADINGS]; // the readings from the analog input
int index = 0; // the index of the current reading
int total = 0; // the running total
int average = 0; // the average
void setup()
{
pinMode(D3, OUTPUT); //P3 to P8 as output
pinMode(D4, OUTPUT);
pinMode(D5, OUTPUT);
pinMode(D6, OUTPUT);
pinMode(D7, OUTPUT);
pinMode(D8, OUTPUT);
attachInterrupt(0, pulse, RISING); //call pulse function when an interrupt is detected on Port 2;
for (int i = 0; i <>
readings[i] = 0; // initialize all the readings to 0
}
}
void loop()
{
int frequence;
if ((beats > 1) && (onetime != 1)) { //make sur it passes only one time when a pulse is detected
frequence = (60000 / period); //calculate bpm using time between the two pulses
if ((frequence >= 40) && (frequence <= 220)) { //if bpm is between 40 and 220
total -= readings[index]; // subtract the last reading
readings[index] = frequence;
total += readings[index]; // add the reading to the total
index = (index + 1); // advance to the next index
if (index >= NUMREADINGS) { // if we're at the end of the array...
index = 0; // ...wrap around to the beginning
average = total / NUMREADINGS; // calculate the average
}
}
onetime = 1; //Puts the one time flag to 1
}
if ((millis() - lastTime) > DEADTIME) {
average = 0;
index = 0;
}
ssegment(average);
}
void pulse()
{
if (beats > 0){
period = millis() - lastTime;
}
lastTime = millis();
beats++;
onetime = 0; //Puts the one time flag to 0
}
void ssegment(int fc) {
int unite, dizaine, centaine;
unite = (fc % 10); //put the first number of the decimal value of bpm in unite variable
dizaine = (((fc % 100) - unite)/10);//put the second number of the decimal value of bpm in dizaine variable
centaine = (((fc % 1000) - dizaine - unite)/100);//put the third number of the decimal value of bpm in centaine variable
digitalWrite(D7, LOW); //address of first number
digitalWrite(D8, HIGH);
chiffre(unite); //send unite to funtion chiffre to be displayed
delay(1);
digitalWrite(D7, HIGH);//address of second number
digitalWrite(D8, LOW);
chiffre(dizaine); //send dizaine to funtion chiffre to be displayed
delay(1);
digitalWrite(D7, HIGH);//address of third number
digitalWrite(D8, HIGH);
chiffre(centaine); //send centaine to funtion chiffre to be displayed
delay(1);
}
void chiffre(int i) { //send bcd value of decimal number to ports D3 to D6
switch(i){
case 1:
digitalWrite(D6, HIGH);
digitalWrite(D3, LOW);
digitalWrite(D4, LOW);
digitalWrite(D5, LOW);
break;
case 2:
digitalWrite(D6, LOW);
digitalWrite(D3, HIGH);
digitalWrite(D4, LOW);
digitalWrite(D5, LOW);
break;
case 3:
digitalWrite(D6, HIGH);
digitalWrite(D3, HIGH);
digitalWrite(D4, LOW);
digitalWrite(D5, LOW);
break;
case 4:
digitalWrite(D6, LOW);
digitalWrite(D3, LOW);
digitalWrite(D4, HIGH);
digitalWrite(D5, LOW);
break;
case 5:
digitalWrite(D6, HIGH);
digitalWrite(D3, LOW);
digitalWrite(D4, HIGH);
digitalWrite(D5, LOW);
break;
case 6:
digitalWrite(D6, LOW);
digitalWrite(D3, HIGH);
digitalWrite(D4, HIGH);
digitalWrite(D5, LOW);
break;
case 7:
digitalWrite(D6, HIGH);
digitalWrite(D3, HIGH);
digitalWrite(D4, HIGH);
digitalWrite(D5, LOW);
break;
case 8:
digitalWrite(D6, LOW);
digitalWrite(D3, LOW);
digitalWrite(D4, LOW);
digitalWrite(D5, HIGH);
break;
case 9:
digitalWrite(D6, HIGH);
digitalWrite(D3, LOW);
digitalWrite(D4, LOW);
digitalWrite(D5, HIGH);
break;
case 0:
digitalWrite(D6, LOW);
digitalWrite(D3, LOW);
digitalWrite(D4, LOW);
digitalWrite(D5, LOW);
break;
}
}
If you have any question, I will be happy to help you.
Additional Ressources:
Subscribe to:
Posts (Atom)