Hardware Interrupt Pin Clearing with I2C

Hello,

I’m working with the MAX30102 which I’m communicating with via my Arduino Uno over I2C. The MAX30102 has an active low interrupt pin that is connected the positive voltage supply by a pullup resistor. The data sheet states that reading the interrupt status register or the register triggering the interrupt will clear the interrupt and reset the pin from low back to its default high state. I’ve been trying to use an ISR to take a temperature reading from the chip and display it, but the sketch gets stuck inside the ISR and stops running the main loop. I’m not sure what else to try.

I have INT wired to digital pin 3, SDA to pin A4, and SCL to pin A5. I’ve hooked up SCL and SDA to my scope and confirmed that the MAX30102 is communicating with the Uno correctly as far as read and write operations go, but the ISR is throwing things off.

#include <Wire.h>

#define ADD  B1010111

volatile float temp;


void setup() {
  
  Wire.begin();
  Serial.begin(9600);
  while(!Serial);

  pinMode(3, INPUT);

  resetMAX30102();
  initializeInterruptStatus();

  // Enable Temperature Reading Interrupt
  writeToRegister(0x03, 2);

  attachInterrupt(digitalPinToInterrupt(3), temperature, LOW);

  // Initialize temperature reading
  writeToRegister(0x21, 1);
}

void loop() {
  delay(1000);
  Serial.println(temp);
}

void temperature() {
  readFromRegister(0x20);
  temp = readFromRegister(0x21);
  readFromRegister(0x01);
}

void writeToRegister(uint8_t regist, uint8_t value) {
  Wire.beginTransmission(ADD);
  Wire.write(regist);
  Wire.write(value);
  Wire.endTransmission();
}

uint8_t readFromRegister(uint8_t regist) {
  Wire.beginTransmission(ADD);
  Wire.write(regist);
  Wire.endTransmission();

  Wire.requestFrom(ADD, 1);
  if (Wire.available()) {
    return Wire.read();
  }
}

void initializeInterruptStatus() {
  readFromRegister(0x00);
  readFromRegister(0x01);
}

void resetMAX30102() {
  writeToRegister(0x09, 0x40);
}

Rule 1 do no processing in interrupt routines that gets you into trouble. Simply set or clear a global flag and check it in your main loop. Why. when you are in an interrupt service routine interrupts are blocked.

This is trouble too:

attachInterrupt(digitalPinToInterrupt(3), temperature, LOW);

Make if FALLING instead of LOW.

gilshultz:
Rule 1 do no processing in interrupt routines that gets you into trouble. Simply set or clear a global flag and check it in your main loop. Why. when you are in an interrupt service routine interrupts are blocked.

Brilliant. Makes sense and fixed my problem.

gfvalvo:
This is trouble too:

attachInterrupt(digitalPinToInterrupt(3), temperature, LOW);

Make if FALLING instead of LOW.

Yep. Had set to FALLING originally and changed it just to see if it would have an affect. I have changed it back now.

Thank you!