Single code for MAX30100 and Sparkfun TMP102 sensors with NodeMCU ESP8266

I am using the MAX30100 and Sparkfun TMP102 sensors with a Nodemcu esp8266. I want to run both sensors at the same time, so I have merged the two example codes for those two sensors. There is an issue with the program though, and I am unsure how to fix it. The individual example codes work fine, but there is an error with my merged code. How can I fix the merged code I've created?

Here are the connections for the sensors to the Nodemcu:

TMP102:
3.7v ==> 3v3
Gnd ==> Gnd
SDA ==> D2
SCL ==> D1
ALT ==> D0

MAX30100:
VIN ==> 3v3
Gnd ==> Gnd
SDA ==> D2
SCL ==> D1

Pictures of circuit



Sparkfun TMP102 Example1 code

#include <Wire.h> // Used to establied serial communication on the I2C bus
#include <SparkFunTMP102.h> // Used to send and recieve specific information from our sensor

// Connections
// VCC = 3.3V
// GND = GND
// SDA = A4
// SCL = A5
const int ALERT_PIN = D0;

TMP102 sensor0;
// Sensor address can be changed with an external jumper to:
// ADD0 - Address
//  VCC - 0x49
//  SDA - 0x4A
//  SCL - 0x4B

void setup() {
  Serial.begin(115200);
  Wire.begin(); //Join I2C Bus
  
  pinMode(ALERT_PIN,INPUT);  // Declare alertPin as an input
  
  /* The TMP102 uses the default settings with the address 0x48 using Wire.
  
     Optionally, if the address jumpers are modified, or using a different I2C bus,
	 these parameters can be changed here. E.g. sensor0.begin(0x49,Wire1)
	 
	 It will return true on success or false on failure to communicate. */
  if(!sensor0.begin())
  {
    Serial.println("Cannot connect to TMP102.");
    Serial.println("Is the board connected? Is the device ID correct?");
    while(1);
  }
  
  Serial.println("Connected to TMP102!");
  delay(100);

  // Initialize sensor0 settings
  // These settings are saved in the sensor, even if it loses power
  
  // set the number of consecutive faults before triggering alarm.
  // 0-3: 0:1 fault, 1:2 faults, 2:4 faults, 3:6 faults.
  sensor0.setFault(0);  // Trigger alarm immediately
  
  // set the polarity of the Alarm. (0:Active LOW, 1:Active HIGH).
  sensor0.setAlertPolarity(1); // Active HIGH
  
  // set the sensor in Comparator Mode (0) or Interrupt Mode (1).
  sensor0.setAlertMode(0); // Comparator Mode.
  
  // set the Conversion Rate (how quickly the sensor gets a new reading)
  //0-3: 0:0.25Hz, 1:1Hz, 2:4Hz, 3:8Hz
  sensor0.setConversionRate(2);
  
  //set Extended Mode.
  //0:12-bit Temperature(-55C to +128C) 1:13-bit Temperature(-55C to +150C)
  sensor0.setExtendedMode(0);

  //set T_HIGH, the upper limit to trigger the alert on
  sensor0.setHighTempF(85.0);  // set T_HIGH in F
  //sensor0.setHighTempC(29.4); // set T_HIGH in C
  
  //set T_LOW, the lower limit to shut turn off the alert
  sensor0.setLowTempF(84.0);  // set T_LOW in F
  //sensor0.setLowTempC(26.67); // set T_LOW in C
}
 
void loop()
{
  float temperature;
  boolean alertPinState, alertRegisterState;
  
  // Turn sensor on to start temperature measurement.
  // Current consumtion typically ~10uA.
  sensor0.wakeup();

  // read temperature data
  temperature = sensor0.readTempF();
  //temperature = sensor0.readTempC();

  // Check for Alert
  alertPinState = digitalRead(ALERT_PIN); // read the Alert from pin
  alertRegisterState = sensor0.alert();   // read the Alert from register
  
  // Place sensor in sleep mode to save power.
  // Current consumtion typically <0.5uA.
  sensor0.sleep();

  // Print temperature and alarm state
  Serial.print("Temperature: ");
  Serial.print(temperature);
  
  Serial.print("\tAlert Pin: ");
  Serial.print(alertPinState);
  
  Serial.print("\tAlert Register: ");
  Serial.println(alertRegisterState);
  
  delay(1000);  // Wait 1000ms
}

MAX30100 Example code

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

#define REPORTING_PERIOD_MS     1000

// PulseOximeter is the higher level interface to the sensor
// it offers:
//  * beat detection reporting
//  * heart rate calculation
//  * SpO2 (oxidation level) calculation
PulseOximeter pox;

uint32_t tsLastReport = 0;

// Callback (registered below) fired when a pulse is detected
void onBeatDetected()
{
    Serial.println("B:1");
}

void setup()
{
    Serial.begin(115200);

    // Initialize the PulseOximeter instance and register a beat-detected callback
    // The parameter passed to the begin() method changes the samples flow that
    // the library spews to the serial.
    // Options:
    //  * PULSEOXIMETER_DEBUGGINGMODE_PULSEDETECT : filtered samples and beat detection threshold
    //  * PULSEOXIMETER_DEBUGGINGMODE_RAW_VALUES : sampled values coming from the sensor, with no processing
    //  * PULSEOXIMETER_DEBUGGINGMODE_AC_VALUES : sampled values after the DC removal filter

    // Initialize the PulseOximeter instance
    // Failures are generally due to an improper I2C wiring, missing power supply
    // or wrong target chip
    if (!pox.begin(PULSEOXIMETER_DEBUGGINGMODE_PULSEDETECT)) {
        Serial.println("ERROR: Failed to initialize pulse oximeter");
        for(;;);
    }

    pox.setOnBeatDetectedCallback(onBeatDetected);
}

void loop()
{
    // Make sure to call update as fast as possible
    pox.update();

    // Asynchronously dump heart rate and oxidation levels to the serial
    // For both, a value of 0 means "invalid"
    if (millis() - tsLastReport > REPORTING_PERIOD_MS) {
        Serial.print("H:");
        Serial.println(pox.getHeartRate());

        Serial.print("O:");
        Serial.println(pox.getSpO2());

        tsLastReport = millis();
    }
}

My Merged Code

#include <Wire.h> // Used to establied serial communication on the I2C bus
#include <SparkFunTMP102.h> // Used to send and recieve specific information from our sensor
#include "MAX30100_PulseOximeter.h"
#define REPORTING_PERIOD_MS     1000
const int ALERT_PIN = D0;
TMP102 sensor0;


PulseOximeter pox
uint32_t tsLastReport = 0;
void onBeatDetected()
{
  Serial.println("B:1");
}



void setup()
{
  Serial.begin(115200);
  Wire.begin(); //Join I2C Bus

  pinMode(ALERT_PIN, INPUT);

  if (!sensor0.begin())
  {
    Serial.println("Cannot connect to TMP102.");
    Serial.println("Is the board connected? Is the device ID correct?");
    while (1);
  }

  Serial.println("Connected to TMP102!");
  delay(100);

  // set the number of consecutive faults before triggering alarm.
  // 0-3: 0:1 fault, 1:2 faults, 2:4 faults, 3:6 faults.
  sensor0.setFault(0);  // Trigger alarm immediately

  // set the polarity of the Alarm. (0:Active LOW, 1:Active HIGH).
  sensor0.setAlertPolarity(1); // Active HIGH

  // set the sensor in Comparator Mode (0) or Interrupt Mode (1).
  sensor0.setAlertMode(0); // Comparator Mode.

  // set the Conversion Rate (how quickly the sensor gets a new reading)
  //0-3: 0:0.25Hz, 1:1Hz, 2:4Hz, 3:8Hz
  sensor0.setConversionRate(2);

  //set Extended Mode.
  //0:12-bit Temperature(-55C to +128C) 1:13-bit Temperature(-55C to +150C)
  sensor0.setExtendedMode(0);

  //set T_HIGH, the upper limit to trigger the alert on
  sensor0.setHighTempF(85.0);  // set T_HIGH in F
  //sensor0.setHighTempC(29.4); // set T_HIGH in C

  //set T_LOW, the lower limit to shut turn off the alert
  sensor0.setLowTempF(84.0);  // set T_LOW in F
  //sensor0.setLowTempC(26.67); // set T_LOW in C


  if (!pox.begin(PULSEOXIMETER_DEBUGGINGMODE_PULSEDETECT)) {
    Serial.println("ERROR: Failed to initialize pulse oximeter");
    for (;;);
  }

  pox.setOnBeatDetectedCallback(onBeatDetected);
}


void loop()
{
  float temperature;
  boolean alertPinState, alertRegisterState;

  // Turn sensor on to start temperature measurement.
  // Current consumtion typically ~10uA.
  sensor0.wakeup();

  // read temperature data
  temperature = sensor0.readTempF();
  //temperature = sensor0.readTempC();

  // Check for Alert
  alertPinState = digitalRead(ALERT_PIN); // read the Alert from pin
  alertRegisterState = sensor0.alert();   // read the Alert from register

  // Place sensor in sleep mode to save power.
  // Current consumtion typically <0.5uA.
  sensor0.sleep();

  // Print temperature and alarm state
  Serial.print("Temperature: ");
  Serial.print(temperature);

  Serial.print("\tAlert Pin: ");
  Serial.print(alertPinState);

  Serial.print("\tAlert Register: ");
  Serial.println(alertRegisterState);


  // Make sure to call update as fast as possible
  pox.update();

  // Asynchronously dump heart rate and oxidation levels to the serial
  // For both, a value of 0 means "invalid"
  if (millis() - tsLastReport > REPORTING_PERIOD_MS) {
    Serial.print("H:");
    Serial.println(pox.getHeartRate());

    Serial.print("O:");
    Serial.println(pox.getSpO2());

    tsLastReport = millis();
  }

  delay(1000);  // Wait 1000ms
}

With the sensors wired as is and the I2C scanner code is ran, what are the results?

It hasn't compiled because there are some errors in the code, I'm not sure how to fix them though. Here's a picture of the errors that pop up

First one

Example: PulseOximeter pox;

Merged: PulseOximeter pox

Spot the difference?
Leo..

Not related to your error, but...suggestions:

  1. delete the delay(1000); at the end of loop()
  2. put all of the temperature code in loop() inside the "if (millis()...)" statement.

That way you'll be calling pox.update() "as fast as possible" and you will still get all of your data every REPORTING_PERIOD_MS (defined as one second).

Also, suggest deleting the temperature sensor wakeup and sleep lines. They're superfluous, unless you are running on a battery, and they add a bit of delay (takes about 1/4 second to wake).

Thank you, now the code is compiling. Although, when I run the code, only the values from the TMP102 are getting displayed on the serial monitor. Am I missing something from the code?
Heres a picture of the serial monitor when I run the merged code


It's supposed to display the values from the Tmp102 AND the MAX30100.

As DaveEvans suggested, remove that delay(1000) and move the temp code inside the if() statement.
Just before tsLastReport = millis();
Because that if statement already has a 1000ms reporting/waiting time.

You can wake/sleep the temp sensor also inside the if() statement, just before and after the temp code.
Leo..

Here is the merged code that we are working on to work with temperature and oximeter sensors..
We used pull up resistors on the b/w the TM102 and MAX30100, but still getting error on teh serial console. Should we use a I2C multiplexer ?
#include <Wire.h>
#include "MAX30100_PulseOximeter.h"
#include <SparkFunTMP102.h>
#define REPORTING_PERIOD_MS 60000
PulseOximeter pox;
uint32_t tsLastReport = 0;
TMP102 sensor0;

void onBeatDetected()
{
Serial.println("Beat!");
}

void setup()
{
Serial.begin(115200);
sensor0.wakeup();
Serial.print("Initializing pulse oximeter..");

// Initialize the PulseOximeter instance
// Failures are generally due to an improper I2C wiring, missing power supply

sensor0.setFault(0); // Trigger alarm immediately

// set the polarity of the Alarm. (0:Active LOW, 1:Active HIGH).
sensor0.setAlertPolarity(1); // Active HIGH

// set the sensor in Comparator Mode (0) or Interrupt Mode (1).
sensor0.setAlertMode(0); // Comparator Mode.

// set the Conversion Rate (how quickly the sensor gets a new reading)
//0-3: 0:0.25Hz, 1:1Hz, 2:4Hz, 3:8Hz
sensor0.setConversionRate(2);

//set Extended Mode.
//0:12-bit Temperature(-55C to +128C) 1:13-bit Temperature(-55C to +150C)
sensor0.setExtendedMode(0);

//set T_HIGH, the upper limit to trigger the alert on
sensor0.setHighTempF(85.0); // set T_HIGH in F
//sensor0.setHighTempC(29.4); // set T_HIGH in C

//set T_LOW, the lower limit to shut turn off the alert
sensor0.setLowTempF(84.0); // set T_LOW in F
//sensor0.setLowTempC(26.67); // set T_LOW in C

// The default current for the IR LED is 50mA and it could be changed
//   by uncommenting the following line. Check MAX30100_Registers.h for all the
//   available options.
// pox.setIRLedCurrent(MAX30100_LED_CURR_7_6MA);

// Register a callback for the beat detection
pox.setOnBeatDetectedCallback(onBeatDetected);

}

void loop()
{
float temperature;
// Make sure to call update as fast as possible
pox.update();
temperature = sensor0.readTempF();
// Asynchronously dump heart rate and oxidation levels to the serial
// For both, a value of 0 means "invalid"
if (millis() - tsLastReport > REPORTING_PERIOD_MS) {
Serial.print("Temperature: ");
Serial.print(temperature);
Serial.print("Heart rate:");
Serial.print(pox.getHeartRate());
Serial.print("bpm / SpO2:");
Serial.print(pox.getSpO2());
Serial.println("%");

    tsLastReport = millis();
}

}

=================================================================
Serial console error:
13:23:56.838 -> --------------- CUT HERE FOR EXCEPTION DECODER ---------------
13:23:56.838 ->
13:23:56.838 -> ets Jan 8 2013,rst cause:2, boot mode:(3,6)
13:23:56.838 ->
13:23:56.838 -> load 0x4010f000, len 3460, room 16
13:23:56.838 -> tail 4
13:23:56.838 -> chksum 0xcc
13:23:56.838 -> load 0x3fff20b8, len 40, room 4
13:23:56.838 -> tail 4
13:23:56.884 -> chksum 0xc9
13:23:56.884 -> csum 0xc9
13:23:56.884 -> v00043fc0
13:23:56.884 -> ~ld
13:23:56.931 ->
13:23:56.931 -> --------------- CUT HERE FOR EXCEPTION DECODER ---------------
13:23:56.931 ->
13:23:56.931 -> Exception (28):
13:23:56.931 -> epc1=0x40201db6 epc2=0x00000000 epc3=0x00000000 excvaddr=0x00000000 depc=0x00000000
13:23:56.931 ->
13:23:56.931 -> >>>stack>>>
13:23:56.931 ->
13:23:56.931 -> ctx: cont
13:23:56.931 -> sp: 3ffffde0 end: 3fffffc0 offset: 0190
13:23:56.931 -> 3fffff70: 00000000 feefeffe feefeffe 40201db4
13:23:56.931 -> 3fffff80: 0001c200 3ffee730 3ffee538 40201ff0
13:23:56.931 -> 3fffff90: 3fffdad0 3ffee730 3ffee538 4020107b
13:23:56.978 -> 3fffffa0: feefeffe 00000000 3ffee784 40202d5c
13:23:56.978 -> 3fffffb0: feefeffe feefeffe 3ffe85d8 40100b55
13:23:56.978 -> <<<stack<<<
13:23:56.978 ->
13:23:56.978 -> --------------- CUT HERE FOR EXCEPTION DECODER ---------------
13:23:56.978 ->
13:23:56.978 -> ets Jan 8 2013,rst cause:2, boot mode:(3,6)
13:23:56.978 ->
13:23:56.978 -> load 0x4010f000, len 3460, room 16
13:23:56.978 -> tail 4
13:23:56.978 -> chksum 0xcc
13:23:56.978 -> load 0x3fff20b8, len 40, room 4
13:23:56.978 -> tail 4
13:23:56.978 -> chksum 0xc9
13:23:56.978 -> csum 0xc9
13:23:57.024 -> v00043fc0
13:23:57.024 -> ~ld
13:23:57.071 ->

Code tags?

I'd load up the ESP Exception Decoder into the Arduino IDE to decode the error message into something a bit more useful.

I'd comment out every line in the loop() function. Then I'd comment every line in setup(). Then upload, does it produce the error?

No. Uncomment a few lines in setup, does it make error after upload? Yes. No.

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