ویژگی های سنسور تشخیص ضربان قلب و اکسیژن خون MAX30102
این سنسور قابلیت انجام دو عمل تشخیص اکسیژن خون و ضربان قلب را دارد . ابتدا اشعه مادون قرمز ارسال میشود و با برخورد به انگشت دست بازتاب شده و سپس با اندازه گیری دامنه موج برگشتی میزان اکسیژن خون تعیین میگردد. ضربان قلب نیز با آنالیز زمانی امواج برگشتی تعیین می شود.
MAX30102 یک ماژول یکپارچه کنندهست که با آردینو و STM32 سازگاری دارد. این یکپارچه سازی توسط یک LED مادون قرمز، یک ردیاب فوتوالکتریک، یک دستگاه نوری و یک مدار الکترونیک با نویز کم، جهت کاهش تاثیر نور محیط انجام می شود.
همچنین داده های ضربان قلب و اکسیژن خون توسط ارتباط I2C به آردوینو یا سایر میکروکنترلر ها منتقل میشود.
دیتاشیت ماژول MAX30102 را می توانید از اینجا دانلود کنید.
معرفی پایه ها (Pinout) سنسور MAX30102
سنسور MAX30102 دارای 8 پایه است که از 4 پایه آن استفاده می شود. کاربرد این 4 پایه به شرح زیر است:
- VCC: تغذیه ماژول – 3 تا 5 ولت
- GND: زمین
- SCL: کلاک باس I2C
- SDA: متصل به دیتا باس I2C
پین اوت (Pinout) این ماژول را می توانید در تصویر زیر مشاهده کنید.
لوازمی که به آن احتیاج دارید
قطعاات مورد نیاز
نرم افزارهای مورد نیاز
راه اندازی ماژول MAX30102 با آردوینو
گام اول: سیم بندی
مطابق مدار زیر، سنسور را به آردوینو وصل کنید.
نکته
برای اتصال ماژول به سیم های رابط میتوانید از برد بورد و پین هدر ها کمک بگیرید و یا میتوانید پین هدر مربوطه را با لحیمکاری به ماژول متصل کنید.
گام دوم: نصب کتابخانه
به Library manager رفته و با جستجوی کلمه MAX30 ،کتابخانه ی SparkFun MAX3010x را نصب کنید.
اگر از ماژول MAX30100 استفاده میکنید، این کتابخانه را دانلود کنید.
گام سوم: کد تشخیص ضربان قلب
کد زیر را روی برد آردوینو آپلود کنید. این کد ضربان قلب شما را به صورت نمودار در پنجره ی سریال نمایش می دهد.
/*
MAX30102- Heart Rate Pulse Detection-Module
Home<iframe class="wp-embedded-content" sandbox="allow-scripts" security="restricted" style="position: absolute; clip: rect(1px, 1px, 1px, 1px);" title="“Home” — Electropeak" src="https://electropeak.com/learn/embed/#?secret=TxwP1tJuq2" data-secret="TxwP1tJuq2" width="600" height="338" frameborder="0" marginwidth="0" marginheight="0" scrolling="no"></iframe>
Based on Arduino Library Example
*/
#include <Wire.h>
#include "MAX30105.h"
MAX30105 particleSensor;
void setup()
{
Serial.begin(115200);
Serial.println("Initializing...");
// Initialize sensor
if (!particleSensor.begin(Wire, I2C_SPEED_STANDARD)) //Use default I2C port, 400kHz speed
{
Serial.println("MAX30105 was not found. Please check wiring/power. ");
while (1);
}
Serial.println("connected");
//Setup to sense a nice looking saw tooth on the plotter
byte ledBrightness = 0x1F; //Options: 0=Off to 255=50mA
byte sampleAverage = 8; //Options: 1, 2, 4, 8, 16, 32
byte ledMode = 3; //Options: 1 = Red only, 2 = Red + IR, 3 = Red + IR + Green
int sampleRate = 100; //Options: 50, 100, 200, 400, 800, 1000, 1600, 3200
int pulseWidth = 411; //Options: 69, 118, 215, 411
int adcRange = 4096; //Options: 2048, 4096, 8192, 16384
particleSensor.setup(ledBrightness, sampleAverage, ledMode, sampleRate, pulseWidth, adcRange); //Configure sensor with these settings
//Arduino plotter auto-scales annoyingly. To get around this, pre-populate
//the plotter with 500 of an average reading from the sensor
//Take an average of IR readings at power up
const byte avgAmount = 64;
long baseValue = 0;
for (byte x = 0 ; x < avgAmount ; x++)
{
baseValue += particleSensor.getIR(); //Read the IR value
}
baseValue /= avgAmount;
//Pre-populate the plotter so that the Y scale is close to IR values
for (int x = 0 ; x < 500 ; x++)
Serial.println(baseValue);
}
void loop()
{
Serial.println(particleSensor.getIR()); //Send raw data to plotter
}
در قسمت اول برنامه بایستی کتابخانه های مرتبط با ماژول به برنامه اضافه شود. در ادامه و در حلقه setup نرخ انتقال داده 115200 در نظر گرفته میشود. بایستی دقت کنید که این عدد را در Serial plotter نیز همین عدد تنظیم کنید. سپس در ادامه برنامه، نصب و راهاندازی ماژول MAX30102 انجام میشود. در ضمن نمونه برداری با فرکانس 400 کیلوهرتز انجام میشود.
در آخر نیز اطلاعات به دست آمده در خروجی Serial plotter به شکل زیر ظاهر میشود.
همانطور که در تصویر مشخص است، ضربان به شکل نوسانی تغیر میکند.
گام چهارم: کد تشخیص اکسیژن خون
کد زیر را روی برد آردوینو آپلود کنید. این کد اکسیژن خون شما را در پنجره سریال نمایش می دهد.
/*
MAX30102- Blood Oxyge -Module
Home<iframe class="wp-embedded-content" sandbox="allow-scripts" security="restricted" style="position: absolute; clip: rect(1px, 1px, 1px, 1px);" title="“Home” — Electropeak" src="https://electropeak.com/learn/embed/#?secret=TxwP1tJuq2" data-secret="TxwP1tJuq2" width="600" height="338" frameborder="0" marginwidth="0" marginheight="0" scrolling="no"></iframe>
Based on Arduino Library Example
*/
#include <Wire.h>
#include "MAX30105.h"
#include "spo2_algorithm.h"
MAX30105 particleSensor;
#define MAX_BRIGHTNESS 255
#if defined(__AVR_ATmega328P__) || defined(__AVR_ATmega168__)
//Arduino Uno doesn't have enough SRAM to store 100 samples of IR led data and red led data in 32-bit format
//To solve this problem, 16-bit MSB of the sampled data will be truncated. Samples become 16-bit data.
uint16_t irBuffer[100]; //infrared LED sensor data
uint16_t redBuffer[100]; //red LED sensor data
#else
uint32_t irBuffer[100]; //infrared LED sensor data
uint32_t redBuffer[100]; //red LED sensor data
#endif
int32_t bufferLength; //data length
int32_t spo2; //SPO2 value
int8_t validSPO2; //indicator to show if the SPO2 calculation is valid
int32_t heartRate; //heart rate value
int8_t validHeartRate; //indicator to show if the heart rate calculation is valid
byte pulseLED = 11; //Must be on PWM pin
byte readLED = 13; //Blinks with each data read
void setup()
{
Serial.begin(115200); // initialize serial communication at 115200 bits per second:
pinMode(pulseLED, OUTPUT);
pinMode(readLED, OUTPUT);
// Initialize sensor
if (!particleSensor.begin(Wire, I2C_SPEED_FAST)) //Use default I2C port, 400kHz speed
{
Serial.println(F("MAX30105 was not found. Please check wiring/power."));
while (1);
}
Serial.println(F("Attach sensor to finger with rubber band. Press any key to start conversion"));
while (Serial.available() == 0) ; //wait until user presses a key
Serial.read();
byte ledBrightness = 60; //Options: 0=Off to 255=50mA
byte sampleAverage = 4; //Options: 1, 2, 4, 8, 16, 32
byte ledMode = 2; //Options: 1 = Red only, 2 = Red + IR, 3 = Red + IR + Green
byte sampleRate = 100; //Options: 50, 100, 200, 400, 800, 1000, 1600, 3200
int pulseWidth = 411; //Options: 69, 118, 215, 411
int adcRange = 4096; //Options: 2048, 4096, 8192, 16384
particleSensor.setup(ledBrightness, sampleAverage, ledMode, sampleRate, pulseWidth, adcRange); //Configure sensor with these settings
}
void loop()
{
bufferLength = 100; //buffer length of 100 stores 4 seconds of samples running at 25sps
//read the first 100 samples, and determine the signal range
for (byte i = 0 ; i < bufferLength ; i++)
{
while (particleSensor.available() == false) //do we have new data?
particleSensor.check(); //Check the sensor for new data
redBuffer[i] = particleSensor.getRed();
irBuffer[i] = particleSensor.getIR();
particleSensor.nextSample(); //We're finished with this sample so 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 after first 100 samples (first 4 seconds of samples)
maxim_heart_rate_and_oxygen_saturation(irBuffer, bufferLength, redBuffer, &spo2, &validSPO2, &heartRate, &validHeartRate);
//Continuously taking samples from MAX30102. Heart rate and SpO2 are calculated every 1 second
while (1)
{
//dumping the first 25 sets of samples in the memory and shift the last 75 sets of samples to the top
for (byte i = 25; i < 100; i++)
{
redBuffer[i - 25] = redBuffer[i];
irBuffer[i - 25] = irBuffer[i];
}
//take 25 sets of samples before calculating the heart rate.
for (byte i = 75; i < 100; i++)
{
while (particleSensor.available() == false) //do we have new data?
particleSensor.check(); //Check the sensor for new data
digitalWrite(readLED, !digitalRead(readLED)); //Blink onboard LED with every data read
redBuffer[i] = particleSensor.getRed();
irBuffer[i] = particleSensor.getIR();
particleSensor.nextSample(); //We're finished with this sample so move to next sample
//send samples and calculation result to terminal program through UART
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);
}
//After gathering 25 new samples recalculate HR and SP02
maxim_heart_rate_and_oxygen_saturation(irBuffer, bufferLength, redBuffer, &spo2, &validSPO2, &heartRate, &validHeartRate);
}
}
در برنامه فوق، اضافه کردن کتابخانه و همچنین تنظیم سرعت و نرخ انتقال داده ها انجام می شود. بایستی دقت شود که محاسبه اکسیژن خون بعد از فشردن دکمه ای دلخواه، آغاز میشود.
در آخر نیز اطلاعات به دست آمده در خروجی Serial Monitor به شکل زیر ظاهر میشود. مشاهده میشود که اکسیژن خون 96 اندازه گیری شده است.
Comments (31)
سلام
اگر بخواهیم به اردوینو uno دو ماژول که هر دو با پروتکل i2c کار می کنند(مثلا همین max30102و max30205) متصل کنیم، با توجه به این که فقط دو پایه برای اتصال i2c رو برد اردوینو داریم، چگونه باید اتصالات سخت افزاری را انجام دهیم و در نوشتن برنامه(در حالی که میخوایم از کتابخونه های موجود برای این ماژول ها مثل همین کتابخونه ای که در این اموزش استفاده شده،استفاده کنیم) باید چه نکاتی را اعمال کنیم؟
سلام.
اگر دو یا چند ماژولی که میخواید به بورد آردوینو متصل کنید، آدرسهای i2c متفاوت داشته باشند، میتونید مستقیما همشون رو به همون پایههای i2c آردوینو متصل کنید و مشکلی نخواهد بود. در صورتی که ماژولها دارای آدرس i2c یکسان باشند دیگه امکان اینکه مستقیم به آردوینو متصل بشن وجود نداره. برای اتصال ماژولهایی که آدرس i2c یکسان دارند میتونید از بردهای توسعه i2c استفاده کنید. برای مثال ماژول توسعه i2c هشت کاناله TCA9548A که میتونید تو این لینک مشاهده کنید: “https://thecaferobot.com/store/tca9548a-1-to-8-i2c-8-way-multi-channel-expansion-board” با این ماژول میتونید تا 8 ماژول که آدرسهای یکسان دارند رو به آردوینو متصل کنید.
سلام.جناب درباره راه اندازی این دو سنسوری که شما فرمودین اگر سوالی داشته باشم میتونم با شما تماس برقرار کنم بپرسم؟
سلام.
بله، در خدمتتون هستم. میتونید سوالی داشتید چه از طریق کامنت و یا از طریق تلگرام بخش فنی که شمارهش در صفحه اصلی سایت هست، بپرسید.
سلام با اتمگا۸ هم میشه راه اندازی کرد؟
سلام.
بله مشکلی نداره. میتونید از انواع میکروکنترلرهای مختلف برای راه اندازی این سنسور استفاده کنید.
میشه لطفا برای نحوه بستن مدارش و کدش با avr راهنمایی کنید؟
با سلام
شما می توانید هر نوع میکروکنترلری که میخواهید را به لیست آردوینو خود اضافه کنید و با توجه به تنظیم پایه های مورد نظر از آن استفاده کنید
سلام خسته نباشید من دنبال یک ماژولی هستم که تعداد ضربان قلب رو تو یک زمان خواص بشماره و بعد به صورت عدد خروجی بده ایا با این سنسور می شه این کار رو کرد و اگه نمی شه سنسوری رو می شناسین که این کار رو انجام بده؟؟؟؟ ممنون
سلام. ممنون.
بله این سنسور این کار رو انجام میده، اما کدی که در این آموزش نوشته شده بیشتر برای محاسبه ی اکسیژن خون هست. شما همچنین میتونید از آموزشهای زیر و ماژول هایی که در اون استفاده شده، کمک بگیرید.
https://thecaferobot.com/learn/interfacing-heart-rate-sensor-module-with-arduino/
https://thecaferobot.com/learn/interfacing-heart-rate-pulse-sensor-module-with-arduino/
https://thecaferobot.com/learn/interfacing-ky-039-finger-heartbeat-measuring-sensor-module-with-arduino/
سلام خیلی ممنون از توضیحاتتون.
من دقیقا همین کار را انجام میدهم اما هیچ خروجی به من نمایش نمیدهد و هیچ چراغی برای ماژول روشن نمی شود.
اما از طرفی در i2c scanner در آدرس 0x57 یک ارتباط i2c پیدا میکنه.
امکانش هست بفرمایید من باید چی کار کنم؟!
سلام
یعنی شما موقعی که Serial Monitor را باز میکنید هیچی بهتون نمایش نمیده؟ اگر اینطور هست، میتونه به خاطر درست تنظیم نشدن baudrate توی Serial Monitor باشه. baudrate رو باید روی 115200 تنظیم کنید.
سلام وقت بخیر
ممنون بابت آموزش عالی تون
برای من هم همین مشکل وجود داره. ماژول روشن نمیشه و در پلاتر اردینو چیزی نشون نمیده. , و فقط پیغام زیر رو نشون میده.
“MAX30105 was not found. Please check wiring/power. ”
baud rate ها هم یکسان هست.
سلام، وقت شما هم بخیر
اگر ماژول روشن نمیشه و اون خطارو دریافت میکنید، مشکل یا از اتصالاتتون هست و یا اینکه خود ماژول خرابه. برای اطمینان اتصالاتتون رو (مخصوصا پایههای SDA و SCL) دوباره چک کنید.
همچنین میتونید از برنامه i2c_scanner استفاده کنید و ببینید آیا آدرسی برگشت داده میشه و یا خیر. اگر آدرسی برگشت داده نشد به احتمال بالا ایراد از خود ماژول هست. برنامه i2c_scanner رو میتونید از قسمت File -> Examples -> Wire -> i2c_scanner پیدا کنید.
سلام آیا میشه دمای بدن رو هم با این سنسور اندازه گیری کرد ؟؟.
اگر میشه لطف میکنید قطعه کدش رو قرار بدید
ممنونم
سلام.
نه این سنسور فقط میتونه میزان اکسیژن خون رو اندازه بگیره. برای اندازهگیری میزان دمای بدن لازمه که از یک سنسور دما دیگه مانند انواع سنسورهای دمای SHT، DHT و … استفاده کنید.
سلام وقت بخیر
آیا دقت این ماژول نسبت به ماژول max30100 بیشتره؟
من max30100 رو راه اندازی کردم اما اصلا دقت مناسبی نداره و درصد خطای بالایی داره
شما اطلاعی دارین که در پالس اکسیمترهای تجاری که دقت مناسبی هم دارن از چه ماژولی استفاده میشه؟؟
سلام.
به شخصه در این مورد تستی انجام ندادهایم اما به طور کلی ماژول max30102 نسبت به max30100 دارای برتری هم از نظر دقت و هم از نظر حافظه است. برای اطلاعات بیشتر میتونید این لینک رو مطالعه کنید:
https://www.teachmemicro.com/max30102-an-improved-heart-rate-sensor-for-arduino
ممنونم
البته طبق لینکی که فرستادین تغییر اصلی مربوط به مقاومت pull up هستش که ما به صورت دستی در max30100 اتصالش رو انجام میدیم و اینجا دیگه نیازی به اون قطع اتصال مقاومت ها نیست.
سلام وقتتون بخیر ، این ماژول رو میخوام با stm32 در محیط آردوینو راه بندازم ولی متاسفانه این خط ارور میده ، ارورش هم اون کلمه i2c هست اگر ممکنه راهنمایی کنید…
if (!particleSensor.begin(Wire, I2C_SPEED_FAST))
سلام.
این کد برای برد آردوینو نوشته و نمیتونید از اون به طور مستقیم برای پروگرم کردن STM32 استفاده کنید.
سلام وقتتون بخیر
میخواستم بدون بجای استفاده از برد اردینو انو میشه از برد اردینو نانو استفاده کرد؟
واینکه ایا کد هارو باید تغییر داد یا نه فرقی نمیکنه؟
ممنون
سلام.
وقت شما هم بخیر
بله شما میتونید جای Arduino Uno از Arduino Nano استفاده کنید و نیازی هم به تغییر دادن جایی در کد هم ندارید.
سلام وقت همگی بخیر من بخام روی نمایشگر oled نوارقلب رو به صورت گرافیکی نشون بدم از چه کدی استفاده کنم؟
با سلام
نمایش نوار قلب 2 حالت دارد یک در حد یک عکس ساده میخواهید داشته باشید که یک عکس bmp درست میکنید و آن را نمایش می دهید
یا میخواهید به صورت لحظه ای و واقعی نمایش بدهید. در این صورت به صورت لحظه ای دیتا را از سنسور یا هر دستگاهی که دارید میخوانید و این دیتا را به صورت پیکلسی نمایش میدهید سپس این نقاط پیکسلی را به صورت عرضی حرکت بدهید.
سلام وقتتون بخیر. این سنسور رو نمیشه با nodemsu esp8266 راه اندازی کرد؟اگر میشه میشه توضیح بدید چون من این سنسور رو که به برد وصل میکنم روشن نمیشه اصلا ممنون میشم راهنمایی کنید
با سلام
امکان راه اندازی برای این ماژول با ESP8266 وجود دارد. به احتمال زیاد شما سیم کشی را اشتباه کرده اید. پایه های I2C برای میکرو ESP8266 بر روی D1 , D2 می باشد.
پس از اتصال از طریق برنامه I2C Scanner بررسی کنید که ارتباط شما با ماژول درست می باشد و ID ماژول را دریافت میکنید یا خیر پس از آن کد مروبطه را آپلود کنید.
سلام
دقت ماژول چقدر هست ؟
با سلام
باتوجه به داده های داخل اینترنت:
A study conducted by IJEECS suggests that the accuracy rate of the MAX30102 measurement is 97.11% and 98.84%, for heart rate and oxygen saturation (SpO2), respectively. Bland Altman was used to appraising and visualizing the agreement between the two measurement devices.
سلام من میتونم با esp32 هم با این سنسور کار کنم؟؟؟؟
با سلام
بله
فقط پایه های مربوط به I2C را به درستی وصل بکنید.