Arduino Heart Rate Sensor Outputting


#1

Hi,

Not sure what I’m doing wrong but I’ve got the below code yet it just outputs “Heart Rate: 10” and outputs 10 in the console, too. I’m using a heart rate sensor from PulseSensor.com with my Arduino. When I open the Arduino monitor separately it’s outputting the correct BPM.

  #include "ofApp.h"
int byteData;
//--------------------------------------------------------------
void ofApp::setup() {
	ofSetLogLevel(OF_LOG_VERBOSE);
	//General setup of look of window.
	ofBackground(255);
	verdana14.load("verdana.ttf", 14, true, true);
	ofSetColor(0);
	if (!serial.setup("COM3", 115200)) {
		ofLogError() << "could not open serial port - listing serial devices";
		serial.listDevices();
		
	}
}

//--------------------------------------------------------------
void ofApp::update() {

	if (serial.available() < 0) {
		msg = "Arduino Error";
		
	}
	else {
		//While statement looping through serial messages when serial is being provided.
		while (serial.available() > 0) {
			//byte data is being writen into byteData as int.
			byteData = serial.readByte();

			//byteData is converted into a string for drawing later.
			msg = "Heart Rate: " + ofToString(byteData);
		}
	}
}

//--------------------------------------------------------------
void ofApp::draw() {
	//drawing the string version pf byteData on oF window.
	verdana14.drawString(msg, 50, 100);

	//printing byteData into console.
	cout << byteData << endl;
}

I have ‘BPM’ as a variable in my Arduino code, found below.
#include <PulseSensorPlayground.h>

volatile int BPM;
volatile boolean QS = false;
volatile int IBI = 600;
volatile int Signal;
volatile boolean Pulse = false;
int redPin = 13;
int greenPin = 12;
int pulsePin = 0;
int blinkPin = 11;

void setup() {

Serial.begin(115200);
interruptSetup();
pinMode(redPin, OUTPUT);       
pinMode(greenPin, OUTPUT);

}

void loop(){

   
  if (QS == true) {
        healthCheck();
   
    Serial.print("Your Current Heart Rate Is: ");            
    Serial.println(BPM);
    Serial.write(BPM);          
    QS = false;
  
   }
  

  delay(2500);
}

Does anyone know why it would be outputting 10? I have a feeling it’s to do with the byteData but I’m not overly sure!


#2

it’s outputting 10 because that’s the ascii character that’s supposed to end the line. you should collect them, something like

string incoming=""";
while (serial.available() > 0) {
//byte data is being writen into byteData as int.
incoming += byteData = serial.readByte();
//byteData is converted into a string for drawing later.
msg = "Heart Rate: " + ofToString(byteData);
}
cout << "received : " << incoming << ‘\m’;

but also there should be a terminator in your serial message from arduino, so that in oF when you receive it, you know your data is there.


#3

Hi as1er;

I’m still really struggling as it’s still displaying 10 on my OpenFrameworks app despite ocasionally printing the correct heartrate in the console(only once every few seconds, inbetween a constant stream of 10’s).

Any ideas?


#4

you can find one right on the console, so you just need to discard the rest.

what happens when you see the right one?
is the string length different?
(this could lead to an easy if(string.size()==10){ yourheart=ofToInt(incoming[7, 21] ; // this is just some pseudocode for a proper substring stripping of the value alone)


#5

Hi,

Thank you for trying to assist me further it’s hugely appreciated. I’m a bit of a noobie when it comes to OpenFrameworks and as such I’m still really struggling. Where would I place your snippet of code and what would I put for the yourheart variable?

Sorry to be such a pain!


#6

hi Harry,

here’s a really simpler alternative.

make sure your arduino firmware sends only bytes (ie, comment out all Serial.print() & printlns(), leave only one serial.write(BPM)); double check serial monitor you are sending just one byte per frame – while you are at it, you might want to dreacrease the delay(2500) into something more performative;

then in oF update serial section, simply read the incoming bytes like you were doing in the first place, should work now cause you changed how you are talking to your microcontroller and sending only 1byte of data per frame, no newlines, no help strings:

while (serial.available() > 0) {
//byte data is being writen into byteData as int.
byteData = serial.readByte();
//byteData is converted into a string for drawing later.
msg = "Heart Rate: " + ofToString(byteData);
}

now you should only see the bpm. bytes are limited to 256 values, so you should only see bpm’s of integers up till 255, if you are looking for more precision/range you have to rethink a different data processing strategy.

but this is simple and fast and should get you going.


#7

Thank you very much this helped me loads!