NAN value a BIG problem

I make this project “How to Make Blood Oxygen & Body Temperature Measurement - Arduino Project Hub” but instead of the measured SOP2 value, NAN appears on the display. I really don’t know why, where the problem comes from.
What needs to be changed in the code?
I really need help, please!
Link for the code:
Arduino Create

The easier you make it to read and copy the code the more likely it is that you will get help

Please follow the advice given in the link below when posting code

If you post it here maybe someon can help.

Guidelines on posting code will be found at the link below;

I can’t attach the code! :roll_eyes:


Why, what happens when you try?

To add code please click this link;

Thanks… Tom… :grinning: :+1: :coffee: :australia:

Use Copy for forum from the IDE and post it here. Not usually much to go wrong in my experience

Because I’m a new user and don’t can upload attachment.

Don’t attach the code, post it as described


1 In the IDE select the “Edit” tab
2 Then select “copy for the Forum”
3 Then move to the post edit window of the forum and , right click your mouse then select “paste”

Tom… :grinning: :+1: :coffee: :australia:

Thank you very much, i put the link to the code in my post at the description. Now i think it’s ok.


Sorry no sign of it.
Please post it in a new post, don’t go back and edit an old post.

Tom… :grinning: :+1: :coffee: :australia:

I make one project but instead of the measured SOP2 value, NAN appears on the display. I really don’t know why, where the problem comes from.
What needs to be changed in the code?
I really need help, please!
Link for the code:

This is circuit diagram.

Everything works on the board, the code doesn’t have errors but does not show me the value of oxygen on the display, NAN appears instead of that value.

I’ve merged your cross-posts @scarlatmd.

Cross-posting is against the rules of the forum. The reason is that duplicate posts can waste the time of the people trying to help. Someone might spend 15 minutes (or more) writing a detailed answer on this topic, without knowing that someone else already did the same in the other topic.

Repeated cross-posting will result in a suspension from the forum.

In the future, please take some time to pick the forum board that best suits the topic of your question and then only post once to that forum board. This is basic forum etiquette, as explained in the “How to get the best out of this forum” guide you will find at the top of every forum category. It contains a lot of other useful information. Please read it.

Thanks in advance for your cooperation.

OPs code, I think…

#include <heartRate.h>
#include <MAX30105.h>
#include <spo2_algorithm.h>
#include <LiquidCrystal_I2C.h>
#include <Wire.h>
#include <Adafruit_MLX90614.h>
#include <EEPROM.h>
#include "MAX30105.h" //sparkfun MAX3010X library
MAX30105 particleSensor;
LiquidCrystal_I2C lcd(0x27,20,4);
//#define MAX30105 //if you have Sparkfun's MAX30105 breakout board , try #define MAX30105 
Adafruit_MLX90614 mlx = Adafruit_MLX90614();

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 Temperature;
int temp;
float ESpO2;//initial value of estimated SpO2
float ESpO2_ROM;
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 30000 // if red signal is lower than this , it indicates your finger is not on the sensor
#define USEFIFO
#define Greenled 8
#define Redled 9
void setup()
  ESpO2 = readEEPROM();
  Temperature =;
  // 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);

  //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 board
  int sampleRate = 100; //Options: 50, 100, 200, 400, 800, 1000, 1600, 3200
  int pulseWidth = 411; //Options: 69, 118, 215, 411
  int adcRange = 4096; //Options: 2048, 4096, 8192, 16384
  // Set up the wanted parameters
  particleSensor.setup(ledBrightness, sampleAverage, ledMode, sampleRate, pulseWidth, adcRange); //Configure sensor with these settings


void loop()
  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
    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
    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) {
        float ir_forGraph = (2.0 * fir - aveir) / aveir * SCALE;
        float red_forGraph = (2.0 * fred - avered) / avered * SCALE;
        //trancation for Serial plotter's autoscaling
        if ( 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;
        float temperature = particleSensor.readTemperatureF();
        if (ir < FINGER_ON){
        temp = Temperature;
        ESpO2_ROM = ESpO2;
        lcd.print("Last test: ");
        lcd.print(" ");
        lcd.print("% ");

        lcd.print("Last temp: ");
        lcd.print(" ");
        if(ir > FINGER_ON){
        Temperature = mlx.readObjectTempC();
        lcd.print("Oxygen % = ");
        lcd.print(" ");
        lcd.print("% ");
       //Temperature = Temperature+2;
        lcd.print("Temperature: ");
        lcd.print(" *C");
        if((ESpO2 >= 90) && (Temperature < 38)){
        if((ESpO2 < 90) || (Temperature > 37)){

    if ((i % Num) == 0) {
      double R = (sqrt(sumredrms) / avered) / (sqrt(sumirrms) / aveir);
      SpO2 = -23.3 * (R - 0.4) + 100; //
      ESpO2 = FSpO2 * ESpO2 + (1.0 - FSpO2) * SpO2;//low pass filter
      sumredrms = 0.0; sumirrms = 0.0; i = 0;
    particleSensor.nextSample(); //We're finished with this sample so move to next sample

void writeEEPROM(float *data)
 byte ByteArray[4];
 memcpy(ByteArray, data, 4);
 for(int x = 0; x < 4; x++)
   EEPROM.write(x, ByteArray[x]);


float readEEPROM()
  float ESpO2 = 85.0;
  byte ByteArray[4];
  for(int x = 0; x < 4; x++)
   ByteArray[x] =;    
  memcpy(&ESpO2, ByteArray, 4);
  return ESpO2;

Tom… :grinning: :+1: :coffee: :australia:

Can you please post some pictures of your project, so we can see your component layout?

Tom… :grinning: :+1: :coffee: :australia:

Yes, of course!!