WorldFamousElectronics / PulseSensorPlayground

A PulseSensor library (for Arduino) that collects our most popular projects in one place.
https://PulseSensor.com
MIT License
201 stars 97 forks source link

Working on the pulsesensor with MKR1010 #122

Closed twmaaa closed 4 years ago

twmaaa commented 4 years ago

First Thanks for the library provided! I am using the MKR1010 board to read the data from the pulse sensor by using the PulseSensor_BPM_alternative by connecting to 5V, GND, and the signal to A0 pin. And I got the same result as the tutorial you provided showing the BPM and IBI as well on the serial plotter. However, I want to draw the exact BPM values to another platform for the data analysis. However, when I check the graph of the serial monitor, the BPM is only capable for showing the pulse waveform within the time, but not the exact int of BPM. And I all want is to get the exact BPM just like the example from the Getting_the_BPM_to_Monitor. So I tried to modify the code of the PulseSensor_BPM_alternative under the loop function:

void loop() {

if (--samplesUntilReport == (byte) 0) {
  samplesUntilReport = SAMPLES_PER_SERIAL_SAMPLE;

    const int myBPM = pulseSensor.getBeatsPerMinute();
    Serial.println(myBPM);
}

  if (pulseSensor.sawStartOfBeat()) {
    pulseSensor.outputBeat();
  }
}

}

By using the function of getBeatsPerMinute(), I wish to get the exact BPM value. However it only keeps showing 0 from the Serial Monitor. What is wrong of my code and how should I fix this? Thank You!!

biomurph commented 4 years ago

@twmaaa That's great! Thanks for using Pulse Sensor and jamming on the MKR 1010. I have one here that I'm using for a different project. Please make sure that you don't connect the Pulse Sensor red wire to the 5V pin! The MKR1010 can only handle 3.3V! Read here https://www.arduino.cc/en/Guide/MKRWiFi1010

It looks like you are inserting your Serial.print of the BPM in the wrong place...

if (--samplesUntilReport == (byte) 0) { samplesUntilReport = SAMPLES_PER_SERIAL_SAMPLE; // you don't need to do anything here if you don't want to stream samples } if (pulseSensor.sawStartOfBeat()) { // pulseSensor.outputBeat(); // if you don't want all the library output, don't use this line const int myBPM = pulseSensor.getBeatsPerMinute(); // get BPM when new value becomes available Serial.println(myBPM); // print BPM every time there is a beat } }`

Try something like that and let us know how it works.

twmaaa commented 4 years ago

@biomurph Thanks for 3.3V reminder! I nearly forgot... After I change to 3.3V and change code, it seems there is nothing showing up on the serial monitor. I am thinking if there is a problem on the function getBeatsPerMinute() due to the Interrupt of the library code.

biomurph commented 4 years ago

@twmaaa if you are using the BPM_Alternative code, you are not using interrupts. Please share the entirety of the code you are using, so I can help troubleshoot your problem better.

twmaaa commented 4 years ago

@biomurph Yes I know... but seems the function "getBeatsPerMinute()" is only working on the examples which using interrupts. So I am thinking if there is a problem on the function getBeatsPerMinute() which may require the interrupts.

for the codes, I only change the loop function as the way I mentioned earlier in the comment and other things keep constant.

define USE_ARDUINO_INTERRUPTS false

include

const int OUTPUT_TYPE = SERIAL_PLOTTER;

const int PULSE_INPUT = A0; const int PULSE_BLINK = 13; // Pin 13 is the on-board LED const int PULSE_FADE = 5; const int THRESHOLD = 550; // Adjust this number to avoid noise when idle

byte samplesUntilReport; const byte SAMPLES_PER_SERIAL_SAMPLE = 10;

PulseSensorPlayground pulseSensor;

void setup() { Serial.begin(115200);

pulseSensor.analogInput(PULSE_INPUT); pulseSensor.blinkOnPulse(PULSE_BLINK); pulseSensor.fadeOnPulse(PULSE_FADE);

pulseSensor.setSerial(Serial); pulseSensor.setOutputType(OUTPUT_TYPE); pulseSensor.setThreshold(THRESHOLD);

// Skip the first SAMPLES_PER_SERIAL_SAMPLE in the loop(). samplesUntilReport = SAMPLES_PER_SERIAL_SAMPLE;

// Now that everything is ready, start reading the PulseSensor signal. if (!pulseSensor.begin()) {

for(;;) {
  // Flash the led to show things didn't work.
  digitalWrite(PULSE_BLINK, LOW);
  delay(50);
  digitalWrite(PULSE_BLINK, HIGH);
  delay(50);
}

} }

void loop() {

if (pulseSensor.sawNewSample()) {

if (--samplesUntilReport == (byte) 0) {
  samplesUntilReport = SAMPLES_PER_SERIAL_SAMPLE;

  if (pulseSensor.sawStartOfBeat()) {
    const int myBPM = pulseSensor.getBeatsPerMinute(); 
    Serial.println(myBPM);
  }
}

} }

biomurph commented 4 years ago

@twmaaa I uploaded your code as is to the Arduino MKR WIFI 1010 that I have on my bench. It works as it should, reporting the BPM with every heartbeat.

Not sure what your issue might be, but try putting this line right after the Serial.begin while(!Serial) {} The serial port does not pop up automagically like with the UNO or other boards. Sometimes that can cause the serial port to barf, or just act weird. When you put in that while statement, the code will hang until the serial port is established. See if that helps?

You can also comment out the lines

if (--samplesUntilReport == (byte) 0) { samplesUntilReport = SAMPLES_PER_SERIAL_SAMPLE;

and the attendant curly brace. You're not using that. You DO, however need to keep in the if(pulseSensor.sawNewSample()) conditional, as that is what is triggering the software timer inside the Pulse Sensor Playground library.

What is the ultimate goal for this code? Are you going to put heartbeats on the internet?

twmaaa commented 4 years ago

@biomurph thank you so much! I think i know the problem... since i merged the code with the temperature sensor, I put the loop function function of temp sensor under the if condition of the pulsesensor, and that's why I cannot read anything from that.

btw, I am working on a sleep coaching system by collecting different parameters. anyway really thanks for the library!