راه اندازی ماژول پالس اکسیمتر و ضربان قلب با آردوینو
در این مقاله با استفاده از ماژول پالس اکسیمتر و ضربان قلب MAX30102 و آردوینو، یک پروژه اندازه گیری ضربان قلب (BPM) و غلظت اکسیژن خون (SP02) را کار خواهیم کرد. پس اگر علاقمند به آشنایی با روش راه اندازی و کار این پروژه جذاب و کاربردی هستید تا انتهای این مقاله همراه ما باشید.
سنسور پالس اکسیمتر MAX30102:
MAX30102 یک ماژول بیوسنسور پالس اکسیمتری و مانیتور ضربان قلب یکپارچه براساس PPG(PhotoPlethysmoGraphy) است. این سنسور را می توان با هر میکروکنترلر مانند Arduino ، ESP8266 ، ESP32 STM32 یا Raspberry Pi Pico با استفاده از پروتکل ارتباطی I2C ادغام کرد. BPM مخفف «ضربان در دقیقه» است که معمولاً برای یک فرد معمولی از 65 تا 75 در هنگام استراحت متغیر است. ورزشکاران ممکن است نرخ BPM کمتر از این محدوده را داشته باشند. SpO2 نشان دهنده سطح اشباع اکسیژن است که برای یک فرد عادی بالای 95 درصد است.این دستگاه نه تنها ضربان قلب، بلکه می تواند غلظت اکسیژن خون را نیز اندازه گیری کند. این سنسوری است که توسط آنالوگ دیوایس طراحی شده است و در پیکربندی های مختلف توسط سازندگان مختلف وجود دارد.
از کاربردهای این سنسور میتوان به موارد ذیل اشاره کرد:
اندازهگیری اکسیژن خون (SpO2):
MAX30102 قادر به اندازهگیری اشباع اکسیژن خون با دقت بالا است. این ویژگی برای مراقبت از سلامتی و تشخیص مشکلات تنفسی مفید است.
اندازهگیری ضربان قلب:
این سنسور میتواند ضربان قلب را به طور دقیق و پیوسته اندازهگیری کند که کاربردهای متعددی مانند سنجش سلامت قلب و تناسب اندام دارد.
مصرف توان پایین و ابعاد کوچک:
MAX30102 مصرف توان بسیار پایین دارد که آن را برای استفاده در دستگاههای پوشیدنی و قابل حمل مناسب میکند.
همچنین در بستهبندیهای کوچک 5.6×2.8×1.2 میلیمتری ارائه میشود. در واقع این سنسور MAX30102 به دلیل قابلیتهای متنوع، کاربردهای گستردهای از جمله، تجهیزات پزشکی و پروژههای sIOT دارد.
وسایل مورد نیاز برای راه اندازی سنسور پالس اکسیمتر MAX30102:
اما بیایید نگاهی به طراحی ماژول سنسور پالس اکسی متر MAX30102 بیندازیم. اینجا بلوک دیاگرام این ماژول را میبینیم:
سنسور MAX30102 به طور کامل از طریق رجیسترهای نرم افزاری قابل تنظیم است و داده های خروجی دیجیتال را میتوان در یک FIFO با عمق 32 در داخل IC ذخیره کرد. FIFO به MAX30102 اجازه می دهد تا به یک میکروکنترلر یا پردازنده در یک گذرگاه مشترک متصل شود، جایی که داده ها به طور مداوم از رجیسترهای MAX30102 خوانده نمیشوند و دارای آدرس I2C ثابت 0xAE (برای عملیات نوشتن) و 0xAF (برای عملیات خواندن)است.
ساب سیستم SpO2 (اندازه گیری اشباع اکسیژن خون)
ساب سیستم SpO2 MAX30102 شامل حذف نور محیط یا کاهش نور محیطی (ALC) که یک تکنیک استفاده شده در انواع دستگاه های الکترونیکی مانند نمایشگرها، دوربین ها و سنسورها است تا اثرات نور محیطی ناخواسته را کاهش دهد. هدف اصلی ALC بهبود عملکرد و دقت این دستگاه ها با کاهش تداخل ناشی از نور محیطی است. ALC دارای یک مدار Track/Hold داخلی برای حذف نور محیط و افزایش محدوده دینامیکی موثر است.همچنین ALC می تواند تا 200µA جریان محیط را حذف کند.
ADC داخلی یک مبدل سیگما-دلتا با بیشنمونهبرداری مداوم با وضوح 18 بیت است. نرخ نمونه برداری ADC ؛ 10.24 مگاهرتز است. نرخ داده خروجی ADC را می توان از 50sps (نمونه در ثانیه) تا 3200sps برنامه ریزی کرد.
سنسور دما
MAX30102 دارای سنسور دمای روی تراشه برای کالیبره کردن وابستگی دمایی ساب سیستم SpO2 است. سنسور دما دارای وضوح ذاتی 0.0625 درجه سانتیگراد است. دادههای خروجی دستگاه نسبتاً به طول موج LED IR حساس نیستند، جایی که طول موج LED قرمز برای تفسیر صحیح دادهها حیاتی است. یک الگوریتم SpO2 که با سیگنال خروجی MAX30102 استفاده میشود، میتواند خطای SpO2 مرتبط با تغییرات دمای محیط را جبران کند.
درایور LED
MAX30102 درایورهای LED قرمز و IR را برای تعدیل پالس های LED برای اندازه گیری SpO2 و HR ادغام می کند. جریان LED را می توان از 0 تا 50 میلی آمپر با ولتاژ تغذیه مناسب برنامه ریزی کرد. عرض پالس LED را می توان از 69 میکرو ثانیه تا 411 میکرو ثانیه برنامه ریزی کرد تا به الگوریتم اجازه دهد تا دقت SpO2 و HR و مصرف انرژی را بر اساس موارد استفاده بهینه کند.
آی سی MAX30102 با یک منبع تغذیه 1.8 ولت کار می کند، اما برای LED های داخلی به یک منبع تغذیه 3.3 ولت جداگانه نیاز است. بنابراین ماژول دارای رگولاتورهای 3.3 ولت و 1.8 ولت است.
سنسور پالس اکسی متر MAX30102 چگونه کار می کند؟
MAX30102 با تابش هر دو نور به انگشت یا اساساً در هر جایی که پوست خیلی ضخیم نیست،( هر دو نور می توانند به راحتی به بافت نفوذ کنند) و با استفاده از ردیاب نوری، میزان نور منعکس شده را اندازه گیری می کند. این روش تشخیص پالس از طریق نور Photoplethysmogram نامیده می شود.
عملکرد MAX30102 را می توان به دو بخش تقسیم کرد: اندازه گیری ضربان قلب و پالس اکسیمتری (اندازه گیری سطح اکسیژن خون).
اندازه گیری ضربان قلب
هموگلوبین اکسیژن دار (HbO2) در خون شریانی دارای ویژگی جذب نور IR است. هر چه خون قرمزتر باشد (هموگلوبین بالاتر)، نور IR بیشتری جذب می شود.
همانطور که خون با هر ضربان قلب از طریق انگشت پمپ می شود، مقدار نور منعکس شده تغییر می کند و یک شکل موج متغیر در خروجی آشکارساز نور ایجاد می کند. همانطور که به تابش نور و خواندن ردیاب نوری ادامه می دهید، به سرعت شروع به خواندن نبض ضربان قلب (HR) می کنید.
پالس اکسیمتری
مبتنی بر میزان جذب نور قرمز و مادون قرمز بسته به میزان اکسیژن خون شما متفاوت باشد، است.
اجازه دهید حسگر پالس اکسیمتر MAX30102 را با آردوینو راه اندازی کنیم:
پین VIN و پین GND MAX30102 را به پایه 3.3 ولت و GND آردوینو وصل کنید. به طور مشابه، پایه SCL و SDA MAX30102 را به ترتیب به پایه A5 و A4 در آردوینو Uno وصل کنید. طبق نقشه عکس بالا اتصالات را انجام دهید.
اندازه گیری ضربان قلب، اکسیژن و دمای خون با MAX30102 و آردوینو
در قسمت کدنویسی این پروژه میتوانیم از کتابخانه MAX30102 Arduino برای اندازهگیری مقدار ضربان قلب بر حسب BPM، اکسیژن خون برحسب درصد و دما بر حسب درجه سانتیگراد استفاده کنیم. قبل از آن باید کتابخانه MAX30102 را نصب کنیم.
نصب کتابخانه آردوینو MAX30102
چندین کتابخانه برای سنسور MAX30102 برای اندازهگیری ضربان قلب، اکسیژن خون و دما وجود دارد. یکی از محبوبترین همه این کتابخانه ها، کتابخانه Sparkfun Electronics است.
برای نصب کتابخانه، MAX3010x را جستجو کنید. کتابخانه SparkFun MAX3010x Pulse and Proximity Sensor را پیدا کرده و بر روی install کلیک کنید.
اندازه گیری ضربان قلب (BPM) با MAX30102 و آردوینو
این کد یک سنسور MAX30102 را در آردوینو راه اندازی می کند تا ضربان قلب را بر حسب ضربان در دقیقه اندازه گیری کند، داده های خوانده شده را برای دقت میانگین می گیرد، و همراه با مقدار سنسور مادون قرمز به نمایشگر سریال ارسال می کند، که نشان می دهد آیا انگشت روی سنسور قرار گرفته است یا خیر.
#include <Wire.h>
#include "MAX30102.h"
#include "heartRate.h"// Create an instance of the MAX30102 class to interact with the sensor<br>MAX30102 particleSensor;// Define the size of the rates array for averaging BPM; can be adjusted for smoother results<br>
const byte RATE_SIZE = 4; // Increase this for more averaging. 4 is a good starting point.<br>
byte rates[RATE_SIZE]; // Array to store heart rate readings for averaging<br>
byte rateSpot = 0; // Index for inserting the next heart rate reading into the array<br>
long lastBeat = 0; // Timestamp of the last detected beat, used to calculate BPM<br> <br>
float beatsPerMinute; // Calculated heart rate in beats per minute<br>
int beatAvg; // Average heart rate after processing multiple readings<br> <br>
void setup() {
Serial.begin(115200); // Start serial communication at 115200 baud rate<br>
Serial.println("Initializing...");
// Attempt to initialize the MAX30105 sensor. Check for a successful connection and report.<br>
if (!particleSensor.begin(Wire, I2C_SPEED_FAST)) { // Start communication using fast I2C speed<br>
Serial.println("MAX30102 was not found. Please check wiring/power. ");
while (1); // Infinite loop to halt further execution if sensor is not found<br> }
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<br>
particleSensor.setPulseAmplitudeGreen(0); // Turn off the green LED as it's not used here<br>}
void loop() {
long irValue = particleSensor.getIR(); // Read the infrared value from the sensor
if (checkForBeat(irValue) == true) { // Check if a heart beat is detected<br>
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<br>
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<br>
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();
}
از منوی Tools، Arduino UNO Board و COM Port را انتخاب کنید. برای آپلود کد روی دکمه آپلود کلیک کنید. پس از بارگذاری کد، سنسور پالس اکسی متر MAX30102 آماده آزمایش است.
برای جریان خون ثابت و داده های قابل اعتماد، حسگر فشار را ثابت نگه دارید. اعمال فشار بهینه بر روی سنسور پالس – باید نه خیلی محکم باشد و نه خیلی سبک.
اندازه گیری اکسیژن خون (SpO2) با MAX30102 و آردوینو
این کد با استفاده از حسگر MAX30105 ضربان قلب و سطح اکسیژن را از انگشت می خواند، سپس این اطلاعات را به یک صفحه نمایش می فرستد. به صورت پویا بافر داده را بر اساس مدل آردوینو تنظیم می کند تا محدودیت های حافظه را در نظر بگیرد.
#include <Wire.h>
#include "MAX30102.h" // Include MAX30102 sensor library
#include "spo2_algorithm.h" // Include SpO2 calculation algorithm
MAX30102 particleSensor; // Create an instance of the MAX30102 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)<br>
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<br> <br>
// 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<br>
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<br>
irBuffer[i] = particleSensor.getIR(); // Store IR data<br>
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<br>
maxim_heart_rate_and_oxygen_saturation(irBuffer, bufferLength, redBuffer, &spo2, &validSPO2, &heartRate, &validHeartRate);
}
}
پس از آپلود کد، انگشت خود را روی سنسور پالس اکسی متر MAX30102 قرار دهید. مانیتور سریال میزان اکسیژن خون را به صورت درصد نمایش می دهد.
اندازه گیری دما با MAX30102 و آردوینو
کد زیر یک سنسور MAX30102 را برای اندازهگیری دما مقداردهی اولیه میکند، سپس به طور مداوم دما را بر حسب سلسیوس و فارنهایت بر روی نمایشگر سریال خوانده و نمایش میدهد.
#include <Wire.h>
#include "MAX30102.h" // Include library for MAX30102 sensor
MAX30102 particleSensor; // Create an instance of the MAX30102 class
void setup() {
Serial.begin(115200); // Start serial communication at 9600 baud rate
Serial.println("Initializing...");
// Check if MAX30105 sensor is properly connected
if (!particleSensor.begin(Wire, I2C_SPEED_FAST)) { // Initialize sensor with fast I2C speed
Serial.println("MAX30102 was not found. Please check wiring/power. ");
while (1); // Infinite loop if sensor is not found
}
particleSensor.setup(0); // Initialize sensor with LEDs turned off to prevent local heating
particleSensor.enableDIETEMPRDY(); // Enable temperature ready interrupt for reading temperature
}
void loop() {
float temperature = particleSensor.readTemperature(); // Read temperature in Celsius
Serial.print("temperatureC="); // Print temperature in Celsius
Serial.print(temperature, 4); // Print with 4 decimal places
float temperatureF = particleSensor.readTemperatureF(); // Convert temperature to Fahrenheit
Serial.print(" temperatureF="); // Print temperature in Fahrenheit
Serial.print(temperatureF, 4); // Print with 4 decimal places
Serial.println(); // New line for readability
}
پس از آپلود کد، انگشت خود را روی سنسور پالس اکسی متر MAX30102 قرار دهید. مانیتور سریال میزان اکسیژن خون را به صورت درصد نمایش می دهد.
پس از آپلود کد، مانیتور سریال را باز کنید. مانیتور سریال مقدار دما را در مقیاس سلسیوس و فارنهایت نشان می دهد.
شما میتوانید این ماژول را با آردوینو نانو هم راه اندازی کرده و یک نمایشگر oled نیز برای مشاهده داده های سنسور روی نمایشگر اضافه کنید.