e
sv

MAX30102 ve Arduino Projesi: Kalp Atış Hızı ve Kanda Oksijen İzleme

976 Okunma — 19 Şubat 2024 16:05
Dijital Potansiyometre
avatar

Admin

  • e 0

    Mutlu

  • e 0

    Eğlenmiş

  • e 0

    Şaşırmış

  • e 0

    Kızgın

  • e 0

    Üzgün

MAX30102 sensörü ve Arduino ile yapılan projeler, kalp atış hızı ve kanda oksijen seviyelerini izlemek için heyecan verici bir fırsat sunar. Bu projede gerekli malzemeler, MAX30102 sensörünün özellikleri, Arduino’nun kullanımı ve bağlantıları, kalp atış hızını ölçmek ve kanda oksijen seviyesini izlemek için kodlama süreçleri, verilerin okunması ve analiz edilmesi, sonuçların görselleştirilmesi ve projenin geliştirilmesi için öneriler ele alınacaktır. MAX30102 ve Arduino ile kalp atış hızı ve kanda oksijen seviyesi izleme projesinin detaylarına birlikte göz atalım.

Proje için Gerekli Malzemeler

MAX30102 ve Arduino ile kalp atış hızı ve kanda oksijen seviyesi ölçümü yapmak için gerekli olan malzemeler şunlardır:

  • MAX30102 Sensörü: Kızılötesi ve kırmızı LED’lerle donatılmış kompakt bir modüldür. Kan oksijen seviyesini ve kalp atış hızını ölçmek için kullanılır.
  • Arduino Kartı: Projenin kontrolünü sağlayacak olan mikrodenetleyici kartıdır. Veri işleme, sensörlerle iletişim kurma ve sonuçları görselleştirme gibi işlemleri yürütür.
  • Jumper Kablo Seti: Bağlantıların yapılacağı için erkek-dişi, dişi-dişi ve erkek-erkek jumper kablolarına ihtiyaç vardır.
  • Breadboard: Devre elemanlarının geçici olarak bir araya getirilip test edilmesi için kullanılır.
  • USB Kablosu: Arduino kartının bilgisayara bağlanması için gerekli olan USB kablosudur.
  • Bilgisayar: Arduino kartının programlanması ve veri analizinin yapılması için kullanılır.

Bu malzemeler, MAX30102 ve Arduino ile kalp atış hızı ve kanda oksijen seviyesi ölçme projesi için temel gereksinimleri karşılar. Proje için diğer elektronik bileşenler veya materyaller de kullanılabilir, ancak bu malzemeler temel başlangıç için yeterlidir.

MAX30102 Sensörünün Özellikleri

MAX30102 ve Arduino
MAX30102 ve Arduino Projesi: Kalp Atış Hızı ve Kanda Oksijen İzleme 7

MAX30102, fotoelektrik bir sensördür ve kızılötesi ve kırmızı ışık emisyon özelliğine sahiptir. Bu sensör, hem kalp atış hızını ölçme hem de kandaki oksijen seviyesini izleme kabiliyetine sahiptir. Sensörün bazı temel özellikleri şunlardır:

  • Çift Dalga Boyu Ölçümü: MAX30102, hem kızılötesi (IR) ışık hem de kırmızı ışık emisyonunu ölçebilme özelliğine sahiptir. Bu özellik, kan dolaşımındaki oksijenasyon seviyelerini hesaplamak için kullanılır.
  • Esnek Kullanım: Sensör, farklı tasarım ihtiyaçlarına uyum sağlamak için esnek bir yapıya sahiptir. Bu özelliği sayesinde çeşitli tıbbi cihazlarda ve giyilebilir teknolojilerde kullanılabilir.
  • Düşük Güç Tüketimi: MAX30102, düşük güç tüketimi ile uzun pil ömrü sunar. Bu özelliği sayesinde portatif cihazlarda etkili bir şekilde kullanılabilir.
  • Entegre I2C Arayüzü: Sensör, entegre I2C arayüzü sayesinde Arduino gibi mikrodenetleyicilere kolayca bağlanabilir ve veri iletişimini sağlayabilir.
MAX30102 ve Arduino
MAX30102 ve Arduino Projesi: Kalp Atış Hızı ve Kanda Oksijen İzleme 8

MAX30102 sensörü, kalp atış hızı ve kanda oksijen seviyesi ölçümü için yüksek doğruluk, düşük güç tüketimi ve entegre iletişim protokolleri gibi avantajlarıyla Arduino projeleri için ideal bir seçenektir. Bu özellikleri sayesinde sağlık izleme cihazları ve fitness takip cihazları gibi uygulamalarda yaygın olarak kullanılmaktadır. Bu sensör, hem profesyonel hem de hobi amaçlı projeler için uygundur. MAX30102 ve Arduino: Kalp Atış Hızı + Kanda Oksijen İzleme projesi için en temel bileşenlerden biridir.

Arduino’un Kullanımı ve Bağlantıları

MAX30102 ve Arduino
MAX30102 ve Arduino Projesi: Kalp Atış Hızı ve Kanda Oksijen İzleme 9

MAX30102 ve Arduino projenizde sensörü doğru şekilde kullanabilmek için Arduino’nun doğru bir şekilde bağlanması gerekmektedir. İşte bu adımlar:

  • Gereken Malzemeler:

    • MAX30102 sensörü
    • Arduino Uno
    • Erkek dişi jumper kabloları
  • Bağlantılar:

    • MAX30102’nin VCC pin’i Arduino’nun 5V pin’ine bağlanmalıdır.
    • MAX30102’nin GND pin’i Arduino’nun GND pin’ine bağlanmalıdır.
    • MAX30102’nin SCL pin’i Arduino’nun A5 pin’ine bağlanmalıdır.
    • MAX30102’nin SDA pin’i Arduino’nun A4 pin’ine bağlanmalıdır.

Arduino’nun bağlantıları yapıldıktan sonra sensör kullanıma hazır hale gelir. Bu adımları doğru bir şekilde takip ederek, MAX30102 ve Arduino: Kalp Atış Hızı + Kanda Oksijen İzleme projesinde sensörü kullanmaya başlayabilirsiniz. Bu basit bağlantı adımlarıyla projenizi hızlı bir şekilde hayata geçirebilirsiniz.

MAX30102 Nasıl alışır

MAX30102, kalp atış hızı ve oksijen doygunluğu gibi biyometrik verileri ölçmek için kullanılan bir entegre devre (IC) sensörüdür. Bu sensör, kızılötesi ışık ve yeşil ışık kullanarak bu ölçümleri gerçekleştirir. MAX30102’yi kullanmak için aşağıdaki adımları takip edebilirsiniz:

MAX30102 ve Arduino Projesi: Kalp Atış Hızı ve Kanda Oksijen İzleme
MAX30102 ve Arduino Projesi: Kalp Atış Hızı ve Kanda Oksijen İzleme 10
  1. Donanım Bağlantısı:
    • MAX30102’yi mikrodenetleyicinizle (Arduino, Raspberry Pi gibi) bağlayın. Gerekli bağlantılar için MAX30102’nin datasheet’ine bakın.
  2. Kütüphane Kurulumu:
    • Arduino kullanıyorsanız, MAX30102 için uygun bir kütüphaneyi indirip yükleyin. Arduino IDE’yi açın, ardından “Library Manager” (Kütüphane Yöneticisi) bölümünden MAX30102 kütüphanesini arayıp yükleyin.
  3. Kod Yazma:
    • Ardından, ölçümleri yapmak için bir Arduino veya Raspberry Pi programı yazın. Bu program, MAX30102’nin sağladığı verilere erişim sağlamalıdır. Örnek bir Arduino kodu aşağıdaki gibi olabilir:
#include <Wire.h>
#include <MAX30105.h>

MAX30105 particleSensor;

void setup()
{
  Serial.begin(115200);
  Serial.println("MAX30102 Test");

  if (!particleSensor.begin(Wire, I2C_SPEED_FAST))
  {
    Serial.println("Sensor not found. Please check your connections and restart the program.");
    while (1);
  }

  particleSensor.setup();
}

void loop()
{
  // Ölçümleri al
  if (particleSensor.getFIFODataAvailable())
  {
    Serial.println("Reading data...");

    // Ölçümleri al
    particleSensor.readFIFO();

    // Kalp atış hızı ve oksijen doygunluğu değerlerine erişim
    Serial.print("Heart rate: ");
    Serial.print(particleSensor.getHeartRate());
    Serial.print(" bpm, ");

    Serial.print("SpO2: ");
    Serial.print(particleSensor.getSpO2());
    Serial.println("%");
  }
  else
  {
    Serial.println("No data available");
  }
}
  1. Programı Yükleme:
    • Ardından, yazdığınız programı mikrodenetleyicinize yükleyin ve çalıştırın.

Bu adımlar genel bir rehber niteliğindedir ve kullanılan platforma (Arduino, Raspberry Pi, vb.) ve programlama diline (C++, Python, vb.) göre değişebilir. MAX30102‘nin datasheet’i ve kullanılan kütüphanenin belgeleri, daha fazla detay sağlayacaktır. Unutmayın ki sensörün doğru çalışabilmesi için bağlantıları doğru bir şekilde yapmalısınız.

Kalp Atış Hızını Ölçmek için Kodlama

MAX30102 ve Arduino: Kalp Atış Hızı + Kanda Oksijen İzleme projesinde kalp atış hızını ölçmek için kodlama aşaması oldukça önemlidir. Kalp atış hızını ölçmek için sensörden gelen verilerin doğru bir şekilde okunması ve analiz edilmesi gerekmektedir. Bu adımları başarılı bir şekilde gerçekleştirmek için aşağıdaki adımları takip edebilirsiniz:

  • İlk olarak, sensörden gelen verilerin doğru bir şekilde okunabilmesi için gerekli kütüphaneleri Arduino’ya eklemelisiniz.
  • Ardından, sensörden gelen verileri okuyacak olan kod parçacığını oluşturmalısınız.
  • Bu kod parçacığı sayesinde sensörden gelen verileri sürekli olarak okuyarak, kalp atış hızını hesaplayabilirsiniz.
  • Hesaplanan kalp atış hızını ekrana bastırmak veya başka bir şekilde görselleştirmek için gerekli kodları eklemelisiniz.
  • Ayrıca, proje kapsamında olası hata durumlarını da göz önünde bulundurarak gerekli önlemleri almalısınız.

Bu adımları takip ederek, MAX30102 ve Arduino ile kalp atış hızını ölçmek için gerekli olan kodlamayı başarılı bir şekilde gerçekleştirebilirsiniz. Bu sayede projenin temel fonksiyonunu oluşturmuş olacaksınız. Bu aşamadan sonra kanda oksijen seviyesini ölçmek için de benzer adımları takip edebilirsiniz.

Unutmayın, projenin başarılı bir şekilde çalışabilmesi için kodlama aşamasına özen göstermek oldukça önemlidir.

// Include necessary libraries for communication and for the MAX30105 sensor
#include <Wire.h>
#include "MAX30105.h"
#include "heartRate.h"
 
// Create an instance of the MAX30105 class to interact with the sensor
MAX30105 particleSensor;
 
// Define the size of the rates array for averaging BPM; can be adjusted for smoother results
const byte RATE_SIZE = 4; // Increase this for more averaging. 4 is a good starting point.
byte rates[RATE_SIZE]; // Array to store heart rate readings for averaging
byte rateSpot = 0; // Index for inserting the next heart rate reading into the array
long lastBeat = 0; // Timestamp of the last detected beat, used to calculate BPM
 
float beatsPerMinute; // Calculated heart rate in beats per minute
int beatAvg; // Average heart rate after processing multiple readings
 
void setup() {
  Serial.begin(115200); // Start serial communication at 115200 baud rate
  Serial.println("Initializing...");
 
  // Attempt to initialize the MAX30105 sensor. Check for a successful connection and report.
  if (!particleSensor.begin(Wire, I2C_SPEED_FAST)) { // Start communication using fast I2C speed
    Serial.println("MAX30102 was not found. Please check wiring/power. ");
    while (1); // Infinite loop to halt further execution if sensor is not found
  }
  Serial.println("Place your index finger on the sensor with steady pressure.");
 
  particleSensor.setup(); // Configure sensor with default settings for heart rate monitoring
  particleSensor.setPulseAmplitudeRed(0x0A); // Set the red LED pulse amplitude (intensity) to a low value as an indicator
  particleSensor.setPulseAmplitudeGreen(0); // Turn off the green LED as it's not used here
}
 
void loop() {
  long irValue = particleSensor.getIR(); // Read the infrared value from the sensor
 
  if (checkForBeat(irValue) == true) { // Check if a heart beat is detected
    long delta = millis() - lastBeat; // Calculate the time between the current and last beat
    lastBeat = millis(); // Update lastBeat to the current time
 
    beatsPerMinute = 60 / (delta / 1000.0); // Calculate BPM
 
    // Ensure BPM is within a reasonable range before updating the rates array
    if (beatsPerMinute < 255 && beatsPerMinute > 20) {
      rates[rateSpot++] = (byte)beatsPerMinute; // Store this reading in the rates array
      rateSpot %= RATE_SIZE; // Wrap the rateSpot index to keep it within the bounds of the rates array
 
      // Compute the average of stored heart rates to smooth out the BPM
      beatAvg = 0;
      for (byte x = 0 ; x < RATE_SIZE ; x++)
        beatAvg += rates[x];
      beatAvg /= RATE_SIZE;
    }
  }
 
  // Output the current IR value, BPM, and averaged BPM to the serial monitor
  Serial.print("IR=");
  Serial.print(irValue);
  Serial.print(", BPM=");
  Serial.print(beatsPerMinute);
  Serial.print(", Avg BPM=");
  Serial.print(beatAvg);
 
  // Check if the sensor reading suggests that no finger is placed on the sensor
  if (irValue < 50000)
    Serial.print(" No finger?");
 
  Serial.println();
}

Kanda Oksijen Seviyesini Ölçmek için Kodlama

MAX30102 ve Arduino: Kalp Atış Hızı + Kanda Oksijen İzleme projesinde kanda oksijen seviyesini ölçmek için kodlama oldukça önemlidir. Bu adımda, sensörden alınan verilerin doğru bir şekilde okunması ve yorumlanması gerekmektedir. İşte bu süreci kolaylaştırmak için kullanabileceğiniz adımlar:

  • İlk olarak, sensörden gelen verileri okumak için gerekli kütüphaneleri Arduino’ya eklemelisiniz. Bu adımda, MAX30102 sensörü için özel olarak geliştirilmiş kütüphaneleri kullanabilirsiniz.
  • Ardından, sensörden alınan verileri filtrelemek ve analiz etmek için kodlama yapmanız gerekecektir. Bu adımda, ölçülen oksijen seviyesini doğru bir şekilde hesaplamak için belirli algoritmalar kullanabilirsiniz.
  • Verileri okuduktan ve analiz ettikten sonra, elde ettiğiniz sonuçları belirli bir formatta görselleştirmeniz gerekebilir. Bu sayede, elde ettiğiniz verileri daha anlaşılır bir şekilde sunabilirsiniz.

Kanda oksijen seviyesini ölçmek için kodlama aşamasında, hassaslık ve doğruluk oldukça önemlidir. Doğru kodlama sayesinde elde edilen verilerin doğruluğu artar ve proje başarısı sağlanmış olur. Bu adımda dikkatlice kodlama yaparak, kanda oksijen seviyesini doğru bir şekilde ölçebilir ve projenizi başarılı bir şekilde tamamlayabilirsiniz.

#include <Wire.h>
#include "MAX30105.h" // Include MAX30105 sensor library
#include "spo2_algorithm.h" // Include SpO2 calculation algorithm
 
MAX30105 particleSensor; // Create an instance of the MAX30105 class
 
#define MAX_BRIGHTNESS 255 // Define maximum LED brightness
 
// Adjust buffer size based on the microcontroller's memory capacity
#if defined(__AVR_ATmega328P__) || defined(__AVR_ATmega168__)
uint16_t irBuffer[100]; // Buffer for IR data (16-bit for memory-limited devices)
uint16_t redBuffer[100]; // Buffer for red LED data
#else
uint32_t irBuffer[100]; // Buffer for IR data (32-bit for devices with more memory)
uint32_t redBuffer[100]; // Buffer for red LED data
#endif
 
int32_t bufferLength = 100; // Length of data buffer
int32_t spo2; // Variable to store calculated SpO2 value
int8_t validSPO2; // Flag indicating if SpO2 calculation is valid
int32_t heartRate; // Variable to store calculated heart rate
int8_t validHeartRate; // Flag indicating if heart rate calculation is valid
 
byte pulseLED = 11; // LED pin for pulse indication (must support PWM)
byte readLED = 13; // LED pin to indicate data read operation
 
void setup() {
  Serial.begin(115200); // Initialize serial communication
  pinMode(pulseLED, OUTPUT); // Set pulseLED as output
  pinMode(readLED, OUTPUT); // Set readLED as output
 
  // Initialize MAX30105 sensor
  if (!particleSensor.begin(Wire, I2C_SPEED_FAST)) {
    Serial.println(F("MAX30105 not found. Check wiring/power."));
    while (1); // Halt execution if sensor not found
  }
 
  Serial.println(F("Attach sensor to finger. Press key to start."));
  while (Serial.available() == 0); // Wait for user input to proceed
  Serial.read(); // Clear the serial buffer
 
  // Sensor configuration settings
  byte ledBrightness = 60; // LED brightness (0-255)
  byte sampleAverage = 4; // Averaging (1, 2, 4, 8, 16, 32)
  byte ledMode = 2; // LED mode (1=Red, 2=Red+IR, 3=Red+IR+Green)
  byte sampleRate = 100; // Sampling rate (50, 100, 200, 400, 800, 1000, 1600, 3200)
  int pulseWidth = 411; // Pulse width (69, 118, 215, 411)
  int adcRange = 4096; // ADC range (2048, 4096, 8192, 16384)
 
  // Apply configuration settings to the sensor
  particleSensor.setup(ledBrightness, sampleAverage, ledMode, sampleRate, pulseWidth, adcRange);
}
 
void loop() {
  // Collect 100 samples and output raw red and IR data
  for (byte i = 0; i < bufferLength; i++) {
    while (!particleSensor.available()) particleSensor.check(); // Wait for new data
 
    redBuffer[i] = particleSensor.getRed(); // Store red LED data
    irBuffer[i] = particleSensor.getIR(); // Store IR data
    particleSensor.nextSample(); // Move to next sample
 
    Serial.print(F("red="));
    Serial.print(redBuffer[i], DEC);
    Serial.print(F(", ir="));
    Serial.println(irBuffer[i], DEC);
  }
 
  // Calculate heart rate and SpO2 from the first 100 samples
  maxim_heart_rate_and_oxygen_saturation(irBuffer, bufferLength, redBuffer, &spo2, &validSPO2, &heartRate, &validHeartRate);
 
  // Continuously update heart rate and SpO2 values with new samples
  while (1) {
    // Shift the last 75 samples to the beginning and fill the remaining with new data
    for (byte i = 25; i < 100; i++) {
      redBuffer[i - 25] = redBuffer[i];
      irBuffer[i - 25] = irBuffer[i];
    }
 
    // Collect new samples to refill the buffer
    for (byte i = 75; i < 100; i++) {
      while (!particleSensor.available()) particleSensor.check(); // Wait for new data
 
      digitalWrite(readLED, !digitalRead(readLED)); // Blink LED with each data read
 
      redBuffer[i] = particleSensor.getRed(); // Store new red data
      irBuffer[i] = particleSensor.getIR(); // Store new IR data
      particleSensor.nextSample(); // Move to next sample
 
      // Output raw data and calculated heart rate/SpO2 values
      Serial.print(F("red="));
      Serial.print(redBuffer[i], DEC);
      Serial.print(F(", ir="));
      Serial.print(irBuffer[i], DEC);
      Serial.print(F(", HR="));
      Serial.print(heartRate, DEC);
      Serial.print(F(", HRvalid="));
      Serial.print(validHeartRate, DEC);
      Serial.print(F(", SPO2="));
      Serial.print(spo2, DEC);
      Serial.print(F(", SPO2Valid="));
      Serial.println(validSPO2, DEC);
    }
 
    // Recalculate heart rate and SpO2 with the updated buffer
    maxim_heart_rate_and_oxygen_saturation(irBuffer, bufferLength, redBuffer, &spo2, &validSPO2, &heartRate, &validHeartRate);
  }
}

Verilerin Okunması ve Analiz Edilmesi

MAX30102 ve Arduino: Kalp Atış Hızı + Kanda Oksijen İzleme projenizde sensörlerden gelen verileri okumak ve analiz etmek oldukça önemlidir. Bu adımda, sensörlerden elde edilen verileri nasıl okuyacağınızı ve bu verileri nasıl analiz edeceğinizi öğreneceksiniz.

Verileri okumak için Arduino’nun sağladığı serial communication özelliğini kullanabilirsiniz. Bu sayede sensörlerden gelen verileri seri bağlantı aracılığıyla Arduino’ya iletebilir ve Arduino üzerinden bu verileri okuyabilirsiniz. Veri okuma işlemi için basit bir Arduino kodu ile serial monitor üzerinden sensör verilerini gözlemleyebilirsiniz.

Daha sonra elde ettiğiniz verileri analiz etmek için farklı yöntemler izleyebilirsiniz. Örneğin, kalp atış hızı verilerini zaman serisi grafiği ile görselleştirebilir ve düzenli aralıklarla ölçülen oksijen seviyelerini karşılaştırmak için basit bir tablo oluşturabilirsiniz.

Ayrıca, elde ettiğiniz verileri istatistiksel olarak analiz ederek, kullanıcıların kalp atış hızı ve oksijen seviyeleri hakkında daha derinlemesine bilgi sahibi olmalarını sağlayabilirsiniz. Bu analizler sayesinde kullanıcıların sağlık durumunu izlemelerine yardımcı olabilir ve gerektiğinde tıbbi yardım almalarını sağlayabilirsiniz.

Bu adımda, elde ettiğiniz verileri nasıl okuyacağınızı ve analiz edeceğinizi öğrendiniz. Bir sonraki adımda bu verileri nasıl görselleştireceğinizi ve projenizi nasıl geliştirebileceğinizi öğreneceksiniz.

Sonuçların Görselleştirilmesi

Proje başarıyla tamamlandıktan sonra elde edilen verilerin etkili bir şekilde görselleştirilmesi oldukça önemlidir. MAX30102 ve Arduino ile yapılan Kalp Atış Hızı ve Kanda Oksijen İzleme projesinin sonuçlarını görselleştirmek için çeşitli yöntemler kullanılabilir. Bu adımlar şunlardır:

MAX30102 ve Arduino
MAX30102 ve Arduino Projesi: Kalp Atış Hızı ve Kanda Oksijen İzleme 11
  • Grafiklerle Veri Görselleştirme: Elde edilen kalp atış hızı ve kanda oksijen seviyesi verileri, çizgi grafikleri veya nokta grafikleri kullanılarak görselleştirilebilir. Bu grafikler sayesinde elde edilen verilerin zamana bağlı değişimleri kolayca takip edilebilir.
  • Bar Grafikleri ile Karşılaştırmalı Analiz: Farklı deneme grupları veya zaman aralıkları arasındaki veri karşılaştırmaları için bar grafikleri oldukça yararlı olabilir. Kalp atış hızı ve oksijen seviyesindeki değişimlerin karşılaştırmalı analizi bu şekilde kolaylıkla yapılabilir.

Projenin amacı ve hedefleri doğrultusunda, elde edilen verilerin en etkili şekilde görselleştirilmesi için farklı grafikleme tekniklerinin kullanılması gerekebilir. Bununla birlikte, görselleştirmelerin okunabilir ve anlaşılabilir olmasına özen gösterilmelidir.

Bu adımların ardından elde edilen görsel veriler, projenin sonuçları ve analizleri için oldukça değerli olacaktır. Bu görselleştirmeler, projenin amacına ulaşma ve elde edilen verilerin anlaşılabilirliği açısından büyük önem taşımaktadır.

Bu adımların ardından elde edilen görsel veriler, projenin sonuçları ve analizleri için oldukça değerli olacaktır. Bu görselleştirmeler, projenin amacına ulaşma ve elde edilen verilerin anlaşılabilirliği açısından büyük önem taşımaktadır.

#include "ssd1306h.h"
#include "MAX30102.h"
#include "Pulse.h"
#include <avr/pgmspace.h>
#include <EEPROM.h>
#include <avr/sleep.h>
 
#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif
#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif
 
 
SSD1306 oled;
MAX30102 sensor;
Pulse pulseIR;
Pulse pulseRed;
MAFilter bpm;
 
#define LED LED_BUILTIN
#define BUTTON 3
#define OPTIONS 7
 
static const uint8_t heart_bits[] PROGMEM = { 0x00, 0x00, 0x38, 0x38, 0x7c, 0x7c, 0xfe, 0xfe, 0xfe, 0xff,
                                              0xfe, 0xff, 0xfc, 0x7f, 0xf8, 0x3f, 0xf0, 0x1f, 0xe0, 0x0f,
                                              0xc0, 0x07, 0x80, 0x03, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
                                              0x00, 0x00
                                            };
 
//spo2_table is approximated as  -45.060*ratioAverage* ratioAverage + 30.354 *ratioAverage + 94.845 ;
const uint8_t spo2_table[184] PROGMEM =
{ 95, 95, 95, 96, 96, 96, 97, 97, 97, 97, 97, 98, 98, 98, 98, 98, 99, 99, 99, 99,
  99, 99, 99, 99, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100,
  100, 100, 100, 100, 99, 99, 99, 99, 99, 99, 99, 99, 98, 98, 98, 98, 98, 98, 97, 97,
  97, 97, 96, 96, 96, 96, 95, 95, 95, 94, 94, 94, 93, 93, 93, 92, 92, 92, 91, 91,
  90, 90, 89, 89, 89, 88, 88, 87, 87, 86, 86, 85, 85, 84, 84, 83, 82, 82, 81, 81,
  80, 80, 79, 78, 78, 77, 76, 76, 75, 74, 74, 73, 72, 72, 71, 70, 69, 69, 68, 67,
  66, 66, 65, 64, 63, 62, 62, 61, 60, 59, 58, 57, 56, 56, 55, 54, 53, 52, 51, 50,
  49, 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, 31, 30, 29,
  28, 27, 26, 25, 23, 22, 21, 20, 19, 17, 16, 15, 14, 12, 11, 10, 9, 7, 6, 5,
  3, 2, 1
} ;
 
 
int getVCC() {
  //reads internal 1V1 reference against VCC
#if defined(__AVR_ATmega1284P__)
  ADMUX = _BV(REFS0) | _BV(MUX4) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);  // For ATmega1284
#else
  ADMUX = _BV(REFS0) | _BV(MUX3) | _BV(MUX2) | _BV(MUX1);  // For ATmega328
#endif
  delay(2); // Wait for Vref to settle
  ADCSRA |= _BV(ADSC); // Convert
  while (bit_is_set(ADCSRA, ADSC));
  uint8_t low = ADCL;
  unsigned int val = (ADCH << 8) | low;
  //discard previous result
  ADCSRA |= _BV(ADSC); // Convert
  while (bit_is_set(ADCSRA, ADSC));
  low = ADCL;
  val = (ADCH << 8) | low;
 
  return (((long)1024 * 1100) / val) / 100;
}
 
void print_digit(int x, int y, long val, char c = ' ', uint8_t field = 3, const int BIG = 2)
{
  uint8_t ff = field;
  do {
    char ch = (val != 0) ? val % 10 + '0' : c;
    oled.drawChar( x + BIG * (ff - 1) * 6, y, ch, BIG);
    val = val / 10;
    --ff;
  } while (ff > 0);
}
 
 
/*
     Record, scale  and display PPG Wavefoem
*/
const uint8_t MAXWAVE = 72;
 
class Waveform {
  public:
    Waveform(void) {
      wavep = 0;
    }
 
    void record(int waveval) {
      waveval = waveval / 8;       // scale to fit in byte  缩放以适合字节
      waveval += 128;              //shift so entired waveform is +ve
      waveval = waveval < 0 ? 0 : waveval;
      waveform[wavep] = (uint8_t) (waveval > 255) ? 255 : waveval;
      wavep = (wavep + 1) % MAXWAVE;
    }
 
    void scale() {
      uint8_t maxw = 0;
      uint8_t minw = 255;
      for (int i = 0; i < MAXWAVE; i++) {
        maxw = waveform[i] > maxw ? waveform[i] : maxw;
        minw = waveform[i] < minw ? waveform[i] : minw;
      }
      uint8_t scale8 = (maxw - minw) / 4 + 1; //scale * 8 to preserve precision
      uint8_t index = wavep;
      for (int i = 0; i < MAXWAVE; i++) {
        disp_wave[i] = 31 - ((uint16_t)(waveform[index] - minw) * 8) / scale8;
        index = (index + 1) % MAXWAVE;
      }
    }
 
    void draw(uint8_t X) {
      for (int i = 0; i < MAXWAVE; i++) {
        uint8_t y = disp_wave[i];
        oled.drawPixel(X + i, y);
        if (i < MAXWAVE - 1) {
          uint8_t nexty = disp_wave[i + 1];
          if (nexty > y) {
            for (uint8_t iy = y + 1; iy < nexty; ++iy)
              oled.drawPixel(X + i, iy);
          }
          else if (nexty < y) {
            for (uint8_t iy = nexty + 1; iy < y; ++iy)
              oled.drawPixel(X + i, iy);
          }
        }
      }
    }
 
  private:
    uint8_t waveform[MAXWAVE];
    uint8_t disp_wave[MAXWAVE];
    uint8_t wavep = 0;
 
} wave;
 
int  beatAvg;
int  SPO2, SPO2f;
int  voltage;
bool filter_for_graph = false;
bool draw_Red = false;
uint8_t pcflag = 0;
uint8_t istate = 0;
uint8_t sleep_counter = 0;
 
void button(void) {
  pcflag = 1;
}
 
void checkbutton() {
  if (pcflag && !digitalRead(BUTTON)) {
    istate = (istate + 1) % 4;
    filter_for_graph = istate & 0x01;
    draw_Red = istate & 0x02;
    EEPROM.write(OPTIONS, filter_for_graph);
    EEPROM.write(OPTIONS + 1, draw_Red);
  }
  pcflag = 0;
}
 
 
 
void Display_5() {
  if (pcflag && !digitalRead(BUTTON)) {
    draw_oled(5);
    delay(1100);
  }
  pcflag = 0;
 
 
}
 
void go_sleep() {
  oled.fill(0);
  oled.off();
  delay(10);
  sensor.off();
  delay(10);
  cbi(ADCSRA, ADEN);  // disable adc
  delay(10);
  pinMode(0, INPUT);
  pinMode(2, INPUT);
  set_sleep_mode(SLEEP_MODE_PWR_DOWN);
  sleep_mode();  // sleep until button press
  // cause reset
  setup();
}
 
void draw_oled(int msg) {
  oled.firstPage();
  do {
    switch (msg) {
      case 0:  oled.drawStr(10, 0, F("Device error"), 1);
        break;
      case 1:  oled.drawStr(0, 0, F("PLACE YOUR"), 2);
        oled.drawStr(25, 18, F("FINGER"), 2);
 
 
        break;
      case 2:  print_digit(86, 0, beatAvg);
        oled.drawStr(0, 3, F("PULSE RATE"), 1);
        oled.drawStr(11, 17, F("OXYGEN"), 1);
        oled.drawStr(0, 25, F("SATURATION"), 1);
        print_digit(73, 16, SPO2f, ' ', 3, 2);
        oled.drawChar(116, 16, '%', 2);
 
        break;
      case 3:  oled.drawStr(33, 0, F("Pulse"), 2);
        oled.drawStr(17, 15, F("Oximeter"), 2);
 
        //oled.drawXBMP(6,8,16,16,heart_bits);
 
        break;
      case 4:  oled.drawStr(28, 12, F("OFF IN"), 1);
        oled.drawChar(76, 12, 10 - sleep_counter / 10 + '0');
        oled.drawChar(82, 12, 's');
        break;
      case 5:  oled.drawStr(0, 0, F("Avg Pulse"), 1);
        print_digit(75, 0, beatAvg);
        oled.drawStr(0, 15, F("AVG OXYGEN"), 1);
        oled.drawStr(0, 22, F("saturation"), 1);
        print_digit(75, 15, SPO2);
 
        break;
    }
  } while (oled.nextPage());
}
 
void setup(void) {
  pinMode(LED, OUTPUT);
  pinMode(BUTTON, INPUT_PULLUP);
  filter_for_graph = EEPROM.read(OPTIONS);
  draw_Red = EEPROM.read(OPTIONS + 1);
  oled.init();
  oled.fill(0x00);
  draw_oled(3);
  delay(3000);
  if (!sensor.begin())  {
    draw_oled(0);
    while (1);
  }
  sensor.setup();
  attachInterrupt(digitalPinToInterrupt(BUTTON), button, CHANGE);
}
 
long lastBeat = 0;    //Time of the last beat
long displaytime = 0; //Time of the last display update
bool led_on = false;
 
 
void loop()  {
  sensor.check();
  long now = millis();   //start time of this cycle
  if (!sensor.available()) return;
  uint32_t irValue = sensor.getIR();
  uint32_t redValue = sensor.getRed();
  sensor.nextSample();
  if (irValue < 5000) {
    voltage = getVCC();
    checkbutton();
    draw_oled(sleep_counter <= 50 ? 1 : 4); // finger not down message
    //? : :if(x>y)z=x;elsez=y
    delay(200);
    ++sleep_counter;
    if (sleep_counter > 100) {
      go_sleep();
      sleep_counter = 0;
    }
  } else {
    sleep_counter = 0;
    // remove DC element
    int16_t IR_signal, Red_signal;
    bool beatRed, beatIR;
    if (!filter_for_graph) {
      IR_signal =  pulseIR.dc_filter(irValue) ;
      Red_signal = pulseRed.dc_filter(redValue);
      beatRed = pulseRed.isBeat(pulseRed.ma_filter(Red_signal));
      beatIR =  pulseIR.isBeat(pulseIR.ma_filter(IR_signal));
    } else {
      IR_signal =  pulseIR.ma_filter(pulseIR.dc_filter(irValue)) ;
      Red_signal = pulseRed.ma_filter(pulseRed.dc_filter(redValue));
      beatRed = pulseRed.isBeat(Red_signal);
      beatIR =  pulseIR.isBeat(IR_signal);
    }
    // invert waveform to get classical BP waveshape
    wave.record(draw_Red ? -Red_signal : -IR_signal );
    // check IR or Red for heartbeat
    if (draw_Red ? beatRed : beatIR) {
      long btpm = 60000 / (now - lastBeat);
      if (btpm > 0 && btpm < 200) beatAvg = bpm.filter((int16_t)btpm);
      lastBeat = now;
      digitalWrite(LED, HIGH);
      led_on = true;
      // compute SpO2 ratio
      long numerator   = (pulseRed.avgAC() * pulseIR.avgDC()) / 256;
      long denominator = (pulseRed.avgDC() * pulseIR.avgAC()) / 256;
      int RX100 = (denominator > 0) ? (numerator * 100) / denominator : 999;
      // using formula
      SPO2f = (10400 - RX100 * 17 + 50) / 100;
      // from table
      if ((RX100 >= 0) && (RX100 < 184))
        SPO2 = pgm_read_byte_near(&spo2_table[RX100]);
    }
    // update display every 50 ms if fingerdown
    if (now - displaytime > 50) {
      displaytime = now;
      wave.scale();
      draw_oled(2);
 
    }
    Display_5();
 
 
  }
  // flash led for 25 ms
  if (led_on && (now - lastBeat) > 25) {
    digitalWrite(LED, LOW);
    led_on = false;
  }
}

Projenin Geliştirilmesi İçin Öneriler

MAX30102 ve Arduino: Kalp Atış Hızı + Kanda Oksijen İzleme projesini geliştirmek ve daha verimli hale getirmek istiyorsanız aşağıdaki önerileri dikkate alabilirsiniz:

  • Veri Hassasiyetinin Artırılması: Sensörün hassasiyetini artırmak için farklı algoritmalar ve filtreleme teknikleri kullanılabilir. Bu, daha doğru kalp atış hızı ve oksijen seviyesi ölçümleri elde etmenizi sağlayacaktır.

  • Enerji Verimliliği İçin Optimize Edilmiş Kodlama: Arduino kodlarınızı gözden geçirerek, enerji tüketimini en aza indirecek şekilde optimize edebilirsiniz. Bu, cihazın daha uzun süre kullanılmasını sağlayacaktır.

  • Veri Görselleştirme Arayüzü: Elde ettiğiniz verileri daha anlaşılır bir şekilde görselleştirmek için kullanıcı dostu bir arayüz geliştirebilirsiniz. Grafikler, tablolar ve gerçek zamanlı veri akışını görüntülemek için bir ekran ekleyebilirsiniz.

  • Taşınabilirlik: Projeyi taşınabilir hale getirmek için mini bir ekran ve pil desteği ekleyebilirsiniz. Böylelikle, kullanıcılar istedikleri her yerde kalp atış hızı ve oksijen seviyesi ölçümlerini yapabilirler.

Bu önerileri dikkate alarak, MAX30102 ve Arduino ile gerçekleştirdiğiniz proje üzerinde daha kapsamlı ve kullanışlı geliştirmeler yapabilirsiniz.

Sıkça Sorulan Sorular

MAX30102 nedir?

MAX30102, kalp atış hızı ve kanda oksijen seviyesini izlemek için kullanılan bir entegredir. Optik biyolojik sensörleri olan bu entegre, Arduino gibi mikrodenetleyicilerle entegre edilerek sağlık izleme projelerinde kullanılabilir.

Arduino Projesi nedir?

Bir Arduino Projesi, Arduino platformu kullanılarak geliştirilen bir projedir. Bu projeler genellikle sensörler, motorlar, ışıklar ve diğer bileşenlerle etkileşimli hale getirilmiş elektronik projelerdir. MAX30102 ve Arduino ile yapılan proje, kalp atış hızı ve kanda oksijen seviyesini ölçen bir sağlık izleme projesi olabilir.

MAX30102 ve Arduino ile ne tür projeler yapılabilir?

MAX30102 ve Arduino ile kalp atış hızı izleme, kanda oksijen seviyesi ölçme, uyku izleme cihazları, fizyolojik durum izleme cihazları gibi sağlık izleme projeleri yapılabilir. Ayrıca spor performans izleme cihazları ve stres ölçüm cihazları da geliştirilebilir.

MAX30102 ve Arduino ile sağlık izleme projeleri nasıl oluşturulur?

Sağlık izleme projeleri için öncelikle MAX30102 sensörü ve Arduino kartı entegre edilir. Daha sonra sensörden alınan veriler Arduino üzerinde işlenir ve istenilen özelliklere göre yazılım geliştirilir. Son adımda ise elde edilen sonuçlar kullanıcıya görüntülenir veya kaydedilir.

MAX30102 ve Arduino ile hangi sağlık verileri ölçülebilir?

MAX30102 ve Arduino ile kalp atış hızı (bpm), kanda oksijen seviyesi (SpO2), nabız dalgalanma indeksi gibi sağlık verileri ölçülebilir. Ayrıca solunum hızı ve fizyolojik aktivite izlemleri de yapılabilir.

etiketlerETİKETLER
Üzgünüm, bu içerik için hiç etiket bulunmuyor.
okuyucu yorumlarıOKUYUCU YORUMLARI

Yorum yapabilmek için giriş yapmalısınız.

Sıradaki içerik:

MAX30102 ve Arduino Projesi: Kalp Atış Hızı ve Kanda Oksijen İzleme

Araç çubuğuna atla