23 февраля 2020г. Магазин не работает. Все оформленные заказы будут обработаны 24 февраля.
КОРЗИНА
0 ТОВАРА
8 (499) 500-14-56 | ПН. - ПТ. 12:00-20:00
ЛЕСНОРЯДСКИЙ ПЕРЕУЛОК, 18С2, БЦ "ДМ-ПРЕСС"
 Цифровой датчик пульса  и уровня SpO2, MAX30102, I2C для Arduino ардуино
 Цифровой датчик пульса  и уровня SpO2, MAX30102, I2C для Arduino ардуино
 Цифровой датчик пульса  и уровня SpO2, MAX30102, I2C для Arduino ардуино
 Цифровой датчик пульса  и уровня SpO2, MAX30102, I2C для Arduino ардуино
Цифровой датчик пульса и уровня SpO2, MAX30102, I2C

Цифровой датчик пульса и уровня SpO2, MAX30102, I2C

Модификация
Артикул: # 1282 Наличие: 0 шт.
Сообщить о поставке на e-mail:
{{ status }}


Возможен безналичный расчёт для юридических лиц при оформлении заказа

С этим товаром берут

Общие сведения

Датчик пульсоксиметрии MAX30102 — плата с интегрированным сенсорным модулем, которая позволяет определять частоту сердечных сокращений, то есть пульс, а так же уровень насыщения крови кислородом (SpO2). Помимо этого, в сенсор встроен температурный датчик, с помощью которого вы можете получить значение температуры (в Цельсиях и Фаренгейтах) окружающей среды.

Видео

Характеристики

  • Оптический модуль с возможностью измерения ЧСС (пульс), SpO2 (степень насыщения крови кислородом) и температуры среды;
  • Адрес на шине I2C: 0x57;
  • Входное напряжение: 5В;
  • Габариты датчика: 15.5мм х 19.5мм х 2.5мм (без гребёнки);
  • Рабочая температура: -40°С ... +85°С;

Подключение

Для удобства подключения к Arduino воспользуйтесь Trema ShieldTrema Power ShieldMotor Shield или Trema Set Shield.

Так как датчик работает по шине I2C, то его выводы подключаются следующим образом:

MAX30102Trema Shield
VINVcc
SDASDA
SCLSCL
GNDGnd

Питание

Датчик питается от напряжения 5 В.

Подробнее о датчике

Датчик предназначен для создания портативных носимых приборов контроля сердечного ритма и насыщенности крови кислородом.

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

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

Примеры

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

Вывод значений ЧСС в монитор порта.

#include "Wire.h"           //  Подключаем библиотеку для работы с шиной I2C
#include "MAX30105.h"       //  Подключаем библиотеку для работы с модулем
#include "heartRate.h"      //  Подключаем блок для работы с ЧСС (пульс)
MAX30105 PARTICLE_SENSOR;   //  Создаём объект для работы с библиотекой
//--------------------------//
const byte RATE_SIZE = 4;   //  Коэффициент усреднения. ЧЕм больше число, тем больше усреднение показаний.
byte rates[RATE_SIZE];      //  Массив со значениями ЧСС
byte rateSpot = 0;          //  Переменная с порядковым номером значения в массиве
long lastBeat = 0;          //  Время последнего зафиксированного удара
float beatsPerMinute;       //  Создаём переменную для хранения значения ЧСС
int beatAvg;                //  Создаём переменную для хранения усреднённого значения ЧСС
//----------------------------------------------------//
void setup() {
  Serial.begin(115200);                               //  Инициируем работу с монитором последовательного порта на скорости 115200 бод
  if (!PARTICLE_SENSOR.begin()) {                     //  Инициируем работу с модулем. Если инициализация не прошла, то
    Serial.println("MAX30105 was not found");         //  выводим сообщение об этом в монитор последовательного порта
    while (1);                                        //  и останавливаем дальнейшее выполнение скетча
  }
  Serial.println("Place your finger on the sensor");  //  выводим сообщение "Положите палец сверху на сенсор"
  PARTICLE_SENSOR.setup();                            //  Устанавливаем настройки для сенсора по умолчанию
  PARTICLE_SENSOR.setPulseAmplitudeRed(0x0A);         //  Выключаем КРАСНЫЙ светодиод для того, чтобы модуль начал работу
  PARTICLE_SENSOR.setPulseAmplitudeGreen(0);          //  Выключаем ЗЕЛЁНЫЙ светодиод
}
//------------------------------------------------------//
void loop() {
  long irValue = PARTICLE_SENSOR.getIR();               //  Считываем значение отражённого ИК-светодиода (отвечающего за пульс) и
  if (checkForBeat(irValue) == true) {                  //  если пульс был зафиксирован, то
    long delta = millis() - lastBeat;                   //  находим дельту по времени между ударами
    lastBeat = millis();                                //  Обновляем счётчик
    beatsPerMinute = 60 / (delta / 1000.0);             //  Вычисляем количество ударов в минуту
    if (beatsPerMinute < 255 && beatsPerMinute > 20) {  //  Если количество ударов в минуту находится в промежутке между 20 и 255, то
      rates[rateSpot++] = (byte)beatsPerMinute;         //  записываем это значение в массив значений ЧСС
      rateSpot %= RATE_SIZE;                            //  Задаём порядковый номер значения в массиве, возвращая остаток от деления и присваивая его переменной rateSpot
      beatAvg = 0;                                      //  Обнуляем переменную и
      for (byte x = 0 ; x < RATE_SIZE ; x++) {          //  в цикле выполняем усреднение значений (чем больше RATE_SIZE, тем сильнее усреднение)
        beatAvg += rates[x];                            //  путём сложения всех элементов массива
      }
      beatAvg /= RATE_SIZE;                             //  а затем деления всей суммы на коэффициент усреднения (на общее количество элементов в массиве)
    }
  }
  Serial.print("IR=");                                  //  Выводим в монитор последовательного порта текст про значение ИК-светдиода
  Serial.print(irValue);                                //  Выводим в монитор последовательного порта значение с ИК-светодиода
  Serial.print(", BPM=");                               //  Выводим в монитор последовательного порта текст про значение ЧСС
  Serial.print(beatsPerMinute);                         //  Выводим в монитор последовательного порта значение ЧСС
  Serial.print(", Avg BPM=");                           //  Выводим в монитор последовательного порта текст про усреднённую ЧСС
  Serial.print(beatAvg);                                //  Выводим в монитор последовательного порта значение усреднённой ЧСС
  if (irValue < 50000)  Serial.print(" No finger?");    //  Если значение ИК-светодиода меньше указанного, то выводим текст о том, что палец убран с датчика
  Serial.println();                                     //  Выводим в монитор последовательного порта переход на новую строку
}

Вывод значений температуры окружающей среды в монитор порта.

#include "Wire.h"                                           //  Подключаем библиотеку для работы с шиной I2C
#include "MAX30105.h"                                       //  Подключаем библиотеку для работы с модулем
MAX30105 PARTICLE_SENSOR;                                   //  Создаём объект для работы с библиотекой

void setup() {
  Serial.begin(9600);                                       //  Инициируем работу с монитором последовательного порта на скорости 9600 бод
  if (!PARTICLE_SENSOR.begin()) {                           //  Инициируем работу с модулем. Если инициализация не прошла, то
    Serial.println("MAX30105 was not found.");              //  выводим сообщение об этом в монитор последовательного порта
    while (1);                                              //  и останавливаем дальнейшее выполнение скетча
  }
  
  //  Встроенные светодиоды потребляют незначительный ток,
  //  однако, если вы хотите исключить их возможное влияние
  //  на результат, то используйте следующую строку:
  PARTICLE_SENSOR.setup(0);                                 //  Настраиваем сенсор на работу с выключенными светодиодами

  //  Если же вы хотите запустить сенсор в стандартном
  //  режиме, то раскомментируйте следующую строку:
  //PARTICLE_SENSOR.setup();                                //  Устанавливаем настройки для сенсора по умолчанию
  
  PARTICLE_SENSOR.enableDIETEMPRDY();                       //  Включаем поддержку прерываний для датчика температуры. Это ОБЯЗАТЕЛЬНЫЙ параметр
}

void loop() {
  float temperature = PARTICLE_SENSOR.readTemperature();    //  Создаём переменную с плавающей точкой и записываем в неё полученное от датчика значение (в Цельсиях)
  Serial.print("temperature C = ");                         //  Выводим в монитор последовательного порта текст
  Serial.print(temperature, 4);                             //  Выводим в монитор последовательного порта значение температуры в Цельсиях

  float temperatureF = PARTICLE_SENSOR.readTemperatureF();  //  Создаём переменную с плавающей точкой и записываем в неё полученное от датчика значение (в Фаренгейтах)
  Serial.print(" | temperature F = ");                      //  Выводим в монитор последовательного порта текст
  Serial.print(temperatureF, 4);                            //  Выводим в монитор последовательного порта значение температуры в Фаренгейтах
  Serial.println();                                         //  Переходим на новую строку
}

Вывод значений уровня SpO2 в монитор порта.

#define  MAX_BRIGHTNESS 255                         //  Задаём переменную максимальной яркости свечения светодиода
//--------------------------------------------------//
#include "Wire.h"                                   //  Подключаем библиотеку для работы с шиной I2C
#include "MAX30105.h"                               //  Подключаем библиотеку для работы с модулем
#include "spo2_algorithm.h"                         //  Подключаем блок работы с насыщением крови кислородом
MAX30105 PARTICLE_SENSOR;                           //  Создаём объект для работы с библиотекой
//--------------------------------------------------//
//  32-битная переменная занимает в памяти 4 байта. Дальше используется 2 массива, каждый из которых содержит 100 значений.
//  Если эти переменные будут 32-х битные, то они займут 100*4*2 = 800 байт. Arduino UNO имеет всего 2 Килобайт (2048 байт) памяти,
//  поэтому при создании всех остальных переменных её объёма памяти не хватит. В связи с этим при запуске скетча выполняется проверка
//  типа платы. Если это Arduino UNO (имеющая на борту микроконтроллер ATmega328), то будут созданы 16-битные массивы, чтобы занимать
//  в 2 раза меньше места. Так как данные с сенсора считываются в 32-битном формате, то при записи в 16-битный массив эти значения
//  будут автоматически обрезаны.
#if defined(__AVR_ATmega328P__) || defined(__AVR_ATmega168__)
uint16_t irBuffer[100];                             //  16-битный массив данных от сенсора со значениями от ИК-светодиода
uint16_t redBuffer[100];                            //  16-битный массив данных от сенсора со значениями от красного светодиода
#else
uint32_t irBuffer[100];                             //  32-битный массив данных от сенсора со значениями от ИК-светодиода
uint32_t redBuffer[100];                            //  32-битный массив данных от сенсора со значениями от красного светодиода
#endif
//--------------------------------------------------//
int32_t bufferLength;                               //  длина буфера данных
int32_t spo2;                                       //  значение SpO2 (насыщенности крови кислородом)
int8_t  validSPO2;                                  //  флаг валидности значений сенсора по SpO2
int32_t heartRate;                                  //  значение ЧСС
int8_t  validHeartRate;                             //  флаг валидности значений сенсора по ЧСС
//--------------------------------------------------//
void setup() {
  Serial.begin(115200);                             //  инициируем работу с монитором последовательного порта на скорости 115200 бод
  if (!PARTICLE_SENSOR.begin()) {                   //  инициируем работу с сенсором. Если этого не произошло, то
    Serial.println(F("MAX30105 was not found."));   //  Выводим сообщением об этом и
    while (1);                                      //  останавливаем дальнейшее выполнение скетча
  }
  Serial.println(F("Press any key!"));              //  Прежде, чем переходить к считыванию, выводим в монитор порта сообщение и
  while (Serial.available() == 0);                  //  ждём отправки любого символа в монитор порта (нажмите Enter, находясь в строке отправки)
  Serial.read();                                    //  Если символ получен, то скетч будет выполнен дальше
  //------------------------------------------------//
  //  Блок настроек сенсора для работы в режиме определения насыщенности крови кислородом и определения ЧСС:
  byte ledBrightness  = 60;                         //  Задаём яркость работы светодиода, при этом потребление тока будет следующим: 0 - 0мА, 255 - 50 мА
  byte sampleAverage  = 4;                          //  Устанавливаем коэффициент усреднения. Возможные варианты значений: 1, 2, 4, 8, 16, 32
  byte ledMode        = 2;                          //  Устанавливаем режим работы светодиодов на сенсоре: 1 - только красный (Red only), 2 - красный и ИК (Red + IR), 3 - красный, ИК и зелёный (Red + IR + Green)
  byte sampleRate     = 100;                        //  Устанавливаем частоту дискретизации (сглаживания сигнала). Варианты: 50, 100, 200, 400, 800, 1000, 1600, 3200
  int  pulseWidth     = 411;                        //  Устанавливаем ширину импульса. Варианты: 69, 118, 215, 411
  int  adcRange       = 4096;                       //  Устанавливаем диапазон значений с АЦП. Варианты: 2048(11 бит), 4096(12 бит), 8192(13 бит), 16384(14 бит)
  //------------------------------------------------//
  //  Настраиваем сенсор согласно вышеуказанным настройкам
  PARTICLE_SENSOR.setup(ledBrightness, sampleAverage, ledMode, sampleRate, pulseWidth, adcRange);
}
//----------------------------------------------------//
void loop() {
  bufferLength = 100;                                 //  Устанавливаем длину буфера равным 100 (куда будут записаны пакеты по 25 значений в течении 4 секунд)
  //  считываем первые 100 значений и определяем диапазон значений сигнала:
  for (byte i = 0 ; i < bufferLength ; i++) {         //  проходим в цикле по буферу и
    while (PARTICLE_SENSOR.available() == false)      //  отправляем сенсору запрос на получение новых данных
      PARTICLE_SENSOR.check();
    redBuffer[i] = PARTICLE_SENSOR.getRed();          //  Записываем в массив значения сенсора, полученные при работе с КРАСНЫМ светодиодом
    irBuffer[i] = PARTICLE_SENSOR.getIR();            //  Записываем в массив значения сенсора, полученные при работе с ИК      светодиодом
    PARTICLE_SENSOR.nextSample();                     //  Как только в буфер было записано 100 значений - отправляем сенсору команду начать вычислять значения ЧСС и SpO2
    Serial.print(F("red="));                          //  Выводим текст в монитор последовательного порта
    Serial.print(redBuffer[i], DEC);                  //  Выводим значение переменной redBuffer[i] в монитор последовательного порта
    Serial.print(F(", ir="));                         //  Выводим текст в монитор последовательного порта
    Serial.println(irBuffer[i], DEC);                 //  Выводим значение переменной irBuffer[i] в монитор последовательного порта
  }

  //  Вычисляем значения ЧСС и SpO2 по первым полученным 100 значениям:
  maxim_heart_rate_and_oxygen_saturation(irBuffer, bufferLength, redBuffer, &spo2, &validSPO2, &heartRate, &validHeartRate);

  //  Непрерывно считываем значений с сенсора и вычисляем значения ЧСС и SpO2 каждую секунду
  while (1) {
    //  Сбрасываем первые полученные 25 значений из буфера, а оставшиеся 75 сдвигаем влево в массиве
    for (byte i = 25; i < 100; i++) {
      redBuffer[i - 25] = redBuffer[i];
      irBuffer[i - 25] = irBuffer[i];
    }
    //  Получаем новые 25 значений прежде чем переходить к вычислению ЧСС
    for (byte i = 75; i < 100; i++) {
      while (PARTICLE_SENSOR.available() == false) {  //  Опрашиваем сенсор на предмет наличия новых значений
        PARTICLE_SENSOR.check();
      }
      redBuffer[i] = PARTICLE_SENSOR.getRed();        //  Записываем в массив значения сенсора, полученные при работе с КРАСНЫМ светодиодом
      irBuffer[i] = PARTICLE_SENSOR.getIR();          //  Записываем в массив значения сенсора, полученные при работе с ИК      светодиодом
      PARTICLE_SENSOR.nextSample();                   //  Как только в буфер было записано 100 значений - отправляем сенсору команду начать вычислять значения ЧСС и SpO2

      Serial.print(F("red="));                        //  Выводим текст в монитор последовательного порта
      Serial.print(redBuffer[i], DEC);                //  Выводим значение переменной   redBuffer[i]   в монитор последовательного порта
      Serial.print(F(", ir="));                       //  Выводим текст в монитор последовательного порта
      Serial.print(irBuffer[i], DEC);                 //  Выводим значение переменной   irBuffer[i]    в монитор последовательного порта
      Serial.print(F(", HR="));                       //  Выводим текст в монитор последовательного порта
      Serial.print(heartRate, DEC);                   //  Выводим значение переменной   heartRate      в монитор последовательного порта
      Serial.print(F(", HRvalid="));                  //  Выводим текст в монитор последовательного порта
      Serial.print(validHeartRate, DEC);              //  Выводим значение переменной   validHeartRate в монитор последовательного порта
      Serial.print(F(", SPO2="));                     //  Выводим текст в монитор последовательного порта
      Serial.print(spo2, DEC);                        //  Выводим значение переменной   spo2           в монитор последовательного порта
      Serial.print(F(", SPO2Valid="));                //  Выводим текст в монитор последовательного порта
      Serial.println(validSPO2, DEC);                 //  Выводим значение переменной   validSPO2      в монитор последовательного порта
    }
    //  После получения очередного пакета из 25 значений повторно считаем значения ЧСС и SpO2
    maxim_heart_rate_and_oxygen_saturation(irBuffer, bufferLength, redBuffer, &spo2, &validSPO2, &heartRate, &validHeartRate);
  }
}

    Вывод значений ЧСС на светодиодную матрицу 64х32 с анимацией:

    #include "Wire.h"             //  Подключаем библиотеку для работы с шиной I2C
    #include "MAX30105.h"         //  Подключаем библиотеку для работы с модулем
    #include "heartRate.h"        //  Подключаем блок для работы с ЧСС (пульс)
    #include "RGBmatrixPanel.h"   //  Подключаем библиотеку для работы с матрицей
    //----------------------------//
    //  Используем эти выводы, если матрица подключена к Arduino UNO
    //#define CLK     8
    //#define OE      9
    //#define LAT     10
    //  Используем эти выводы, если матрица подключена к Arduino MEGA
    //#define CLK     11
    //#define OE      9
    //#define LAT     10
    //  Используем эти выводы, если матрица подключена к Piranha ULTRA
    #define CLK       11          //  Вывод Arduino, к которому подключён вывод CLK матрицы
    #define OE        12          //  Вывод Arduino, к которому подключён вывод OE матрицы
    #define LAT       13          //  Вывод Arduino, к которому подключён вывод LAT матрицы
    #define A         A0          //  Вывод Arduino, к которому подключён вывод A матрицы
    #define B         A1          //  Вывод Arduino, к которому подключён вывод B матрицы
    #define C         A2          //  Вывод Arduino, к которому подключён вывод C матрицы
    #define D         A3          //  Вывод Arduino, к которому подключён вывод D матрицы
    #define RATE_SIZE 5           //  Коэффициент усреднения, равный количеству элементов в массиве усреднения
    #define ZUMMER    2           //  Вывод, к которому подключен зуммер
    #define OFF       0           //  Переменная, имеющая значение LOW или 0
    #define ON        1           //  Переменная, имеющая значение HIGH или 1
    MAX30105 PARTICLE_SENSOR;     //  Создаём объект для работы с библиотекой
    //----------------------------//
    //  Объявляем объект MATRIX для работы с матрицей 64х32, включаем двойную буферизацию
    RGBmatrixPanel MATRIX(A, B, C, D, CLK, LAT, OE, false, 64);
    //----------------------------//
    byte  rates[RATE_SIZE];       //  Массив со значениями ЧСС
    byte  rateSpot        = 0;    //  Переменная с порядковым номером значения в массиве
    bool  no_finger_flag  = true; //  Флаг отсутствия приложенного к сенсору пальца
    bool  new_beat_flag   = true; //  Флаг считывания нового удара пульса
    long  lastBeat        = 0;    //  Время последнего зафиксированного удара
    float beatsPerMinute;         //  Создаём переменную для хранения значения ЧСС
    int   beatAvg;                //  Создаём переменную для хранения усреднённого значения ЧСС
    //----------------------------//
    //  Указываем 2 массива с изображениями сердца - малого размера и большого, для создания анимации
    static const unsigned char PROGMEM small_heart[] =
    { 0x03, 0xC0, 0xF0, 0x06, 0x71, 0x8C, 0x0C, 0x1B, 0x06, 0x18, 0x0E, 0x02, 0x10, 0x0C, 0x03, 0x10,
      0x04, 0x01, 0x10, 0x04, 0x01, 0x10, 0x40, 0x01, 0x10, 0x40, 0x01, 0x10, 0xC0, 0x03, 0x08, 0x88,
      0x02, 0x08, 0xB8, 0x04, 0xFF, 0x37, 0x08, 0x01, 0x30, 0x18, 0x01, 0x90, 0x30, 0x00, 0xC0, 0x60,
      0x00, 0x60, 0xC0, 0x00, 0x31, 0x80, 0x00, 0x1B, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x04, 0x00,
    };
    static const unsigned char PROGMEM large_heart[] =
    { 0x01, 0xF0, 0x0F, 0x80, 0x06, 0x1C, 0x38, 0x60, 0x18, 0x06, 0x60, 0x18, 0x10, 0x01, 0x80, 0x08,
      0x20, 0x01, 0x80, 0x04, 0x40, 0x00, 0x00, 0x02, 0x40, 0x00, 0x00, 0x02, 0xC0, 0x00, 0x08, 0x03,
      0x80, 0x00, 0x08, 0x01, 0x80, 0x00, 0x18, 0x01, 0x80, 0x00, 0x1C, 0x01, 0x80, 0x00, 0x14, 0x00,
      0x80, 0x00, 0x14, 0x00, 0x80, 0x00, 0x14, 0x00, 0x40, 0x10, 0x12, 0x00, 0x40, 0x10, 0x12, 0x00,
      0x7E, 0x1F, 0x23, 0xFE, 0x03, 0x31, 0xA0, 0x04, 0x01, 0xA0, 0xA0, 0x0C, 0x00, 0xA0, 0xA0, 0x08,
      0x00, 0x60, 0xE0, 0x10, 0x00, 0x20, 0x60, 0x20, 0x06, 0x00, 0x40, 0x60, 0x03, 0x00, 0x40, 0xC0,
      0x01, 0x80, 0x01, 0x80, 0x00, 0xC0, 0x03, 0x00, 0x00, 0x60, 0x06, 0x00, 0x00, 0x30, 0x0C, 0x00,
      0x00, 0x08, 0x10, 0x00, 0x00, 0x06, 0x60, 0x00, 0x00, 0x03, 0xC0, 0x00, 0x00, 0x01, 0x80, 0x00
    };
    //--------------------------------------------//
    void setup() {
      PARTICLE_SENSOR.begin();                    //  Инициируем работу с сенсором
      MATRIX.begin();                             //  Инициируем работу с матрицей
      MATRIX.setTextWrap(false);                  //  Отключаем перенос текста на следующую строку
      MATRIX.setTextSize(1);                      //  Устанавливаем размер текста равным 1 (6 пикселей на символ)
      pinMode(ZUMMER, OUTPUT);                    //  Настраиваем вывод, к которому подключен зуммер, работать в режиме ВЫХОДА
      PARTICLE_SENSOR.setup();                    //  Запускаем сенсор с настройками по умолчанию
      PARTICLE_SENSOR.setPulseAmplitudeRed(0x0A); //  Выключаем КРАСНЫЙ светодиод для того, чтобы модуль начал работу
      PARTICLE_SENSOR.setPulseAmplitudeGreen(0);  //  Выключаем ЗЕЛЁНЫЙ светодиод
    }
    //----------------------------------------------------------------------------//
    void loop() {
      long irValue = PARTICLE_SENSOR.getIR();                                     //  Считываем значение отражённого ИК-светодиода (отвечающего за пульс) и
      if (irValue > 50000) {                                                      //  если был зафиксирован приложенный к сенсору палец, то
        no_finger_flag = true;                                                    //  устанавливаем флаг отсутствия пальца
        if (new_beat_flag == true) {                                              //  Проверяем, если флаг нового удара пульса установлен, то
          new_beat_flag = false;                                                  //  сбрасываем флаг нового удара сердца
          MATRIX.fillScreen(0);                                                   //  Очищаем экран
          MATRIX.drawBitmap(5, 5, small_heart, 24, 21, MATRIX.Color333(3, 0, 0)); //  Выводим изображение сердца малого размера
          MATRIX.setCursor(37, 5);                                                //  Устанавливаем курсор
          MATRIX.print("BPM:");                                                   //  Выводим текст
          MATRIX.setCursor(40, 20);                                               //  Устанавливаем курсор
          MATRIX.print(beatAvg);                                                  //  Выводим количество ударов в минуту
          MATRIX.swapBuffers(false);                                              //  Выводим изображение из буфера на матрицу
        }
        if (checkForBeat(irValue) == true) {                                      //  Если зафиксирован новый удар пульса, то
          new_beat_flag = true;                                                   //  устанавливаем флаг нового удара
          long delta = millis() - lastBeat;                                       //  вычисляем дельту по времени между 2 соседними ударами
          lastBeat = millis();                                                    //  обновляем счётчик времени
          beatsPerMinute = 60 / (delta / 1000.0);                                 //  вычисляем "сырое" количество ударов в минуту
          if (beatsPerMinute < 255 && beatsPerMinute > 20) {                      //  Дополнительно отфильтровываем значение ударов в минуту и если оно попадает в выборку, то
            rates[rateSpot++] = (byte)beatsPerMinute;                             //  записываем новое значение в массив усреднения
            rateSpot %= RATE_SIZE;                                                //  Задаём порядковый номер значения в массиве, возвращая остаток от деления и присваивая его переменной rateSpot
            beatAvg = 0;                                                          //  Обнуляем переменную и
            for (byte x = 0 ; x < RATE_SIZE ; x++)                                //  в цикле выполняем усреднение значений (чем больше RATE_SIZE, тем сильнее усреднение)
              beatAvg += rates[x];                                                //  путём сложения всех элементов массива
            beatAvg /= RATE_SIZE;                                                 //  а затем деления всей суммы на коэффициент усреднения (на общее количество элементов в массиве)
          }
          digitalWrite(ZUMMER, ON);                                               //  Включаем зуммер
          MATRIX.fillRect(0, 0, 32, 32, MATRIX.Color333(0, 0, 0));                //  Выводим квадрат размером 32х32, закрашенный чёрным, чтобы затереть изображение сердца малого размера
          MATRIX.drawBitmap(0, 0, large_heart, 32, 32, MATRIX.Color333(3, 0, 0)); //  Выводим рисунок сердца большого размера
          MATRIX.swapBuffers(false);                                              //  Выводим изображение из буфера на матрицу
          delay(100);                                                             //  Ждём 100мс, чтобы зуммер и матрица отобразили изменения и включились
          digitalWrite(ZUMMER, OFF);                                              //  Выключаем зуммер
        }
      }
      if (irValue < 50000 && no_finger_flag == true ) {                           //  Если пале убран с сенсора, то
        for (byte x = 0 ; x < RATE_SIZE ; x++) {                                  //  проходим в цикле по массиву усреднения и
          rates[x] = 0;                                                           //  обнуляем его
        }
        beatAvg = 0;                                                              //  обнуляем переменную со значением усреднённой ЧСС
        no_finger_flag = false;                                                   //  сбрасываем флаг отсутствия пальца на сенсоре, чтобы не заходить в этот блок при каждом выполнении цикла
        new_beat_flag = true;                                                     //  Устанавливаем флаг обнаружения пальца, чтобы в следующий проход цикла зайти в блок определения пульса
        MATRIX.fillScreen(0);                                                     //  Очищаем экран
        MATRIX.setTextColor(MATRIX.Color333(3, 3, 3));                            //  Устанавливаем цвет текста
        MATRIX.setCursor(3, 12);                                                  //  Устанавливаем крусор
        MATRIX.println("No finger!");                                             //  Выводим тект о том, что палец не приложен
        MATRIX.swapBuffers(false);                                                //  Выводим изображение из буфера на матрицу
      }
    }

    Комплектация

    • 1x Датчик пульсоксиметрии MAX30102;
    • 1x 4-контактная гребёнка;

    Ссылки

    Похожие товары

    Гарантии и возврат Используя сайт Вы соглашаетесь с условями