Hi there,
I'm trying to read a pulse rate (BPM) from a pulse sensor on my Arduino Uno r3. The pulse sensor came with premade some code, that already sends data to Processing via Serial communication. This data was then used in another premade program that creates a nice Java window to display the heartbeat signal and some other stuff. I don't want to use the premade Processing code, so I'm writing a new one. I am, however, modifying the premade Arduino code, because most of that is useful. There is also an "Interrupt" Arduino sketch to go along with the one I've posted below, but I haven't messed with that because it deals with the sensor output. I can post that if need be.
What I want to do is to capture the BPM data from the pulse sensor and save it to a .csv file to look at later. I am trying to modify the premade pulse sensor code to let me do this.
Arduino code:
/*
>> Pulse Sensor Amped 1.1 <<
This code is for Pulse Sensor Amped by Joel Murphy and Yury Gitman
www.pulsesensor.com
>>> Pulse Sensor purple wire goes to Analog Pin 0 <<<
Pulse Sensor sample aquisition and processing happens in the background via Timer 2 interrupt. 2mS sample rate.
PWM on pins 3 and 11 will not work when using this code, because we are using Timer 2!
The following variables are automatically updated:
Signal : int that holds the analog signal data straight from the sensor. updated every 2mS.
IBI : int that holds the time interval between beats. 2mS resolution.
BPM : int that holds the heart rate value, derived every beat, from averaging previous 10 IBI values.
QS : boolean that is made true whenever Pulse is found and BPM is updated. User must reset.
Pulse : boolean that is true when a heartbeat is sensed then false in time with pin13 LED going out.
This code is designed with output serial data to Processing sketch "PulseSensorAmped_Processing-xx"
The Processing sketch is a simple data visualizer.
All the work to find the heartbeat and determine the heartrate happens in the code below.
Pin 13 LED will blink with heartbeat.
If you want to use pin 13 for something else, adjust the interrupt handler
It will also fade an LED on pin fadePin with every beat. Put an LED and series resistor from fadePin to GND.
Check here for detailed code walkthrough:
http://pulsesensor.myshopify.com/pages/pulse-sensor-amped-arduino-v1dot1
Code Version 02 by Joel Murphy & Yury Gitman Fall 2012
This update changes the HRV variable name to IBI, which stands for Inter-Beat Interval, for clarity.
Switched the interrupt to Timer2. 500Hz sample rate, 2mS resolution IBI value.
Fade LED pin moved to pin 5 (use of Timer2 disables PWM on pins 3 & 11).
Tidied up inefficiencies since the last version.
*/
// VARIABLES
int pulsePin = 0; // Pulse Sensor purple wire connected to analog pin 0
int blinkPin = 13; // pin to blink led at each beat
int fadePin = 5; // pin to do fancy classy fading blink at each beat
int fadeRate = 0; // used to fade LED on with PWM on fadePin
// these variables are volatile because they are used during the interrupt service routine!
volatile int BPM; // used to hold the pulse rate
volatile int Signal; // holds the incoming raw data
volatile int IBI = 600; // holds the time between beats, the Inter-Beat Interval
volatile boolean Pulse = false; // true when pulse wave is high, false when it's low
volatile boolean QS = false; // becomes true when Arduoino finds a beat.
void setup(){
pinMode(blinkPin,OUTPUT); // pin that will blink to your heartbeat!
pinMode(fadePin,OUTPUT); // pin that will fade to your heartbeat!
Serial.begin(115200); // we agree to talk fast!
interruptSetup(); // sets up to read Pulse Sensor signal every 2mS
// UN-COMMENT THE NEXT LINE IF YOU ARE POWERING The Pulse Sensor AT LOW VOLTAGE,
// AND APPLY THAT VOLTAGE TO THE A-REF PIN
//analogReference(EXTERNAL);
}
void loop(){
// sendDataToProcessing('S', Signal); // send Processing the raw Pulse Sensor data
// if (QS == true){ // Quantified Self flag is true when arduino finds a heartbeat
// fadeRate = 255; // Set 'fadeRate' Variable to 255 to fade LED with pulse
// sendDataToProcessing('B',BPM); // send heart rate with a 'B' prefix
// sendDataToProcessing('Q',IBI); // send time between beats with a 'Q' prefix
// QS = false; // reset the Quantified Self flag for next time
// }
//
// ledFadeToBeat();
// Serial.print(BPM, DEC); // Trying to print to Serial
// Serial.print(","); // Maybe delimiting it will help?
Serial.println(BPM); // Trying again to print to Serial
delay(100); // take a break
}
void ledFadeToBeat(){
fadeRate -= 15; // set LED fade value
fadeRate = constrain(fadeRate,0,255); // keep LED fade value from going into negative numbers!
analogWrite(fadePin,fadeRate); // fade LED
}
void sendDataToProcessing(char symbol, int data ){
Serial.print(symbol); // symbol prefix tells Processing what type of data is coming
Serial.println(data); // the data to send culminating in a carriage return
}
The code I have grafted in is under the "void loop()", the two "Serial.print" and the "Serial.println" lines. With the "Serial.println" line active, and the two "Serial.print" lines commented (those two lines were experimental), I am able to get integers running on the serial monitor. I've commented out the other code in the loop because it adds some other characters(like "S") and things that are needed for the premade Processing program.
I'm trying to capture this serial output using this Processing code:
import processing.serial.*;
PrintWriter output;
Serial port;
void setup() {
// Create a new file in the sketch directory
output = createWriter("positions.txt");
// GO FIND THE ARDUINO
println(Serial.list()); // print a list of available serial ports
// choose the number between the [] that is connected to the Arduino
port = new Serial(this, Serial.list()[1], 115200); // make sure Arduino is talking serial at this baud rate
port.clear(); // flush buffer
port.bufferUntil('\n'); // set buffer full flag on receipt of carriage return
}
void loop() {
print(BPM);
}
void keyPressed() {
output.flush(); // Writes the remaining data to the file
output.close(); // Finishes the file
exit(); // Stops the program
}
Running this code throws an error: "Cannot find anything named 'BPM' ". I should mention that I've cannibalized the "// GO FIND THE ARDUINO" section of the setup section from the premade Processing code, which I've attached.
I've been trying to learn how to use Arduino and Processing by poring over the examples (e.g. createWriter(), PrintWriter, print(), read(), etc...) in the Processing documentation, but I'm having trouble understanding what's going on here.
I know that good data (constantly updating integers) is coming out of the Arduino, because I can see it when I check the Serial Monitor. I'm expecting that the Serial Monitor represents the data coming directly into the serial port, and that Processing can read what I can see on the monitor. This is where my understanding breaks down. As far as I know, I'm trying to point Processing at the serial port, and get it to store the data it finds there, but it looks like Processing can't tell what it's looking at.
Any help would be appreciated! Please let me know if I need to provide any more information.
PulseSensorAmpd_Processing_1dot1.pde (6.26 KB)