2

max30100 i2c sensor gives heartrate and spo2 reading in serial and also can show values in lcd display. I want to show it's indication via LED.

If SpO2 value <94 , it will turn on Red led in digital pin 4

If SpO2 value >=94, it will urn on Green led in digital pin 5

Here pox.getSpO2() gives the SpO2 value.

How can I use this value to toggle between two digital pin. I understand it's easier to read analog pin value for toggling but I am searching for guidelines how I2C values can be use for this condition.

Thank you.

Here is the minimalistic code of SpO2

#include <Wire.h>
#include "MAX30100_PulseOximeter.h"
#define REPORTING_PERIOD_MS 1000
PulseOximeter pox;
uint32_t tsLastReport = 0;
void setup()
{
 Serial.begin(9600);
 Serial.print("Initializing pulse oximeter..");
 if (!pox.begin()) {
 Serial.println("FAILED");
 for(;;);
 } else {
 Serial.println("SUCCESS");
 }
}
void loop()
{
 pox.update();
 if (millis() - tsLastReport > REPORTING_PERIOD_MS) {
 Serial.print("SpO2:");
 Serial.print(pox.getSpO2());
 Serial.println("%");
 tsLastReport = millis();
 }
}
asked Aug 13, 2021 at 13:11

1 Answer 1

2

You've done all the hard work already by setting the sensor up and managing to read from it.

I'd define a constant for the SpO2 threshold near the top, and convenient names for the pins:

const uint8_t SpO2_threshold = 94; // percent
const uint8_t red_pin = 4;
const uint8_t green_pin = 5;

Then set the pins to output mode in the setup() as usual. (Maybe set them both HIGH (or LOW) too in there, to indicate that no reading has been done yet.)

In the loop, inside the reporting section, simply grab the value and toggle the pins:

...
uint8_t spo2 = pox.getSpO2();
// Print it out to serial if needed, then:
if (spo2 < SpO2_threshold) {
 digitalWrite(green_pin, LOW);
 digitalWrite(red_pin, HIGH);
} else {
 digitalWrite(red_pin, LOW);
 digitalWrite(green_pin, HIGH);
}

A more involved version that pulses one LED (short on time, variable off time) depending on the value read from the sensor. It uses the same technique as the sensor reading timing (the one used in the "blink without delay" example).

Sensor readings are clamped (any value at or below spo2_min will result in the fasted blink time, over spo2_max the slowest). Then that range is mapped to a range of led off times. Don't use the values in this example, I'm not a medical doctor :-)

// pin mapping
const uint8_t led_pin = LED_BUILTIN;
// sensor readings (%)
const int spo2_min = 85;
const int spo2_max = 100;
// led timings (ms)
const unsigned long led_off_min = 50;
const unsigned long led_off_max = 5000;
unsigned long led_off_time = led_off_max; // variable off time
const unsigned long led_on_time = 50; // fixed, short on time
// sensor reading timing (ms)
const unsigned long sensor_interval = 1000;
// led state
uint8_t led_state = LOW;
// "timer" state
unsigned long last_reading = 0;
unsigned long last_led_toggle = 0;
void setup() {
 pinMode(led_pin, OUTPUT);
 digitalWrite(led_pin, led_state);
 Serial.begin(9600);
 Serial.print("Initializing pulse oximeter..");
 if (!pox.begin()) {
 Serial.println("FAILED");
 for (;;);
 } else {
 Serial.println("SUCCESS");
 }
}
void loop() {
 pox.update();
 unsigned long current_millis = millis();
 /* sensor reading "timer" */
 if (current_millis - last_reading >= sensor_interval)
 {
 last_reading = current_millis;
 int spo2 = pox.getSpO2();
 // clamp reading to expected range
 int clamped = constrain(spo2, spo2_min, spo2_max);
 // map to off time range
 led_off_time = map(clamped,
 spo2_min, spo2_max,
 led_off_min, led_off_max);
 char buff[128];
 sprintf_P(buff, PSTR("reading: %d (%%) -> interval: %lu (ms)"),
 spo2, led_off_time);
 Serial.println(buff);
 }
 /* led toggling "timers" */
 unsigned long led_elapsed = current_millis - last_led_toggle;
 if ((led_state == LOW) && (led_elapsed >= led_off_time))
 {
 last_led_toggle = current_millis;
 led_state = HIGH;
 digitalWrite(led_pin, led_state);
 }
 else if ((led_state == HIGH) && (led_elapsed >= led_on_time))
 {
 last_led_toggle = current_millis;
 led_state = LOW;
 digitalWrite(led_pin, led_state);
 }
}
answered Aug 13, 2021 at 15:26
7
  • Thanks a lot. I already tried earlier same as this way and it's working. You explanations made it more clearly understandable to me. Thank you. Commented Aug 13, 2021 at 16:18
  • Hello, how about using only single red led via giving pulse. If <94, led will blink rapidly. if >=94, led will blink slowly. I tried to add delay(); but it works when using around 10ms delay. but for 500ms delay, spo2 loops also gets delay and it only show 0%. Doesn't work for larger delay cycle. Any thoughts ? Commented Aug 13, 2021 at 23:12
  • 1
    delay is not your friend. Use the same technique as you did for the sensor readings, i.e. check the time elapsed since you last toggled the LED, and toggle it if that is longer than your threshold. Added an example. Probably won't be great if you're only receiving ints in a rather small range - you don't have much granularity. Commented Aug 14, 2021 at 8:10
  • 1
    Other note: if you need need more complicated than this, I'd recommend you find a timer library that you like, and look into state machines also. Lots of examples and docs on both these topics. Commented Aug 14, 2021 at 8:33
  • 1
    There was an error in the printf format string, fixed it, but can't reproduce what you are seeing. The only place where the speed changes is in the sensor update part. If you want to print something based on the reading value, it must go in there. If you want to repeat it, then you need to save it so that the last reading is available elsewhere in the loop. Commented Aug 16, 2021 at 21:34

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.