BLYNK
BLYNK.IO       📲 GETTING STARTED       📗 DOCS       👉 SKETCH BUILDER

I've codes of HR and SpO2 for MAX30102 , on ESP32 how to merge them for Blynk

How can the following code be merged for showing data on BLYNK.
Or anyone having code for both of them.

HeartRate;

#include <Wire.h>
#include "MAX30105.h"

#include "heartRate.h"

MAX30105 particleSensor;

const byte RATE_SIZE = 4; //Increase this for more averaging. 4 is good.
byte rates[RATE_SIZE]; //Array of heart rates
byte rateSpot = 0;
long lastBeat = 0; //Time at which the last beat occurred

float beatsPerMinute;
int beatAvg;

void setup()
{
  Serial.begin(115200);
  Serial.println("Initializing...");

  // Initialize sensor
  if (!particleSensor.begin(Wire, I2C_SPEED_FAST)) //Use default I2C port, 400kHz speed
  {
    Serial.println("MAX30105 was not found. Please check wiring/power. ");
    while (1);
  }
  Serial.println("Place your index finger on the sensor with steady pressure.");

  particleSensor.setup(); //Configure sensor with default settings
  particleSensor.setPulseAmplitudeRed(0x0A); //Turn Red LED to low to indicate sensor is running
  particleSensor.setPulseAmplitudeGreen(0); //Turn off Green LED
}

void loop()
{
  long irValue = particleSensor.getIR();

  if (checkForBeat(irValue) == true)
  {
    //We sensed a beat!
    long delta = millis() - lastBeat;
    lastBeat = millis();

    beatsPerMinute = 60 / (delta / 1000.0);

    if (beatsPerMinute < 255 && beatsPerMinute > 20)
    {
      rates[rateSpot++] = (byte)beatsPerMinute; //Store this reading in the array
      rateSpot %= RATE_SIZE; //Wrap variable

      //Take average of readings
      beatAvg = 0;
      for (byte x = 0 ; x < RATE_SIZE ; x++)
        beatAvg += rates[x];
      beatAvg /= RATE_SIZE;
    }
  }

  Serial.print("IR=");
  Serial.print(irValue);
  Serial.print(", BPM=");
  Serial.print(beatsPerMinute);
  Serial.print(", Avg BPM=");
  Serial.print(beatAvg);

  if (irValue < 50000)
    Serial.print(" No finger?");

  Serial.println();
}

blood O2;

#define BLYNK_PRINT Serial
#include <WiFi.h>
#include <BlynkSimpleEsp32.h>
#include <Wire.h>

#include "MAX30105.h" //sparkfun MAX3010X library
#include "heartRate.h"
SimpleTimer timer;
MAX30105 particleSensor;

char auth[] = "fIGPsYeI0rf2DWG6FAPXdf-NGuhaF0Fe";


char ssid[] = "vivo 1713";
char pass[] = "fab123456";

#define INTERVAL_MESSAGE2 60000
unsigned long time_2 = 0;
int period = 2000;
unsigned long time_now = 0;
double avered = 0;
double aveir = 0;
double sumirrms = 0;
double sumredrms = 0;
int i = 0;
int Num = 100; //calculate SpO2 by this sampling interval

int oxygen;
double ESpO2 = 95.0;    //initial value of estimated SpO2
double FSpO2 = 0.7;     //filter factor for estimated SpO2
double frate = 0.95;    //low pass filter for IR/red LED value to eliminate AC component
#define TIMETOBOOT 3000 // wait for this time(msec) to output SpO2
#define SCALE 88.0      //adjust to display heart beat and SpO2 in the same scale
#define SAMPLING 5      //if you want to see heart beat more precisely , set SAMPLING to 1
#define FINGER_ON 3000  // if red signal is lower than this , it indicates your finger is not on the sensor
#define MINIMUM_SPO2 0.0

const byte RATE_SIZE = 4; //Increase this for more averaging. 4 is good.
byte rates[RATE_SIZE];    //Array of heart rates
byte rateSpot = 0;
long lastBeat = 0; //Time at which the last beat occurred
float beatsPerMinute;
int beatAvg;


#define USEFIFO

void setup()
{
  Serial.begin(115200);
  Serial.println("Initializing...");
 
  Blynk.begin(auth, ssid, pass);

  // Initialize sensor
  while (!particleSensor.begin(Wire, I2C_SPEED_FAST)) //Use default I2C port, 400kHz speed
  {
Serial.println("MAX30102 was not found. Please check wiring/power/solder jumper at MH-ET LIVE MAX30102 board. ");
//while (1);
  }
  Serial.println("Place your index finger on the sensor with steady pressure.");

  //Setup to sense a nice looking saw tooth on the plotter
  byte ledBrightness = 255; // 0x7F Options: 0=Off to 255=50mA
  byte sampleAverage = 4;   //Options: 1, 2, 4, 8, 16, 32
  byte ledMode = 2;         //Options: 1 = Red only, 2 = Red + IR, 3 = Red + IR + Green
  int sampleRate = 400;     //1000 is best but needs processing power//Options: 50, 100, 200, 400, 800, 1000, 1600, 3200
  int pulseWidth = 411;     //Options: 69, 118, 215, 411
  int adcRange = 16384;     //Options: 2048, 4096, 8192, 16384
  // Set up the wanted parameters
  particleSensor.setup(ledBrightness, sampleAverage, ledMode, sampleRate, pulseWidth, adcRange); //Configure sensor with these settings
  particleSensor.enableDIETEMPRDY();
  timer.setInterval(500, sendUptime);
}

void sendUptime()
{
  Blynk.virtualWrite(V4, oxygen);
  Blynk.virtualWrite(V5, beatAvg);
}

void loop()
{
  Blynk.run();
  timer.run(); // Initiates SimpleTimer

  uint32_t ir, red, green;
  double fred, fir;
  double SpO2 = 0; //raw SpO2 before low pass filtered

#ifdef USEFIFO
  particleSensor.check(); //Check the sensor, read up to 3 samples

  while (particleSensor.available())

  { //do we have new data
#ifdef MAX30105
red = particleSensor.getFIFORed(); //Sparkfun's MAX30105
ir = particleSensor.getFIFOIR();   //Sparkfun's MAX30105
#else
red = particleSensor.getFIFOIR(); //why getFOFOIR output Red data by MAX30102 on MH-ET LIVE breakout board
ir = particleSensor.getFIFORed(); //why getFIFORed output IR data by MAX30102 on MH-ET LIVE breakout board
#endif

i++;
fred = (double)red;
fir = (double)ir;
avered = avered * frate + (double)red * (1.0 - frate); //average red level by low pass filter
aveir = aveir * frate + (double)ir * (1.0 - frate);    //average IR level by low pass filter
sumredrms += (fred - avered) * (fred - avered);        //square sum of alternate component of red level
sumirrms += (fir - aveir) * (fir - aveir);             //square sum of alternate component of IR level
if ((i % SAMPLING) == 0)
{ //slow down graph plotting speed for arduino Serial plotter by thin out
  if (millis() > TIMETOBOOT)
  {
    if (ir < FINGER_ON)
      ESpO2 = MINIMUM_SPO2; //indicator for finger detached
    float temperature = particleSensor.readTemperatureF();
    if (ESpO2 <= -1)
    {
      ESpO2 = 0;
    }

    if (ESpO2 > 100)
    {
      ESpO2 = 100;
    }

    oxygen = ESpO2;

    Serial.print(" Oxygen % = ");
    Serial.println(oxygen);
  }
}
if ((i % Num) == 0)
{
  double R = (sqrt(sumredrms) / avered) / (sqrt(sumirrms) / aveir);
  // Serial.println(R);
  SpO2 = -23.3 * (R - 0.4) + 100;               //http://ww1.microchip.com/downloads/jp/AppNotes/00001525B_JP.pdf
  ESpO2 = FSpO2 * ESpO2 + (1.0 - FSpO2) * SpO2; //low pass filter
  //Serial.print(SpO2); Serial.print(","); Serial.println(ESpO2);
  sumredrms = 0.0;
  sumirrms = 0.0;
  i = 0;
  break;
}
particleSensor.nextSample(); //We're finished with this sample so move to next sample
//Serial.println(SpO2);
  }

  long irValue = particleSensor.getIR();
  Serial.println(irValue);



  if (millis() > time_2 + INTERVAL_MESSAGE2 && oxygen < 93)

  {
time_2 = millis();

Blynk.notify("Alert! Oxygen Saturation below 93% Detected");
Serial.print("Alert called");
  }

#endif
}

I think the only way you’re going to achieve this is to run the MAX30102 code in one of the ESP32 cores and the Blynk code in the other core.
How good are your coding skills?

Pete.

How can It be done ?
coding skills are basic…Not very good

In that case, it’s probably not going to happen.

I think the normal approach is to run your Blynk code in Core0, so your MAX30102 code would run in Core1.

Pete.

Heart rate code for Max30102 and ESP32 is showing zero Avg beats= 0
attached the execution.

#define BLYNK_PRINT Serial
#include <WiFi.h>
#include <BlynkSimpleEsp32.h>
#include "MAX30105.h" //sparkfun MAX3010X library
#include "heartRate.h"

SimpleTimer timer;
MAX30105 particleSensor;


const byte RATE_SIZE = 4; //Increase this for more averaging. 4 is good.
byte rates[RATE_SIZE]; //Array of heart rates
byte rateSpot = 0;
long lastBeat = 0; //Time at which the last beat occurred

float beatsPerMinute;
int beatAvg;

char auth[] = "fIGPsYeI0rf2DWG6FAPXdf-NGuhaF0Fe";


char ssid[] = "vivo 1713";
char pass[] = "fab123456";

void setup() {
  // put your setup code here, to run once:
Serial.begin(115200);
  Serial.println("Initializing...");
  Blynk.begin(auth, ssid, pass);

  // Initialize sensor
  if (!particleSensor.begin(Wire, I2C_SPEED_FAST)) //Use default I2C port, 400kHz speed
  {
Serial.println("MAX30105 was not found. Please check wiring/power. ");
while (1);
  }
  Serial.println("Place your index finger on the sensor with steady pressure.");

  particleSensor.setup(); //Configure sensor with default settings
  particleSensor.setPulseAmplitudeRed(0x0A); //Turn Red LED to low to indicate sensor is running
  particleSensor.setPulseAmplitudeGreen(0); //Turn off Green LED
  timer.setInterval(100, HR);
}

void HR(){
  long irValue = particleSensor.getIR();

  if (checkForBeat(irValue) == true)
  {
//We sensed a beat!
long delta = millis() - lastBeat;
lastBeat = millis();

beatsPerMinute = 60 / (delta / 1000.0);

if (beatsPerMinute < 255 && beatsPerMinute > 20)
{
  rates[rateSpot++] = (byte)beatsPerMinute; //Store this reading in the array
  rateSpot %= RATE_SIZE; //Wrap variable

  //Take average of readings
  beatAvg = 0;
  for (byte x = 0 ; x < RATE_SIZE ; x++)
    beatAvg += rates[x];
  beatAvg /= RATE_SIZE;
}
  }

  Serial.print("IR=");
  Serial.print(irValue);
  Serial.print(", BPM=");
  Serial.print(beatsPerMinute);
  Serial.print(", Avg BPM=");
  Serial.print(beatAvg);
  Blynk.virtualWrite(V5, beatAvg);
  if (irValue < 50000)
Serial.print(" No finger?");

  Serial.println();
}

void loop() {
  Blynk.run();
  timer.run(); // Initiates SimpleTimer
}

Execution:

@Baig I’ve moved your other post on the same topic into this one. Please don’t spam the forum with multiple posts like this.

Pete.

Ok, I Appologize. I’m new here.

@PeteKnight can you please tell what’s wrong with my HR code?

I think your void HR() code is meant to be in the void loop. which is incompatible with Blynk.
That’s why you need to run the Blynk code in one core and the MAX30102 code in another.

Pete.

I’ve tried it in the void loop but it’s showing slow results,

Is this with the original Sparkfun example sketch, or with your sketch that includes the Blynk code?

Pete.

It’s from the Sparkfun library example code to which I put the Blynk code

As I said, that approach is incompatible with Blynk.

Pete.

OKay, what amendments would you suggest ?

I’ve provided you two links in post #4 to enable you to learn about using both cores of the ESP32.

Pete.

Much thanks.