Skip to content

Adafruit_MLX90614 and MAX30102 Not working#4561

@fervidautomation

Description

@fervidautomation

Make your question, not a Statement, inclusive. Include all pertinent information:

What you are trying to do
I tried to use ESP32 wroom dev board and use Adafruit_MLX90614 and MAX30102 sensor on I2C communication. As you might know both works on I2C communication. but It did not work. Any piece of advice will be highly appreciated.

Describe your system (Hardware, computer, O/S, core version, environment)
ESP32 Wroom dev MLX90614 and MAX30102
Describe what is failing
MAX30102 provide the data but mlx does not. If I am using a separate-2 2 programs then It is working fine.Which is kind of indication that the wiring is correct.

/*

simple SpO2 plotter for MH-ET LIVE MAX30102 breakout board and ESP32 devkit-C

Using Sparkfun MAX3010X library
https://github.com/sparkfun/SparkFun_MAX3010x_Sensor_Library

ESP32_MAX30102_simple-SpO2_plotter.ino
by coniferconifer Copyright 2020
LICENSED under Apache License 2.0

Version 1.0

Shows SpO2 and the user's heart beat on Arduino's serial plotter.
No display hardware is required.
This program should not be used for medical purposes.
I wrote this to learn how SpO2 can be measured and pay tributes for the inventors.

Pulse oximetry was developed in 1972, by Takuo Aoyagi and Michio Kishi,
bioengineers, at Nihon Kohden in Japan.
https://ethw.org/Takuo_Aoyagi

Since MH-ET LIVE MAX30102 breakout board seems outputting IR and RED swapped.
red = particleSensor.getFIFOIR();
ir = particleSensor.getFIFORed();
is used in my code. If you have Sparkfun's MAX30105 breakout board , try to
use #define MAX30105

Tips:

SpO2 is calculated as R=((square root means or Red/Red average )/((square root means of IR)/IR average))
SpO2 = -23.3 * (R - 0.4) + 100;
// taken from a graph in https://ww1.microchip.com/downloads/jp/AppNotes/00001525B_JP.pdf
// https://ww1.microchip.com/downloads/en/Appnotes/00001525B.pdf

Instructions:

  1. Install Sparkfun's MAX3010X library
  2. Load code onto ESP32 with MH-ET LIVE MAX30102 board
  3. Put MAX30102 board in plastic bag and insulates from your finger.
    and attach sensor to your finger tip
  4. Run this program by pressing reset botton on ESP32
  5. Wait for 3 seconds and Open Arduino IDE Tools->'Serial Plotter'
    Make sure the drop down is set to 115200 baud
  6. Search the best position and presure for the sensor by watching
    the blips on Arduino's serial plotter
    I recommend to place LED under the backside of nail and wrap you
    finger and the sensor by rubber band softly.
  7. Checkout the SpO2 and blips by seeing serial Plotter
    100%,95%,90%,85% SpO2 lines are always drawn on the plotter

Hardware Connections (Breakoutboard to ESP32 Arduino):

-VIN = 3.3V
-GND = GND
-SDA = 21 (or SDA)
-SCL = 22 (or SCL)
-INT = Not connected

this script also works on Arduino nao

Hardware Connections (Breakoutboard to Arduino nano): experimental

-VIN = 3.3V
-GND = GND
-SDA = A4 (or SDA)
-SCL = A5 (or SCL)
-INT = Not connected

Trouble Shooting:

Make sure to solder jumper on 3V3 side.
if you forget this, I2C does not work and can not find MAX30102.
says "MAX30102 was not found. Please check wiring/power."

*/

#include<Wire.h> #include"MAX30105.h"//sparkfun MAX3010X library #include<Adafruit_MLX90614.h>bool status; Adafruit_MLX90614 mlx = Adafruit_MLX90614(0x5A); MAX30105 particleSensor; TwoWire I2CBME = TwoWire(0); //#define MAX30105 //if you have Sparkfun's MAX30105 breakout board , try #define MAX30105  #defineUSEFIFO #defineI2C_SDA33//21 #defineI2C_SCL32//22voidsetup(){// Serial.begin(9600); Serial.begin(115200); I2CBME.begin(I2C_SDA, I2C_SCL, I2C_SPEED_FAST); // Serial.println("mlx start Initializing...");//status = mlx.begin();  Serial.print(status) ; // mlx.begin(); mlx.begin(); // Serial.println("mls end Initializing...");// Serial.println("max start Initializing...") ;// Initialize sensor//if (!particleSensor.begin(Wire, I2C_SPEED_FAST)) //Use default I2C port, 400kHz speedif (!particleSensor.begin(I2CBME, I2C_SPEED_FAST ,0x57)) //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); } //Setup to sense a nice looking saw tooth on the plotter byte ledBrightness = 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//Options: 1 = IR only, 2 = Red + IR on MH-ET LIVE MAX30102 boardint sampleRate = 200; //Options: 50, 100, 200, 400, 800, 1000, 1600, 3200int pulseWidth = 411; //Options: 69, 118, 215, 411int 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 } double avered = 0; double aveir = 0; double sumirrms = 0; double sumredrms = 0; int i = 0; int Num = 100;//calculate SpO2 by this sampling intervaldouble ESpO2 = 95.0;//initial value of estimated SpO2double FSpO2 = 0.7; //filter factor for estimated SpO2double frate = 0.95; //low pass filter for IR/red LED value to eliminate AC component #defineTIMETOBOOT3000// wait for this time(msec) to output SpO2 #defineSCALE88.0//adjust to display heart beat and SpO2 in the same scale #defineSAMPLING5//if you want to see heart beat more precisely , set SAMPLING to 1 #defineFINGER_ON30000// if red signal is lower than this , it indicates your finger is not on the sensor #defineMINIMUM_SPO280.0voidloop(){Serial.print("status is mlx " + status) ; Serial.println("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"); 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 sampleswhile (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++; mlx.begin(); 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(1000); 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 levelif ((i % SAMPLING) == 0){//slow down graph plotting speed for arduino Serial plotter by thin outif ( millis() > TIMETOBOOT){float ir_forGraph = (2.0 * fir - aveir) / aveir * SCALE; float red_forGraph = (2.0 * fred - avered) / avered * SCALE; //trancation for Serial plotter's autoscalingif ( ir_forGraph > 100.0) ir_forGraph = 100.0; if ( ir_forGraph < 80.0) ir_forGraph = 80.0; if ( red_forGraph > 100.0 ) red_forGraph = 100.0; if ( red_forGraph < 80.0 ) red_forGraph = 80.0; // Serial.print(red); Serial.print(","); Serial.print(ir);Serial.print(".");if (ir < FINGER_ON) ESpO2 = MINIMUM_SPO2; //indicator for finger detached Serial.print(ir_forGraph); // to display pulse wave at the same time with SpO2 data Serial.print(","); Serial.print(red_forGraph); // to display pulse wave at the same time with SpO2 data Serial.print(","); Serial.print(ESpO2); //low pass filtered SpO2 Serial.print(","); Serial.print(85.0); //reference SpO2 line Serial.print(","); Serial.print(90.0); //warning SpO2 line Serial.print(","); Serial.print(95.0); //safe SpO2 line Serial.print(","); Serial.println(100.0); //max SpO2 linedelay(3000)} } 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); } #elsewhile (1){//do we have new data #ifdef MAX30105 red = particleSensor.getRed(); //Sparkfun's MAX30105 ir = particleSensor.getIR(); //Sparkfun's MAX30105 #else red = particleSensor.getIR(); //why getFOFOIR outputs Red data by MAX30102 on MH-ET LIVE breakout board ir = particleSensor.getRed(); //why getFIFORed outputs 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 levelif ((i % SAMPLING) == 0){//slow down graph plotting speed for arduino IDE toos menu by thin out//#if 0if ( millis() > TIMETOBOOT){float ir_forGraph = (2.0 * fir - aveir) / aveir * SCALE; float red_forGraph = (2.0 * fred - avered) / avered * SCALE; //trancation for Serial plotter's autoscalingif ( ir_forGraph > 100.0) ir_forGraph = 100.0; if ( ir_forGraph < 80.0) ir_forGraph = 80.0; if ( red_forGraph > 100.0 ) red_forGraph = 100.0; if ( red_forGraph < 80.0 ) red_forGraph = 80.0; // Serial.print(red); Serial.print(","); Serial.print(ir);Serial.print(".");if (ir < FINGER_ON) ESpO2 = MINIMUM_SPO2; //indicator for finger detached Serial.print((2.0 * fir - aveir) / aveir * SCALE); // to display pulse wave at the same time with SpO2 data Serial.print(","); Serial.print((2.0 * fred - avered) / avered * SCALE); // to display pulse wave at the same time with SpO2 data Serial.print(","); Serial.print(ESpO2); //low pass filtered SpO2 Serial.print(","); Serial.print(85.0); // Serial.print(","); Serial.print(90.0); //warning SpO2 line Serial.print(","); Serial.print(95.0); //safe SpO2 line Serial.print(","); Serial.println(100.0); //max SpO2 line//#endif Serial.println(); delay(1000)} } 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; // 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); } #endif } 

Metadata

Metadata

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions