Using both max30102 and mlx90614, but

I am a beginner.
I am using the max30102 SpO2 sensor and mlx90614 temperature sensor connected to ESP32 devkit V1 via I2C. When I write a sketch that uses two sensors at the same time, I don't get the correct value from either sensor. If I use either sensor, I can get a normal value.
Please tell me how to use two sensors at the same time.
I'm sorry I'm not good at English.

The sketch is below. I used the library example to simplify it.

#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;

#include <Wire.h>
#include <Adafruit_MLX90614.h>

Adafruit_MLX90614 mlx = Adafruit_MLX90614();

#define DEBUG1 1
#define DEBUG2 1

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

#if DEBUG1
// max30102/5
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
#endif

#if DEBUG2
// max90614
mlx.begin();
#endif

}

void loop()
{

#if DEBUG1
// max30102/5
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();
#endif

#if DEBUG2
// max90614
Serial.print("Ambient = "); Serial.print(mlx.readAmbientTempC());
Serial.print("*C\tObject = "); Serial.print(mlx.readObjectTempC()); Serial.println("*C");
Serial.print("Ambient = "); Serial.print(mlx.readAmbientTempF());
Serial.print("*F\tObject = "); Serial.print(mlx.readObjectTempF()); Serial.println("*F");

Serial.println();
delay(500);
#endif

}

The "Serial.print" at the time of the above sketch is as follows.

IR=6416, BPM=0.00, Avg BPM=0 No finger?
Ambient = nanC Object = nanC
Ambient = nanF Object = nanF

IR=6291, BPM=0.00, Avg BPM=0 No finger?
Ambient = nanC Object = nanC
Ambient = nanF Object = nanF

1 Like

I think you should replace

#define DEBUG1 1
#define DEBUG2 1

by
#define DEBUG
and use something like this in you code:

#ifdef DEBUG
  .......
#else
 ......
#endif

Thank you for your consideration. But it's not the intention of my question.

When using both max30102 and mlx90416 statements,
DEBUG1 1
DEBUG2 1
This is the case where the sensor values are incorrect.

Then for example,
DEBUG1 0
allows you to compile statements that are only mlx90416.
At this time, the sensor value becomes normal.

To solve the problem, do I manipulate the register address of the I2C sensor?

0x57 ---> SpO2 sensor
0x5A ---> Temp sensor
I looked it up.

It is self resolved.
The solution is to change the I2C clock speed at mlx90614.
Both sensors now output the correct values as below.

IR=6772, BPM=0.80, Avg BPM=0 No finger?
Ambient = 28.19C Object = 25.81C
Ambient = 82.74F Object = 78.46F

I looked up various information on the Internet.
I found an article about lowering the I2C clock speed as a countermeasure to fix the value at mlx90614.
I tried a method of dynamically adjusting the frequency before and after the I2C communication part of the Adafruit library source code "Adafruit_MLX90614.cpp" and it worked.

Adafruit_MLX90614.cpp around line 130,

/*********************************************************************/

uint16_t Adafruit_MLX90614::read16(uint8_t a) {
uint8_t buffer[3];
buffer[0] = a;
Wire.setClock(50000);
// read two bytes of data + pec
bool status = i2c_dev->write_then_read(buffer, 1, buffer, 3);
if (!status)
return 0;
Wire.setClock(100000);
// return data, ignore pec
return uint16_t(buffer[0]) | (uint16_t(buffer[1]) << 8);
}

2 Likes

@goblins Could you please help me solving this, As I face the same issue. I went through solution but can't find it.

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.