Sunday, January 31, 2010

My workbench

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.

My workbench

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: