Hi!
I am trying to get my arduino Uno board to give me a BPM pulse rate from the readings of a “Pulse Sensor (www.pulsesensor.com)”
This is my attempt:
#include <LiquidCrystal.h>
#include <Keypad.h>
//Sources: http://sunraysme.wordpress.com/2012/04/10/a-keypad-for-thearduino/
// http://pulsesensor.myshopify.com/pages/pulse-sensor-amped-arduino-v1dot1
//Basics
int sysinit = 0;
int agedigit1;
int agedigit2;
int maxpuls;
int pulsePin = 0;
int blinkPin = 13;
int fadePin = 5;
int fadeRate = 0;
volatile int BPM;
volatile int Signal;
volatile int IBI = 600;
volatile boolean Pulse = false;
volatile boolean QS = false;
volatile int rate[10];
volatile unsigned long sampleCounter = 0;
volatile unsigned long lastBeatTime = 0;
volatile int P =512;
volatile int T = 512;
volatile int thresh = 512;
volatile int amp = 100;
volatile boolean firstBeat = true;
volatile boolean secondBeat = false;
const byte rows = 4; //four rows
const byte cols = 3; //three columns
char keys[rows][cols] = {
{'1','2','3'},
{'4','5','6'},
{'7','8','9'},
{'*','0','#'}
};
byte rowPins[rows] = {5, 4, 3, 2};
byte colPins[cols] = {8, 7, 6};
Keypad kpd = Keypad( makeKeymap(keys), rowPins, colPins, rows, cols );
LCD definitions
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
void interruptSetup(){
TCCR2A = 0x02;
TCCR2B = 0x06;
OCR2A = 0x7C;
TIMSK2 = 0x02;
sei();
}
ISR(TIMER2_COMPA_vect){
Signal = analogRead(pulsePin);
sampleCounter += 2;
int N = sampleCounter - lastBeatTime;
if(Signal < thresh && N > (IBI/5)*3){
if (Signal < T){
T = Signal;
}
}
if(Signal > thresh && Signal > P){
P = Signal;
}
if (N > 250){
if ( (Signal > thresh) && (Pulse == false) && (N > ((IBI/5)*3) )) {
Pulse = true;
digitalWrite(pulsePin,HIGH);
IBI = sampleCounter - lastBeatTime;
lastBeatTime = sampleCounter;
if(secondBeat) {
secondBeat = false;
for(int i=0; i<=9; i++) {
rate[i] = IBI;
}
}
if(firstBeat) {
firstBeat = false;
secondBeat = true;
sei();
return;
}
word runningTotal = 0;
for(int i=0; i<=8; i++) {
rate[i] = rate[i+1];
runningTotal += rate[i];
}
rate[9] = IBI;
runningTotal += rate[9];
runningTotal /= 10;
BPM = 60000/runningTotal;
QS = true;
}
}
if (Signal < thresh && Pulse == true) {
digitalWrite(13,LOW);
Pulse = false;
amp = P - T;
thresh = amp/2 + T;
P = thresh;
T = thresh;
}
if (N > 2500) {
thresh = 512;
P = 512;
T = 512;
firstBeat = true;
secondBeat = false;
lastBeatTime = sampleCounter;
}
}
void setup()
{
lcd.begin(16,2);
pinMode(13,OUTPUT); //Ledpin
pinMode(10,OUTPUT);
pinMode(8, INPUT_PULLUP); //Kolumn 1
pinMode(7, INPUT_PULLUP); //Kolumn 2
pinMode(6, INPUT_PULLUP); //Kolumn 3
lcd.setCursor(0,0);
lcd.print("Input age and press '#' on the keypad");
lcd.print(" Age: ");
lcd.setCursor(0,5);
interruptSetup();
}
void loop()
{
char key = kpd.getKey();
switch (sysinit) {
case 0: {
int digit = key - '0';
if(digit >= 0) {
if(digit <= 9) {
agedigit1 = digit;
lcd.print(key);
sysinit = sysinit++;
}
}
}
break;
case 1: {
int digit2 = key - '0';
if(digit2 >= 0) {
if(digit2 <=9) {
agedigit2 = digit2;
lcd.print(key);
sysinit = sysinit++;
}
}
}
break;
case 2: {
if(key == '#') {
maxpuls = 220 - (10*agedigit1 + agedigit2);
lcd.setCursor(0,1);
lcd.print(" Maxpuls: ");
lcd.print(maxpuls);
Serial.println();
sysinit = sysinit++;
}
}
break;
case 3: {
sendDataToProcessing('S', Signal);
if (QS == true){
sendDataToProcessing('B',BPM);
sendDataToProcessing('Q',IBI);
QS = false;
}
ledFadeToBeat();
delay(20);
}
break;
}
}
void sendDataToProcessing(char symbol, int data ) {
Serial.print(symbol);
Serial.println(data);
}
void ledFadeToBeat(){
fadeRate-= 15;
fadeRate= constrain(fadeRate,0,255);
analogWrite(fadePin, fadeRate);
}
I should mention that this is my first attempt to Arduino and therefore apologize for any structural or obvious “mess ups” in my code.
Any help with figuring out how to convert the sensor values to BPM is greatly appreciated!