user79768: 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();
    }
}


user69563: 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);
  }

}


79768: <p>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.</p>
<p>If SpO2 value &lt;94 , it will turn on Red led in digital pin 4</p>
<p>If SpO2 value &gt;=94, it will urn on Green led in digital pin 5</p>
<p>Here <strong>pox.getSpO2()</strong> gives the SpO2 value.</p>
<p>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.</p>
<p>Thank you.</p>
<p>Here is the minimalistic code of SpO2</p>
<pre><code>#include &lt;Wire.h&gt;
#include &quot;MAX30100_PulseOximeter.h&quot;
#define REPORTING_PERIOD_MS     1000

PulseOximeter pox;
uint32_t tsLastReport = 0;

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

    Serial.print(&quot;Initializing pulse oximeter..&quot;);

    if (!pox.begin()) {
        Serial.println(&quot;FAILED&quot;);
        for(;;);
    } else {
        Serial.println(&quot;SUCCESS&quot;);
    }
}

void loop()
{

    pox.update();

    if (millis() - tsLastReport &gt; REPORTING_PERIOD_MS) {
        Serial.print(&quot;SpO2:&quot;);
        Serial.print(pox.getSpO2());
        Serial.println(&quot;%&quot;);

        tsLastReport = millis();
    }
}
</code></pre>
 69563: <p>You've done all the hard work already by setting the sensor up and managing to read from it.</p>
<p>I'd define a constant for the SpO2 threshold near the top, and convenient names for the pins:</p>
<pre><code>const uint8_t SpO2_threshold = 94;  // percent
const uint8_t red_pin = 4;
const uint8_t green_pin = 5;
</code></pre>
<p>Then set the pins to output mode in the <code>setup()</code> as usual. (Maybe set them both HIGH (or LOW) too in there, to indicate that no reading has been done yet.)</p>
<p>In the loop, inside the reporting section, simply grab the value and toggle the pins:</p>
<pre><code>...
uint8_t spo2 = pox.getSpO2();
// Print it out to serial if needed, then:
if (spo2 &lt; SpO2_threshold) {
  digitalWrite(green_pin, LOW);
  digitalWrite(red_pin, HIGH);
} else {
  digitalWrite(red_pin, LOW);
  digitalWrite(green_pin, HIGH);
}
</code></pre>
<hr />
<p>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 &quot;blink without delay&quot; example).</p>
<p>Sensor readings are clamped (any value at or below <code>spo2_min</code> will result in the fasted blink time, over <code>spo2_max</code> 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 :-)</p>
<pre><code>// 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;

// &quot;timer&quot; 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(&quot;Initializing pulse oximeter..&quot;);
  if (!pox.begin()) {
    Serial.println(&quot;FAILED&quot;);
    for (;;);
  } else {
    Serial.println(&quot;SUCCESS&quot;);
  }
}

void loop() {
  pox.update();
  unsigned long current_millis = millis();

  /* sensor reading &quot;timer&quot; */
  if (current_millis - last_reading &gt;= 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(&quot;reading: %d (%%) -&gt; interval: %lu (ms)&quot;),
              spo2, led_off_time);
    Serial.println(buff);
  }

  /* led toggling &quot;timers&quot; */
  unsigned long led_elapsed = current_millis - last_led_toggle;

  if ((led_state == LOW) &amp;&amp; (led_elapsed &gt;= led_off_time))
  {
    last_led_toggle = current_millis;
    led_state = HIGH;
    digitalWrite(led_pin, led_state);
  }
  else if ((led_state == HIGH) &amp;&amp; (led_elapsed &gt;= led_on_time))
  {
    last_led_toggle = current_millis;
    led_state = LOW;
    digitalWrite(led_pin, led_state);
  }

}
</code></pre>
