Arduino ile MAX30100 Kalp Nabız Sensörü Kullanımı
Öncelikle MAX30100’ün nabız hızını nasıl ölçtüğünü açıklamaya çalışayım. Cihaz, biri kırmızı ışık yayan, diğeri kızılötesi ışık yayan iki LED’e sahiptir. Nabız hızı için yalnızca kızılötesi ışık gereklidir. Hem kırmızı ışık hem de kızılötesi ışık, kandaki oksijen seviyelerini ölçmek için kullanılır.
Eğer elinizde bu modül yoksa, farklı modüller kullandığımız diğer nabız ölçüm yazılarımıza bakabilirsiniz:

Kalp kan pompaladığında, daha fazla kan olması sonucu oksijenli kanda bir artış olur. Kalp rahatladıkça oksijenli kan hacmi de azalır. Sonuçta cihaz, oksijenden zengin kanın artması ve azalması arasındaki süreyi bilerek nabız hızını hesaplar.
Oksijenli kan daha fazla kızılötesi ışığı emer ve daha fazla kırmızı ışık geçirirken, oksijensiz kan kırmızı ışığı emer ve daha fazla kızılötesi ışık geçirir. MAX30100’ün ana işlevi budur: her iki ışık kaynağı için de ışığı emme seviyelerini okur ve bunları I2C aracılığıyla okunabilen bir arabellekte saklar.
MAX30100 Modülü
Yaygın olarak bulunan iki adet MAX30100 devre kartı vardır. GY-MAX30100 modülünüz varsa:

Diğer modüllere kıyasla bu kart Arduino ile kullanıma hazırdır. Sadece bu kablolama kurulumunu takip edin:
GY-MAX30100 Modülü | Arduino UNO/Nano |
VIN | 5V |
GND | GND |
SCL | A5 |
SDA | A4 |
INT | D2 |
Sadece bu kablolama kurulumunu takip edin ve buradaki MAX30100 kütüphanesini kullanın. Kütüphanenin kullanımı oldukça kolaydır; örnek bir kod:
#include "MAX30100.h"
MAX30100* pulseOxymeter;
void setup() {
Wire.begin();
Serial.begin(115200);
Serial.println("Nabız oksimetre testi");
pulseOxymeter = new MAX30100();
pinMode(2, OUTPUT);
}
void loop() {
pulseoxymeter_t result = pulseOxymeter->update();
if( result.pulseDetected == true )
{
Serial.println("Nabiz");
Serial.print( "BPM: " );
Serial.print( result.heartBPM );
}
}
Burada kalp nabız hızı seri monitör aracılığıyla görüntülenir. Kan oksijen konsantrasyonunu eklemeniz gerekiyorsa, yalnızca şu satırı eklemeniz gerekir:
Serial.print( "SaO2: " );
Serial.print( result.SaO2 );
Serial.println( "%" );
Problemli MAX30100 Modülü
Eğer RCWL-0530’a sahipseniz:

Maalesef bu modülü kullanıyorsanız yapacak çok işiniz var. Bu ucuz modülün bazı ciddi tasarım sorunları mevcut. Eğer veri sayfasına bakarsanız böyle bir şemayı kullandığını göreceksiniz:

MAX30100 entegresi, VDD için 1.8V kullanır ve bu özel modül, bu voltajı elde etmek için iki regülatör kullanır. Bunda yanlış bir şey yok. Ancak yakından bakarsanız, SCL ve SDA pinleri 4.7k ohm dirençler aracılığıyla 1.8V’a çekilir! Bu, daha yüksek mantık seviyelerine sahip mikrodenetleyicilerle iyi çalışmayacağı anlamına gelir. Arduino, minimum 2 V’luk bir YÜKSEK voltajı algılayabilir!
Çözüm, dirençleri karttan çıkarmak (aşağıdaki resimde çevrelenmiştir) ve bunun yerine harici 4.7k ohm dirençler eklemektir.

Dirençleri çıkartılmış modülün görüntüsü:

Dirençleri çıkardıktan sonra, bu kablo şemasını kullanarak bu modülü Arduino UNO’ya bağlayabilirsiniz:

Burada SCL, SDA ve INT, 4.7k ohm’luk direnç aracılığıyla 3.3V’a çeker. Bu, Arduino UNO’nun MAX30100’ü aşırı beslemeden YÜKSEK mantık seviyesini tespit edebilmesini sağlar.
Örnek için bu kütüphaneyi kullandık. Kütüphane birkaç örnek sunar. En temel örnek hazır olarak kütüphane ile gelmektedir:
#include <Wire.h>
#include "MAX30100_PulseOximeter.h"
#define REPORTING_PERIOD_MS 1000
// PulseOximeter is the higher level interface to the sensor
// it offers:
// * beat detection reporting
// * heart rate calculation
// * SpO2 (oxidation level) calculation
PulseOximeter pox;
uint32_t tsLastReport = 0;
// Callback (registered below) fired when a pulse is detected
void onBeatDetected()
{
Serial.println("Beat!");
}
void setup()
{
Serial.begin(115200);
Serial.print("Initializing pulse oximeter..");
// Initialize the PulseOximeter instance
// Failures are generally due to an improper I2C wiring, missing power supply
// or wrong target chip
if (!pox.begin()) {
Serial.println("FAILED");
for(;;);
} else {
Serial.println("SUCCESS");
}
// The default current for the IR LED is 50mA and it could be changed
// by uncommenting the following line. Check MAX30100_Registers.h for all the
// available options.
// pox.setIRLedCurrent(MAX30100_LED_CURR_7_6MA);
// Register a callback for the beat detection
pox.setOnBeatDetectedCallback(onBeatDetected);
}
void loop()
{
// Make sure to call update as fast as possible
pox.update();
// Asynchronously dump heart rate and oxidation levels to the serial
// For both, a value of 0 means "invalid"
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();
}
}
Bağlantı şemasını takip edip bu kodu Arduino’nuza yüklediyseniz, kart üzerindeki kırmızı LED yanmalıdır ve bunu seri monitörde görmelisiniz:

Benzer bir çıktı alıyorsanız MAX30100’ün çalıştığı anlamına gelir. Tek yapmanız gereken, parmağınızı entegre’nin (LED’li olan) üstüne koymak ve nabız hızınız görüntülemektir
Eğer LED yanmıyorsa ve seri monitörde “FAILED” mesajını alıyorsanız, bu bir güç sorunu olabilir. Yukarıdaki kodun 58. satırına bakarsanız:
//pox.setIRLedCurrent(MAX30100_LED_CURR_7_6MA);
Bu, LED üzerindeki akımı ayarlar. Bu, başlangıçta, LED akımı varsayılan 50 mA olacak şekilde yorumlanmıştır. LED’den geçen akımı 7,6 mA’ya eşit yapmak için bunu yorumlayın. Bu güç sorununu çözecektir.
Bu arada, yukarıdaki setIRLedCurrent() işlevinde kullanabileceğiniz diğer olası değerler şunlardır:
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
Akım ne kadar yüksek olursa, LED’in o kadar parlak olduğunu ve cildinize o kadar derine ulaştığını unutmayın.
Sensör Güncelleme Hızı
Bu kod satırını çalıştırmaya gelince kullandığımız kitaplıktaki bu fonkyison ise şu işe yarar:
pox.update();
Bu satır sensör okumalarını günceller ve loop() içine yerleştirilir. Kitaplığın yazarı, bu işlevin çağrılması arasındaki sürenin 10 ms’den az olması gerektiğini vurgulamaktadır. Görünen o ki, MAX30100’ün örnekleme frekansını ayarlayabilirsiniz ancak kütüphanede bu frekans 100 Hz olarak ayarlanmıştır. Örnekleme frekansının düzenlenmesi, MAX30100’den gelen verileri işlemek için kullanılan filtrenin FIR katsayılarını gerektirir.
Kısacası, bu kodu kullanarak 10 ms’den fazla bir gecikme koyamaz veya bu süreyi loop() içinde yapamazsınız.
Bu nedenle yukarıdaki kod için şunu görüyoruz:
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();
}
normal delay() rutini yerine sensör değerlerini okurken. millis() işlevi arka planda çalışmaya devam eder ve kod yürütülmesini engellemez.
MAX30100 ile 16×2 LCD Kullanma
Zamanlama sorunları nedeniyle, şimdi MAX30100 ile diğer cihazları kullanırken bir sorun ortaya çıkıyor. pox.update()’nin 100 ms’den az olmamak üzere yürütüldüğünden emin olun.

Arduino Kodu
#include <Wire.h>
#include "MAX30100_PulseOximeter.h"
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);
#define REPORTING_PERIOD_MS 1000
PulseOximeter pox;
int LED = 13;
uint32_t tsLastReport = 0;
void onBeatDetected()
{
digitalWrite(LED, !digitalRead(LED));
}
void setup()
{
lcd.begin();
lcd.backlight();
lcd.setCursor(0, 0);
lcd.print("Hazirlaniyor...");
delay(1000);
lcd.setCursor(0, 1);
if (!pox.begin()) {
lcd.print("HATA");
while (1);
} else {
lcd.print("BASARİLİ");
}
pox.setIRLedCurrent(MAX30100_LED_CURR_7_6MA);
pox.setOnBeatDetectedCallback(onBeatDetected);
delay(1000);
}
void loop()
{
pox.update();
if (millis() - tsLastReport > REPORTING_PERIOD_MS) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Nabiz: ");
lcd.print(pox.getHeartRate());
lcd.print(" bpm");
lcd.setCursor(0, 1);
lcd.print("SpO2: ");
lcd.print(pox.getSpO2());
lcd.print("%");
tsLastReport = millis();
}
}
loop() içinde hiçbir delay() yoktur ve görüntü yalnızca her saniyede bir güncellenir, bu nedenle pox.update() mümkün olduğunca hızlı yürütülür.
Yorum yapma özelliği, forum tarafından gelen istek sebebiyle kapatılmıştır. Lütfen tartışmalar ve sorularınız için topluluk forumumuza katılın.