Получение BPM из данного кода

Я нашел код, который может мигать светодиодом на Arduino в соответствии с сердцебиением. Я использую AD8232 в качестве датчика частоты сердечных сокращений.

Код для этого таков:

// Переменные
int PulseSensorPurplePin = 0; // Pulse Sensor PURPLE WIRE connected to ANALOG PIN 0
int LED13 = 13; // Бортовой сигнал Arduino LED
int Signal; // содержит входящие необработанные данные. Значение сигнала может варьироваться от 0 до 1024
int Threshold = 550; // Определите, какой сигнал "считать биением", а какой проглотить.

void setup() {
  pinMode(LED13, OUTPUT); // контакт, который будет мигать в такт вашему сердцебиению
  Serial.begin(9600); // Устанавливает последовательную связь с определенной скоростью.
}

void loop() {
  Signal = analogRead(PulseSensorPurplePin); // Считайте значение PulseSensor.
  // Назначьте это значение переменной "Signal".
  Serial.println(Signal); // Отправить значение сигнала на последовательный плоттер.
  if(Signal > Threshold) {
    // Если сигнал выше "550", то "включите" бортовой светодиод Arduino.
    digitalWrite(LED13, HIGH);
  } else {
    digitalWrite(LED13, LOW); // Иначе сигнал должен быть ниже "550", поэтому "выключите" этот светодиод.
  }
  delay(10);
}

Мой вопрос: как я могу получить BPM?

Отредактировано ниже:

Является ли этот код для BPM правильным?

int x = 0;
int LastTime = 0;
bool BPMTiming = false;
bool BeatComplete = false;
int BPM = 0;    
#define UpperThreshold 518
#define LowerThreshold 490    
int LED13 = 44; // The on-board Arduino LED
int Signal; // содержит входящие необработанные данные. Значение сигнала может варьироваться от 0 до 1024

void setup() {
  pinMode(LED13, OUTPUT);
  Serial.begin(9600);
}

void loop() {
  int value = analogRead(0);
  if (value > UpperThreshold) {
    if (BeatComplete) {
      BPM = millis() - LastTime;
      BPM = int(60 / (float(BPM) / 1000));
      BPMTiming = false;
      BeatComplete = false;
    }
    if (BPMTiming == false) {
      LastTime = millis();
      BPMTiming = true;
    }
  }
  if ((value < LowerThreshold) & (BPMTiming))
    BeatComplete = true;
    // показать bpm
  Serial.print(BPM);
  Serial.println(" BPM");
  x++;
  Signal = analogRead(0); // Считывание значения датчика пульса.
  // Назначьте это значение переменной "Signal".
  if (Signal > UpperThreshold) {
    // Если сигнал выше "550", то "включите" бортовой светодиод Arduino.
    digitalWrite(LED13, HIGH);
  } else {
    digitalWrite(LED13, LOW); // Иначе сигнал должен быть ниже "550", поэтому "выключите" этот светодиод.
  }
}

, 👍3

Обсуждение

можете ли вы получить код для меня при использовании nodemcu и датчика импульсов? я пробовал это много раз, но все равно получается больше 100. Мне нужно войти в нормальный bpm, @user61363


1 ответ


Лучший ответ:

2

Если вы знаете интервал между ударами сердца, вы можете рассчитать частоту по формуле: частота = 1 / время. Теперь, если вы возьмете частоту и умножите ее на 60, то получите BPM.

У меня нет одного из датчиков, которые вы используете, поэтому я подключил потенциометр к контакту A0, чтобы проверить этот код.

    int UpperThreshold = 518;
    int LowerThreshold = 490;
    int reading = 0;
    float BPM = 0.0;
    bool IgnoreReading = false;
    bool FirstPulseDetected = false;
    unsigned long FirstPulseTime = 0;
    unsigned long SecondPulseTime = 0;
    unsigned long PulseInterval = 0;

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

    void loop(){

      reading = analogRead(0); 

      // Обнаружен передний край сердечного ритма.
      if(reading > UpperThreshold && IgnoreReading == false){
        if(FirstPulseDetected == false){
          FirstPulseTime = millis();
          FirstPulseDetected = true;
        }
        else{
          SecondPulseTime = millis();
          PulseInterval = SecondPulseTime - FirstPulseTime;
          FirstPulseTime = SecondPulseTime;
        }
        IgnoreReading = true;
      }

      // Обнаружена задняя кромка сердечного ритма.
      if(reading < LowerThreshold){
        IgnoreReading = false;
      }  

      BPM = (1.0/PulseInterval) * 60.0 * 1000;

      Serial.print(reading);
      Serial.print("\t");
      Serial.print(PulseInterval);
      Serial.print("\t");
      Serial.print(BPM);
      Serial.println(" BPM");
      Serial.flush();

      // Пожалуйста, не используйте delay() - это только для целей тестирования.
      delay(50);  
    }

Обновленный ответ в ответ на ваши комментарии ниже:

Скетч считывает данные и отправляет их на последовательный монитор каждые 50 мс из-за задержки(50). Что, если мы изменим это на 1000 мс? Последовательный монитор будет обновляться один раз в секунду, что будет более "удобочитаемым". Проблема с этой идеей заключается в том, что при частоте сердечных сокращений выше 60 ударов в минуту показания будут неточными. У меня нет датчика для тестирования, но я предполагаю, что задержка в 1 секунду сделает код неработоспособным.

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

Мы можем сделать это без каких-либо библиотек, используя millis(). Вот обновленный скетч с использованием millis() для таймеров. К этому скетчу добавлено мигание бортового светодиода. Я использую Uno, так что вам придется изменить LED_BUILDIN на любой контакт, который вы используете.

int UpperThreshold = 518;
int LowerThreshold = 490;
int reading = 0;
float BPM = 0.0;
bool IgnoreReading = false;
bool FirstPulseDetected = false;
unsigned long FirstPulseTime = 0;
unsigned long SecondPulseTime = 0;
unsigned long PulseInterval = 0;
const unsigned long delayTime = 10;
const unsigned long delayTime2 = 1000;
const unsigned long baudRate = 9600;
unsigned long previousMillis = 0;
unsigned long previousMillis2 = 0;

void setup(){
  Serial.begin(baudRate);
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, LOW);
}

void loop(){

  // Получить текущее время
  unsigned long currentMillis = millis();

  // Первое событие
  if(myTimer1(delayTime, currentMillis) == 1){

    reading = analogRead(0); 

    // Обнаружен передний край сердечного ритма.
    if(reading > UpperThreshold && IgnoreReading == false){
      if(FirstPulseDetected == false){
        FirstPulseTime = millis();
        FirstPulseDetected = true;
      }
      else{
        SecondPulseTime = millis();
        PulseInterval = SecondPulseTime - FirstPulseTime;
        FirstPulseTime = SecondPulseTime;
      }
      IgnoreReading = true;
      digitalWrite(LED_BUILTIN, HIGH);
    }

    // Обнаружена задняя кромка сердечного ритма.
    if(reading < LowerThreshold && IgnoreReading == true){
      IgnoreReading = false;
      digitalWrite(LED_BUILTIN, LOW);
    }  

    // Рассчитать удары в минуту.
    BPM = (1.0/PulseInterval) * 60.0 * 1000;
  }

  // Второе событие
  if(myTimer2(delayTime2, currentMillis) == 1){
    Serial.print(reading);
    Serial.print("\t");
    Serial.print(PulseInterval);
    Serial.print("\t");
    Serial.print(BPM);
    Serial.println(" BPM");
    Serial.flush();
  }
}

// First event timer
int myTimer1(long delayTime, long currentMillis){
  if(currentMillis - previousMillis >= delayTime){previousMillis = currentMillis;return 1;}
  else{return 0;}
}

// Second event timer
int myTimer2(long delayTime2, long currentMillis){
  if(currentMillis - previousMillis2 >= delayTime2){previousMillis2 = currentMillis;return 1;}
  else{return 0;}
}

Размер компиляции кода с задержкой составляет 4732 против таймеров millis на уровне 4682 (с удаленным светодиодным кодом). Два таймера дешевле цены одной задержки :)

Светодиод будет гореть в течение всего времени, пока показания сердечного ритма будут находиться выше нижнего порога. Если вы хотите, чтобы он был включен дольше или решите, как долго он должен быть включен, я не буду писать код для вас, но дам вам подсказку. Вы можете снова скопировать myTimer1() и сделать третий таймер.

,

Большое вам спасибо за ответ и за редактирование моего вопроса, предоставленный вами код работает безупречно, но у меня есть светодиод, подключенный к контакту 44, я хочу указать, что светодиод для каждого удара сердца, это означает, что когда происходит удар, этот светодиод должен мигать.. и еще : в течение первых нескольких секунд на последовательном мониторе BPM показывает более 500 значений - иногда и 1000, как этого избежать? См.Мою правку.., @Mudassir Hussain

Видишь это http://s44.photobucket.com/user/beingmachine/media/Screen%20Shot%202017-08-23%20at%204.00.08%20PM_zpshktk2ucq.png.html, @Mudassir Hussain