skruglewicz
Created April 5, 2022

SpresenseBPM

My Idea is to create a Heart Rate Monitor that measures a patients Beats Per Minute (BPM)..

IntermediateWork in progress57
SpresenseBPM

Things used in this project

Hardware components

Spresense boards (main & extension)
Sony Spresense boards (main & extension)
×1
PulseSensor Heart Rate Sensor
×1
UCTRONICS SSD1306 I2C OLED Display 128x64 Yellow Blue
×1
Jumper wires (generic)
Jumper wires (generic)
×1
Breadboard (generic)
Breadboard (generic)
×1

Software apps and online services

PlatformIO IDE
PlatformIO IDE
Arduino IoT Cloud
Arduino IoT Cloud
Edge Impulse Studio
Edge Impulse Studio

Story

Read more

Code

Spresense_test.ino.ino

Python
Test sketch to the SpreSense using the Arduino IDE.
void setup() {
    pinMode(LED0, OUTPUT);
    pinMode(LED1, OUTPUT);
    pinMode(LED2, OUTPUT);
    pinMode(LED3, OUTPUT);
}
void loop() {
    digitalWrite(LED0, HIGH);
    delay(100);
    digitalWrite(LED1, HIGH);
    delay(100);
    digitalWrite(LED2, HIGH);
    delay(100);
    digitalWrite(LED3, HIGH);
    delay(1000);

    digitalWrite(LED0, LOW);
    delay(100);
    digitalWrite(LED1, LOW);
    delay(100);
    digitalWrite(LED2, LOW);
    delay(100);
    digitalWrite(LED3, LOW);
    delay(1000);
}

SpreSense_GettingStartedProject.ino

Python
to test the wireing for the Heart rate sensor, I used a script from the vendor page for the sensor. The website is in the sketch if you would like to explore more.. I modified it to use the pins on Spesense.
/*  PulseSensor Starter Project and Signal Tester
 *  The Best Way to Get Started  With, or See the Raw Signal of, your PulseSensor.com & Arduino.
 *
 *  Here is a link to the tutorial
 *  https://pulsesensor.com/pages/code-and-guide
 *
 *  WATCH ME (Tutorial Video):
 *  https://www.youtube.com/watch?v=RbB8NSRa5X4
 *
 *
-------------------------------------------------------------
1) This shows a live human Heartbeat Pulse.
2) Live visualization in Arduino's Cool "Serial Plotter".
3) Blink an LED on each Heartbeat.
4) This is the direct Pulse Sensor's Signal.
5) A great first-step in troubleshooting your circuit and connections.
6) "Human-readable" code that is newbie friendly."

*/


//  Arduino variables Variables
//int PulseSensorPurplePin = 0;        // Pulse Sensor PURPLE WIRE connected to ANALOG PIN 
//int LED13 = 13;                      //  The on-board Arduion LED

// Sony spresense variables
int PulseSensorPurplePin = 2;        // Pulse Sensor PURPLE WIRE connected to ANALOG PIN on spresense main board
int LED13 = LED0;                      //  The on-board spesense LED

int Signal;                // holds the incoming raw data. Signal value can range from 0-1024
int Threshold = 550;            // Determine which Signal to "count as a beat", and which to ingore.


// The SetUp Function:
void setup() {
  pinMode(LED13,OUTPUT);         // pin that will blink to your heartbeat!
   //Serial.begin(9600);         // Set's up Serial Communication at certain speed.
  //Serial.begin(15200);
}

// The Main Loop Function
void loop() {

  Signal = analogRead(PulseSensorPurplePin);  // Read the PulseSensor's value.
                                              // Assign this value to the "Signal" variable.

   //Serial.println(Signal);                    // Send the Signal value to Serial Plotter.

//
//   if(Signal > Threshold){                          // If the signal is above "550", then "turn-on" Arduino's on-Board LED.
//     digitalWrite(LED13,HIGH);
//   } else {
//     digitalWrite(LED13,LOW);                //  Else, the sigal must be below "550", so "turn-off" this LED.
//   }

// I reversed this logic to detect a beat under the threshold?
   if(Signal < Threshold){                          // If the signal is above "550", then "turn-on" Arduino's on-Board LED.
     digitalWrite(LED13,HIGH);
     //Serial.println(Signal);                    // Send the Signal value to Serial Plotter.
   } else {
     digitalWrite(LED13,LOW);                //  Else, the sigal must be below "550", so "turn-off" this LED.
   }

delay(10);
     digitalWrite(LED13,LOW); 

}

OLED_Test.ino

Python
This sketch is used to test the wiring Spresense to the OLED Display (SSD1306). This sketch will display a counter value incremented in the main loop function. A function is called to display the values of the counter.
/*
 OLED_Test.ino
  Displays results on 128 x 64 OLED display
  Uses Adafruit SSD1306 OLED Library
  Uses Adafruit GFX Graphics Library
*/

// Include Wire Library for I2C
#include <Wire.h>

// Include Adafruit Graphics & OLED libraries
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

// Reset pin not used but needed for library
// works on NANO
//#define OLED_RESET 4
//Adafruit_SSD1306 display(OLED_RESET);

// CODE for MKR WAN 1300
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 32 // OLED display height, in pixels

// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
#define OLED_RESET     4 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
int count;

void setup() {
  // Start Wire library for I2C
  Wire.begin(); 
  
  // initialize OLED with I2C addr 0x3C
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);

  count=1;
}

void displayValues(int v){
  // Delay to allow sensor to stabalize
  delay(2000);
  // Clear the display
  display.clearDisplay();
  //Set the color - always use white despite actual display color
  display.setTextColor(WHITE);
  //Set the font size
  display.setTextSize(1);
  //Set the cursor coordinates
  display.setCursor(25,0);
  display.print("COUNTER");
  display.setCursor(33,12); 
  display.setTextSize(3);
  display.print(v);
}

void loop() {
  ++count;
  displayValues(count);
  display.display();

}

BPM_SpreSense.ino

Python
Sketch to display BPM to the OLED display from the PulseSensor. using the design .
/*
   Sketch to display BPM to the OLED display from the PulseSensor.

 */

  /* OLED Section */
// Include Wire Library for I2C
#include <Wire.h>
// Include Adafruit Graphics & OLED libraries
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
// Reset pin not used but needed for library
#define OLED_RESET 4
Adafruit_SSD1306 display(OLED_RESET);  


/* PulseSensor Section */
#define USE_ARDUINO_INTERRUPTS false
#include <PulseSensorPlayground.h>

////  Arduino variables 
const int PULSE_INPUT = A0;     // Pulse Sensor PURPLE WIRE connected to ANALOG PIN 
const int PULSE_BLINK = 13;    // Pin 13 is the on-board LED

// Change to SpreSense PINS
const int PULSE_INPUT = A2;     // Pulse Sensor PURPLE WIRE connected to ANALOG PIN 
const int PULSE_BLINK = 0;    // Pin 0 is the on-board LED


const int PULSE_FADE = 5;
const int THRESHOLD = 550;   // Adjust this number to avoid noise when idle

/*
   samplesUntilReport = the number of samples remaining to read
   until we want to report a sample over the serial connection.
*/
byte samplesUntilReport;
const byte SAMPLES_PER_SERIAL_SAMPLE = 10;

/*
   All the PulseSensor Playground functions.
*/
PulseSensorPlayground pulseSensor;

void setup() {
  
  /* OLED Section */
  // Start Wire library for I2C
  Wire.begin();   
  // initialize OLED with I2C addr 0x3C
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);

  
  /* PulseSensor Section */
  /*
     Use 115200 baud because that's what the Processing Sketch expects to read,
     and because that speed provides about 11 bytes per millisecond.
  */
  Serial.begin(115200);

  // Configure the PulseSensor manager.
  pulseSensor.analogInput(PULSE_INPUT);
  pulseSensor.blinkOnPulse(PULSE_BLINK);
  pulseSensor.fadeOnPulse(PULSE_FADE);

  pulseSensor.setSerial(Serial);
  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()) {
    /*
       PulseSensor initialization failed,
       likely because our Arduino platform interrupts
       aren't supported yet.

       If your Sketch hangs here, try changing USE_PS_INTERRUPT to false.
    */
    for(;;) {
      // Flash the led to show things didn't work.
      digitalWrite(PULSE_BLINK, LOW);
      delay(50);
      digitalWrite(PULSE_BLINK, HIGH);
      delay(50);
    }
  }

}

// set up display object that will be displayed on the OLED
void displayValues(int v){
  // Delay to allow sensor to stabalize
  delay(2000);
  // Clear the display
  display.clearDisplay();
  //Set the color - always use white despite actual display color
  display.setTextColor(WHITE);
  //Set the font size
  display.setTextSize(1);
  //Set the cursor coordinates
  display.setCursor(0,0);
  display.print("Beats Per Minute");
  display.setCursor(33,12); 
  display.setTextSize(3);
  display.print(v);
}

void loop() {

/* PulseSensor Section */
  if (pulseSensor.sawNewSample()) {
    /*
       Every so often, send the latest Sample.
       We don't print every sample, because our baud rate
       won't support that much I/O.
    */
    if (--samplesUntilReport == (byte) 0) {
      samplesUntilReport = SAMPLES_PER_SERIAL_SAMPLE;

      //pulseSensor.outputSample();
      int myBPM = pulseSensor.getBeatsPerMinute();  // Calls function on our pulseSensor object that returns BPM as an "int".
                                               // "myBPM" hold this BPM value now. 

      /*
         At about the beginning of every heartbeat,
         report the heart rate and inter-beat-interval.
      */
      if (pulseSensor.sawStartOfBeat()) {
        // print the values to the serial monitor
        Serial.println("  A HeartBeat Happened ! "); // If test is "true", print a message "a heartbeat happened".
        Serial.print("BPM: ");                        // Print phrase "BPM: " 
        Serial.println(myBPM);                        // Print the value inside of myBPM. 

        // Set up the display and display the BPM
        displayValues(myBPM);
        display.display();
      }
    }

    /*******
      Here is a good place to add code that could take up
      to a millisecond or so to run.
    *******/
  }

  /******
     Don't add code here, because it could slow the sampling
     from the PulseSensor.
  ******/

}

Credits

skruglewicz

skruglewicz

19 projects • 9 followers
I am now a retired Senior Software Engineer with a Bachelor’s of Science Degree in Computer Science from Boston University.

Comments