Подключение пульсоксиметра и датчика сердечного ритма MAX30100 к Arduino

Подключение пульсоксиметра и датчика сердечного ритма MAX30100 к Arduino

Создаёте ли вы фитнес-трекер, разрабатываете носимое устройство для мониторинга здоровья или просто интересуетесь, как бьётся ваше сердце — MAX30100 представляет собой компактный и мощный датчик, который предоставляет биометрические данные в реальном времени буквально на кончиках ваших пальцев. Этот маломощный модуль с интерфейсом I2C способен измерять как частоту сердечных сокращений, так и уровень кислорода в крови (SpO2).

Благодаря простому интерфейсу и широкой доступности MAX30100 является отличным инструментом для студентов, любителей электроники, инженеров, преподавателей и даже мобильных разработчиков и разработчиков игр, которые хотят добавить в свои проекты данные о здоровье в реальном времени.

В этом практическом руководстве вы узнаете, как работает датчик MAX30100, как подключить его к Arduino, и рассмотрите несколько практических примеров, включая обнаружение присутствия, измерение температуры, частоты сердечных сокращений и уровня кислорода в крови.

Давайте начнём и воплотим ваш проект мониторинга здоровья в жизнь — удар за ударом!

Обзор оборудования модуля MAX30100

В центре модуля находится MAX30100 — небольшой, но мощный датчик, созданный компанией Analog Devices. Этот датчик предназначен для измерения частоты сердечных сокращений и уровня кислорода в крови (SpO2).

Датчик включает в себя:

  • Два специальных светодиода — красный и инфракрасный (ИК), которые направляют свет в вашу кожу

  • Фотодетектор — измеряющий количество отражённого света

  • Специальную оптику и обработку сигналов — обеспечивающие точность измерений

Interfacing MAX30100 Pulse Oximeter and Heart Rate Sensor with Arduino

Благодаря компактности, надёжности и низкому энергопотреблению MAX30100 широко используется в медицинских устройствах, таких как фитнес-трекеры и умные часы.

Требования к питанию

MAX30100 требует два различных напряжения для корректной работы: 1,8 вольт для основного чипа и 3,3 вольта для красного и ИК-светодиодов. Не беспокойтесь — модуль оснащён встроенными стабилизаторами напряжения, поэтому вам нужно обеспечить только один источник питания, а модуль позаботится об остальном.

Interfacing MAX30100 Pulse Oximeter and Heart Rate Sensor with Arduino

Одно из лучших качеств MAX30100 — его низкое энергопотребление. При нормальной работе он потребляет всего около 600 мкА. В режиме ожидания (когда не выполняет измерений) — всего 0,7 мкА! Это делает его идеальным для устройств с батарейным питанием.

Встроенный датчик температуры

MAX30100 также включает встроенный датчик температуры. Этот датчик помогает повысить точность измерений сердечного ритма и уровня кислорода в крови, компенсируя изменения окружающей температуры.

Этот датчик температуры достаточно точен. Он измеряет внутреннюю температуру чипа (также называемую температурой кристалла) в диапазоне от -40°C до +85°C с точностью ±1°C.

Интерфейс I2C

Для связи с микроконтроллером MAX30100 использует простой двухпроводный интерфейс I2C.

Обратите внимание, что датчик имеет фиксированный I2C-адрес:

  • 0xAE для записи данных

  • 0xAF для чтения данных

Буфер FIFO

MAX30100 собирает данные быстрее, чем микроконтроллер может их обработать. Это может привести к проблемам, например, к потере важных измерений, если микроконтроллер не готов вовремя их прочитать. Для решения этой проблемы датчик имеет специальную область памяти, называемую буфером FIFO (First In, First Out — «первым вошёл, первым вышел»). Этот буфер работает как временное хранилище. Он позволяет датчику продолжать сбор данных о частоте сердечных сокращений и уровне кислорода в крови, даже когда микроконтроллер занят. Позже, когда микроконтроллер будет готов, он может прочитать все сохранённые измерения из буфера.

Буфер MAX30100 может хранить до 16 наборов данных. Это даёт микроконтроллеру достаточно времени для завершения других задач перед обращением за данными.

Прерывания

MAX30100 поддерживает функцию прерываний, позволяющую датчику отправлять оповещения микроконтроллеру при наступлении определённых событий. Существует пять типов прерываний:

  • Power Ready — оповещение при включении датчика или восстановлении после просадки питания (browout).

  • Данные SpO2 готовы — оповещение, когда доступно новое измерение кислорода в крови

  • Данные сердечного ритма готовы — оповещение, когда доступно новое измерение частоты сердечных сокращений

  • Температура готова — оповещение, когда завершено измерение температуры

  • FIFO почти заполнен — предупреждение, когда буфер FIFO почти заполнен и может скоро начать терять новые данные

Interfacing MAX30100 Pulse Oximeter and Heart Rate Sensor with Arduino

Эти оповещения отправляются через специальный вывод INT. Этот вывод обычно находится в состоянии HIGH. При возникновении прерывания вывод переходит в состояние LOW и остаётся в нём до тех пор, пока микроконтроллер не проверит и не сбросит прерывание.

Технические характеристики

Вот технические характеристики:

Подробную информацию о датчике MAX30100 можно найти в техническом описании.

MAX30100 vs. MAX30102

Компания Analog Devices создала улучшенную версию — новый датчик MAX30102. По сравнению со старым MAX30100, новая версия предлагает ряд улучшений, делающих его более мощным и эффективным для измерения частоты сердечных сокращений и уровня кислорода в крови.

  • Объём памяти (буфер FIFO): MAX30102 оснащён более объёмным буфером памяти по сравнению с предшественником. В то время как MAX30100 мог хранить только 16 выборок данных SpO2 и сердечного ритма, MAX30102 может хранить до 32 выборок! Это позволяет MAX30102 накапливать больше данных до их обработки, что особенно полезно, когда микроконтроллер занят другими задачами.

  • Улучшенное обнаружение света: MAX30102 имеет АЦП с более высоким разрешением — до 18 бит, что позволяет различать 262 144 уровня интенсивности света. Старый MAX30100 имел только 16-битный АЦП. Это означает, что MAX30102 может обнаруживать гораздо более тонкие изменения света, проходящего через кожу, что делает его более точным при измерении сердечного ритма и уровня кислорода.

  • Энергоэффективность: MAX30102 использует более короткую длительность импульса светодиодов по сравнению с MAX30100. Что это значит? По сути, светодиоды внутри датчика включаются на более короткое время при каждом измерении. Это может показаться незначительным изменением, но оно существенно влияет на энергопотребление датчика. Меньшее энергопотребление крайне важно для устройств вроде фитнес-трекеров и умных часов, которые работают от небольших батарей и должны работать весь день (или дольше) между зарядками.

Если вас интересует работа с модулем MAX30102, вы можете следовать руководству по ссылке ниже:

Interfacing MAX30100 Pulse Oximeter and Heart Rate Sensor with Arduino

Как работает пульсоксиметр и датчик сердечного ритма MAX30100?

MAX30100 — это оптический датчик, который измеряет частоту сердечных сокращений и уровень кислорода в крови с помощью света. Он имеет два специальных светодиода — красный и инфракрасный (ИК) — и фотодетектор.

Вы можете задаться вопросом, зачем этому датчику нужны два разных цвета света. Причина в том, что эти световые лучи имеют разные длины волн: красный свет имеет длину волны 660 нанометров, а инфракрасный — 880 нанометров. Благодаря разным длинам волн они по-разному взаимодействуют с нашей кровью, что помогает датчику выполнять два различных измерения.

Interfacing MAX30100 Pulse Oximeter and Heart Rate Sensor with Arduino

MAX30100 работает, направляя оба луча света на тонкую часть тела, например, на кончик пальца или мочку уха. Эти области идеальны, потому что кожа достаточно тонкая, чтобы свет легко проникал. Когда свет проходит через кожу, часть его поглощается кровью, а остальная часть отражается обратно. Фотодетектор на датчике измеряет, сколько света вернулось. Этот процесс известен как `фотоплетизмография (PPG) `_ — по сути, это измерение изменений объёма крови с помощью света.

MAX30100 выполняет две основные функции: измерение частоты сердечных сокращений и уровня кислорода в крови (SpO2).

Измерение частоты сердечных сокращений

Кровь переносит кислород с помощью белка, называемого гемоглобином. Когда гемоглобин несёт кислород (так называемый оксигемоглобин, или HbO2), он поглощает больше инфракрасного света.

Каждый раз, когда сердце сокращается, свежая богатая кислородом кровь поступает в палец. Поскольку эта кровь содержит много оксигемоглобина, она поглощает больше инфракрасного света. Это означает, что меньше инфракрасного света отражается обратно к фотодетектору.

Между ударами сердца в пальце чуть меньше оксигенированной крови, поэтому меньше инфракрасного света поглощается и больше света достигает детектора.

Interfacing MAX30100 Pulse Oximeter and Heart Rate Sensor with Arduino

Непрерывно излучая инфракрасный свет и измеряя эти изменения в количестве обнаруженного света, датчик может видеть паттерн, соответствующий вашему сердцебиению. Он подсчитывает эти «импульсы» изменяющейся интенсивности света, чтобы вычислить, сколько раз ваше сердце бьётся в минуту — вашу частоту сердечных сокращений!

Измерение уровня кислорода в крови (пульсоксиметрия)

Для измерения уровня кислорода в крови MAX30100 хитроумно использует оба луча — красный и инфракрасный. Ключевая идея заключается в том, что оксигемоглобин (HbO2) и дезоксигемоглобин (Hb) поглощают свет по-разному:

  • Оксигемоглобин поглощает больше инфракрасного света (880nm)

  • Дезоксигемоглобин поглощает больше красного света (660nm)

На графике спектра поглощения ниже показано, как оксигемоглобин и дезоксигемоглобин поглощают различные длины волн света с разной интенсивностью.

Interfacing MAX30100 Pulse Oximeter and Heart Rate Sensor with Arduino

Сравнивая, сколько красного и инфракрасного света поглощается, MAX30100 может рассчитать, какой процент вашего гемоглобина несёт кислород. Этот процент и есть ваш уровень SpO2, который показывает, насколько хорошо ваша кровь насыщена кислородом.

Распиновка модуля MAX30100

Давайте подробнее рассмотрим назначение каждого вывода:

Interfacing MAX30100 Pulse Oximeter and Heart Rate Sensor with Arduino

VIN — это вывод питания. Его можно подключить к 3,3V или 5V, в зависимости от логического уровня вашего микроконтроллера.

SCL — вывод тактирования, используемый для связи по I2C.

SDA — вывод данных, используемый для связи по I2C.

INT — вывод прерывания. MAX30100 можно настроить на генерацию прерывания при наступлении определённых событий, как описано выше. Этот вывод обычно находится в состоянии HIGH, но переходит в состояние LOW при возникновении прерывания и остаётся в нём до тех пор, пока микроконтроллер не прочитает и не сбросит прерывание.

IRD — подключение земли для инфракрасного светодиода внутри модуля. К этому выводу ничего подключать не нужно — он обслуживается внутренне микросхемой.

RD — аналогично IRD, это подключение земли для красного светодиода внутри модуля. Оставьте этот вывод неподключённым.

GND — это вывод заземления.

MAX30100 не работает — проблема и решения

Модуль MAX30100 очень популярен среди любителей электроники, потому что он доступен по цене и отлично подходит для измерения частоты сердечных сокращений и уровня кислорода в крови. Однако многие версии этого модуля имеют конструктивный дефект, который может помешать его корректной работе — особенно при использовании с Arduino. Не волнуйтесь — это руководство объясняет проблему и предлагает два простых решения.

Проблема

Датчик MAX30100 требует два разных напряжения для корректной работы: 1,8V для питания основной микросхемы и 3,3V для питания красного и инфракрасного светодиодов. Для обеспечения этих напряжений модуль имеет два стабилизатора — U1 и U2. U1 преобразует 5V в 3,3V, а U2 берёт 3,3V от U1 и преобразует их в 1,8V.

Пока всё нормально. Но вот ошибка проектирования:

На модуле есть три важных подтягивающих резистора (R1, R2 и R3) для линий связи (SCL, SDA и INT). Эти резисторы должны подтягивать сигнальные линии к напряжению, которое Arduino может распознать как «HIGH». Но они подключены к линии питания 1,8V (выделено красным) вместо 3,3V!

Interfacing MAX30100 Pulse Oximeter and Heart Rate Sensor with Arduino Interfacing MAX30100 Pulse Oximeter and Heart Rate Sensor with Arduino

Почему это проблема?

Поскольку сигнальные линии подтянуты только до 1,8V, большинство микроконтроллеров не могут распознать это как корректный сигнал HIGH. Вот почему модуль не обнаруживается на шине I2C и может казаться неработающим.

Не волнуйтесь! У нас есть два решения этой проблемы.

Решение 1 (проверено):

  1. Перережьте дорожку на плате (выделена красным), соединяющую подтягивающие резисторы 4,7 кОм с линией 1,8V. Это прекратит подтяжку сигнальных линий к неправильному напряжению.

  2. Сделайте перемычку (показана жёлтым) проводом или каплей припоя. Это переподключит подтягивающие резисторы к линии 3,3V. Таким образом, сигнальные линии будут подтянуты к напряжению, которое Arduino может распознать.

Вот плата до и после модификации:

Interfacing MAX30100 Pulse Oximeter and Heart Rate Sensor with Arduino Interfacing MAX30100 Pulse Oximeter and Heart Rate Sensor with Arduino

После выполнения этих изменений подключите модуль к Arduino UNO следующим образом:

Interfacing MAX30100 Pulse Oximeter and Heart Rate Sensor with Arduino

Подключение довольно простое. Подключите вывод VIN модуля MAX30100 к выводу 3,3V, а GND — к GND на Arduino. Затем подключите вывод SCL к выводу тактирования I2C, а вывод SDA — к выводу данных I2C на Arduino. Наконец, подключите вывод INT к цифровому выводу 2.

Решение 2 (проверено):

Если вы предпочитаете не резать дорожки и не паять перемычки, попробуйте следующее:

Аккуратно удалите все три подтягивающих резистора 4,7 кОм (R1, R2, R3) с модуля.

Вот плата до и после удаления резисторов:

Interfacing MAX30100 Pulse Oximeter and Heart Rate Sensor with Arduino Interfacing MAX30100 Pulse Oximeter and Heart Rate Sensor with Arduino

После этого подключите модуль к Arduino UNO так же, как в Решении 1. Просто добавьте собственные внешние подтягивающие резисторы 4,7 кОм на линии SCL, SDA и INT. Подключите один конец каждого резистора к соответствующей сигнальной линии, а другой — к 3,3V.

Вот как выглядит схема подключения:

Interfacing MAX30100 Pulse Oximeter and Heart Rate Sensor with Arduino

Наша оценка:

Мы протестировали оба решения, и оба работают отлично! Выбирайте то, которое вам удобнее.

После применения любого из исправлений ваш модуль MAX30100 должен отлично работать с Arduino!

Установка библиотеки

Связь с MAX30100 была бы довольно сложной, если бы нам пришлось писать весь код самостоятельно. К счастью, `OXullo Intersecans `_ создал полезную библиотеку, которая значительно упрощает задачу.

Для установки библиотеки:

  1. Сначала откройте Arduino IDE. Затем нажмите на значок Менеджера библиотек на левой боковой панели.

  2. Введите «max30100» в строке поиска для фильтрации результатов.

  3. Найдите библиотеку MAX30100lib от OXullo Intersecans.

  4. Нажмите кнопку Install, чтобы добавить её в Arduino IDE.

Interfacing MAX30100 Pulse Oximeter and Heart Rate Sensor with Arduino

Пример 1 — Измерение частоты сердечных сокращений (BPM) и уровня кислорода в крови (SpO2)

В этом примере мы будем измерять частоту сердечных сокращений и уровень кислорода в крови (SpO2) и отображать результаты в мониторе последовательного порта. Этот пример даёт базовое представление о получении биометрических данных в реальном времени с помощью датчика MAX30100.

Предупреждение:

Этот датчик использует свет для обнаружения пульса. Многие факторы могут повлиять на показания, такие как движение или положение пальца. Поэтому он отлично подходит для обучения и экспериментов, но не является надёжным для медицинского использования.

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

#define REPORTING_PERIOD_MS 1000

// Create a PulseOximeter object
PulseOximeter pox;

// Time at which the last beat occurred
uint32_t tsLastReport = 0;

// Callback routine is executed when a pulse is detected
void onBeatDetected() {
  Serial.println("Beat!");
}

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

  Serial.print("Initializing pulse oximeter..");

  // Initialize sensor
  if (!pox.begin()) {
    Serial.println("FAILED");
    for (;;)
      ;
  } else {
    Serial.println("SUCCESS");
  }

  // Configure sensor to use 7.6mA for LED drive
  pox.setIRLedCurrent(MAX30100_LED_CURR_7_6MA);

  // Register a callback routine
  pox.setOnBeatDetectedCallback(onBeatDetected);
}

void loop() {
  // Read from the sensor
  pox.update();

  // Grab the updated heart rate and SpO2 levels
  if (millis() - tsLastReport > REPORTING_PERIOD_MS) {
    Serial.print("Heart rate:");
    Serial.print(pox.getHeartRate());
    Serial.print("bpm / SpO2:");
    Serial.print(pox.getSpO2());
    Serial.println("%");

    tsLastReport = millis();
  }
}

После загрузки скетча на Arduino аккуратно приложите палец к датчику и держите его как можно неподвижнее. Подождите несколько секунд, пока датчик собирает данные. Вскоре вы увидите показания частоты сердечных сокращений и SpO2 в мониторе последовательного порта.

Interfacing MAX30100 Pulse Oximeter and Heart Rate Sensor with Arduino

Объяснение кода:

Мы начинаем с подключения двух важных библиотек: Wire.h используется для связи по I2C между Arduino и датчиком MAX30100. MAX30100_PulseOximeter.h — это библиотека, которая помогает нам легко взаимодействовать с датчиком.

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

Далее мы определяем константу REPORTING_PERIOD_MS. Она задаёт, как часто показания частоты сердечных сокращений и SpO2 будут отображаться в мониторе последовательного порта. В данном случае установлено значение 1000 миллисекунд, что означает обновление раз в секунду.

#define REPORTING_PERIOD_MS 1000

Затем мы создаём объект pox, который будет обрабатывать все функции пульсоксиметра. Мы также создаём переменную tsLastReport, которая хранит время последнего измерения. Это помогает нам определить, когда прошла одна секунда, чтобы вывести новые данные.

// Create a PulseOximeter object
PulseOximeter pox;

// Time at which the last beat occurred
uint32_t tsLastReport = 0;

Мы также настраиваем функцию обратного вызова (callback). Эта функция вызывается каждый раз, когда датчик обнаруживает сердцебиение. В этом примере она просто выводит «Beat!» в монитор последовательного порта. Однако вы можете настроить эту функцию по своему усмотрению; например, можно заставить мигать светодиод.

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

В функции setup() мы сначала инициализируем последовательную связь, а затем пытаемся подключиться к датчику, вызывая pox.begin(). Если всё работает, выводим «SUCCESS». Если нет — выводим «FAILED» и останавливаем программу. Это помогает быстро понять, работает датчик или нет.

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

После этого мы настраиваем яркость инфракрасного светодиода с помощью функции setIRLedCurrent(). Инфракрасный свет — это то, что проходит через палец для обнаружения кровотока. В этом примере мы устанавливаем ток 7,6 мА — не слишком ярко и не слишком тускло.

pox.setIRLedCurrent(MAX30100_LED_CURR_7_6MA);

Это значение выбрано потому, что оно хорошо работает в большинстве ситуаций. По умолчанию библиотека устанавливает ток светодиода на 50 мА, что часто слишком много и может привести к сбою датчика при запуске.

Вот некоторые предустановленные значения тока, из которых можно выбрать. Варианты варьируются от полностью выключенного (0 мА) до очень яркого (50 мА):

  • MAX30100_LED_CURR_0MA

  • MAX30100_LED_CURR_4_4MA

  • MAX30100_LED_CURR_7_6MA

  • MAX30100_LED_CURR_11MA

  • MAX30100_LED_CURR_14_2MA

  • MAX30100_LED_CURR_17_4MA

  • MAX30100_LED_CURR_20_8MA

  • MAX30100_LED_CURR_24MA

  • MAX30100_LED_CURR_27_1MA

  • MAX30100_LED_CURR_30_6MA

  • MAX30100_LED_CURR_33_8MA

  • MAX30100_LED_CURR_37MA

  • MAX30100_LED_CURR_40_2MA

  • MAX30100_LED_CURR_43_6MA

  • MAX30100_LED_CURR_46_8MA

  • MAX30100_LED_CURR_50MA

Помните: больший ток делает светодиод ярче и позволяет проникать глубже в кожу, но также потребляет больше энергии. Попробуйте разные значения, чтобы найти оптимальное для вашей конфигурации.

Наконец, мы связываем нашу функцию onBeatDetected с датчиком с помощью setOnBeatDetectedCallback(). Это заставляет функцию автоматически запускаться при каждом обнаружении пульса.

pox.setOnBeatDetectedCallback(onBeatDetected);

В функции loop() мы сначала вызываем pox.update(). Это очень важно — это указывает датчику проверить наличие новых данных и поддерживать актуальность показаний частоты сердечных сокращений и SpO2, считывая данные из его внутреннего буфера FIFO.

pox.update();

Далее мы проверяем, прошла ли целая секунда с момента последнего вывода значений частоты сердечных сокращений и SpO2. Вместо использования delay() (который приостановил бы всю программу) мы используем функцию millis(). millis() отслеживает время в фоновом режиме, поэтому остальная часть программы продолжает работать без задержек.

Если секунда прошла, мы выводим показания частоты сердечных сокращений и SpO2 в монитор последовательного порта. Затем обновляем tsLastReport текущим временем, чтобы следующее обновление произошло через секунду.

if (millis() - tsLastReport > REPORTING_PERIOD_MS) {
  Serial.print("Heart rate:");
  Serial.print(pox.getHeartRate());
  Serial.print("bpm / SpO2:");
  Serial.print(pox.getSpO2());
  Serial.println("%");

  tsLastReport = millis();
}

Проблемы с обнаружением сердцебиения?

Если датчик не обнаруживает ваше сердцебиение правильно, не волнуйтесь! Вот несколько простых способов решения:

  • Не нажимайте на датчик слишком сильно. Если вы слишком сжимаете палец, это препятствует нормальному кровотоку.

  • Не нажимайте слишком слабо. Это может пропускать лишний свет и создавать зашумлённый сигнал.

  • Попробуйте найти «правильное» давление — как если бы вы аккуратно держали монету между пальцами.

  • Попробуйте использовать резинку или скотч, чтобы удерживать палец на датчике неподвижно.

  • Попробуйте другие части тела с тонкой кожей и хорошим кровообращением, например, мочку уха или нижнюю губу.

Пример 2 — Чтение необработанных значений красного и ИК-света

Второй пример показывает, как считывать необработанные значения инфракрасного (ИК) и красного света с датчика.

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

// Create a MAX30100 object
MAX30100 sensor;

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

  Serial.print("Initializing MAX30100..");

  // Initialize sensor
  if (!sensor.begin()) {
    Serial.println("FAILED");
    for (;;)
      ;
  } else {
    Serial.println("SUCCESS");
  }

  // Configure sensor
  configureMax30100();
}

void loop() {
  uint16_t ir, red;

  sensor.update();

  while (sensor.getRawValues(&ir, &red)) {
    Serial.print("R[");
    Serial.print(red);
    Serial.print("] IR[");
    Serial.print(ir);
    Serial.println("]");
  }
}

void configureMax30100() {
  sensor.setMode(MAX30100_MODE_SPO2_HR);
  sensor.setLedsCurrent(MAX30100_LED_CURR_50MA, MAX30100_LED_CURR_27_1MA);
  sensor.setLedsPulseWidth(MAX30100_SPC_PW_1600US_16BITS);
  sensor.setSamplingRate(MAX30100_SAMPRATE_100HZ);
  sensor.setHighresModeEnabled(true);
}

После загрузки кода на Arduino откройте монитор последовательного порта. Направьте датчик вверх и проведите рукой над ним. Вы заметите, что числа меняются по мере того, как ваша рука отражает разное количество света обратно к датчику.

Interfacing MAX30100 Pulse Oximeter and Heart Rate Sensor with Arduino

Визуализация данных

Просто смотреть на числа может быть неудобно. Лучший способ понять, что происходит — увидеть данные в виде графика с помощью Serial Plotter в Arduino IDE.

Для этого замените цикл while() в вашем скетче на версию ниже:

while (sensor.getRawValues(&ir, &red)) {
  Serial.print(red);
  Serial.print(", ");
  Serial.println(ir);
}

В Arduino IDE выберите Tools > Serial Plotter. Когда вы проведёте рукой над датчиком, вы увидите две линии на графике — одну для красного света и одну для инфракрасного. Этот график значительно упрощает понимание того, как датчик реагирует на движения вашей руки.

Interfacing MAX30100 Pulse Oximeter and Heart Rate Sensor with Arduino

Пример 3 — Измерение температуры

Как упоминалось ранее, MAX30100 имеет встроенный датчик температуры, который измеряет внутреннюю температуру чипа (температуру кристалла). Хотя этот датчик в основном помогает корректировать (калибровать) показания сердечного ритма и SpO2 с учётом изменений температуры, он также хорошо работает как быстрый термометр.

Этот пример выводит температуру в градусах Цельсия и Фаренгейта.

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

#define REPORTING_PERIOD_MS 1000

// Create a MAX30100 object
MAX30100 sensor;

// Time when the last reading was taken
uint32_t tsLastReading = 0;

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

  Serial.print("Initializing MAX30100..");

  // Initialize sensor
  if (!sensor.begin()) {
    Serial.println("FAILED");
    for (;;)
      ;
  } else {
    Serial.println("SUCCESS");
  }

  // Configure sensor
  configureMax30100();
}

void loop() {
  sensor.update();

  if (millis() - tsLastReading > REPORTING_PERIOD_MS) {
    sensor.startTemperatureSampling();
    if (sensor.isTemperatureReady()) {
      float temp = sensor.retrieveTemperature();
      Serial.print("Temperature = ");
      Serial.print(temp);
      Serial.print("*C | ");
      Serial.print((temp * 9.0) / 5.0 + 32.0);  //print the temperature in Fahrenheit
      Serial.println("*F");
    }
    tsLastReading = millis();
  }
}

void configureMax30100() {
  sensor.setMode(MAX30100_MODE_SPO2_HR);
  sensor.setLedsCurrent(MAX30100_LED_CURR_50MA, MAX30100_LED_CURR_27_1MA);
  sensor.setLedsPulseWidth(MAX30100_SPC_PW_1600US_16BITS);
  sensor.setSamplingRate(MAX30100_SAMPRATE_100HZ);
  sensor.setHighresModeEnabled(true);
}

После запуска скетча попробуйте приложить палец к датчику или слегка подуть на него. Вы должны увидеть небольшое повышение температуры.

Interfacing MAX30100 Pulse Oximeter and Heart Rate Sensor with Arduino

Пример 4 — Обнаружение присутствия

В этом финальном примере вы узнаете, как использовать MAX30100 в качестве датчика приближения или движения.

Вот как это работает: скетч выполняет несколько измерений в начале (во время setup) и усредняет их для установки базовой линии. После этого он постоянно проверяет наличие резких изменений относительно этой базовой линии. Когда что-то перемещается над датчиком — например, ваша рука — он выведет: «Something is there!»

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

#define REPORTING_PERIOD_MS 1000

int lastOccurrence = LOW;

// Create a MAX30100 object
MAX30100 sensor;

uint16_t ir, red;
uint16_t avg_ir = 0, avg_red = 0;

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

  Serial.print("Initializing MAX30100..");

  // Initialize sensor
  if (!sensor.begin()) {
    Serial.println("FAILED");
    for (;;)
      ;
  } else {
    Serial.println("SUCCESS");
  }

  configureMax30100();

  takeSampleReadings();
}

void loop() {
  sensor.update();

  while (sensor.getRawValues(&ir, &red)) {
    if (ir > 10 * avg_ir && red > 10 * avg_red) {
      if (lastOccurrence == LOW) {
        Serial.println("Something is there!");
        lastOccurrence = HIGH;
      }
    } else {
      lastOccurrence = LOW;
    }
  }
}

void configureMax30100() {
  sensor.setMode(MAX30100_MODE_SPO2_HR);
  sensor.setLedsCurrent(MAX30100_LED_CURR_50MA, MAX30100_LED_CURR_27_1MA);
  sensor.setLedsPulseWidth(MAX30100_SPC_PW_1600US_16BITS);
  sensor.setSamplingRate(MAX30100_SAMPRATE_100HZ);
  sensor.setHighresModeEnabled(true);
}

void takeSampleReadings() {
  delay(50);
  for (int i = 0; i <= 9; i++) {
    sensor.update();
    sensor.getRawValues(&ir, &red);
    avg_ir += ir;
    avg_red += red;
    delay(50);
  }
  avg_ir /= 10;
  avg_red /= 10;
}

Попробуйте загрузить этот скетч и провести рукой над датчиком. Наблюдайте за сообщением «Something is there!» в мониторе последовательного порта. Вы также можете проверить, на каком расстоянии ваша рука ещё может быть обнаружена.

Interfacing MAX30100 Pulse Oximeter and Heart Rate Sensor with Arduino

MAX30100 невероятно чувствителен — он может обнаруживать мельчайшие движения, потому что способен различать до 65 536 уровней (16 бит) света. Это впечатляющая точность для обнаружения близлежащих объектов!