ماژول حسگر MAX30102 جهت اندازهگیری اکسیژن خون و ضربان قلب به کار میرود. این ماژول دارای یک ADC 18 بیتی بوده و از پروتکل I2C جهت انتقال دادهها استفاده مینماید.
حسگر MAX 30102
نحوه اندازه گیری اکسیژن خون
مقدار خون غنی شده با اکسیژن در زمانی که قلب، خون را به رگها پمپ میکند بیشتر و زمانی که قلب در حال استراحت است این مقدار کمتر میشود. با دانستن زمان بین این کم و زیاد شدن خون غنی از اکسیژن میتوان ضربان قلب را مشخص نمود.
در صورت تاباندن نور مادون قرمز بر روی خون غنی از اکسیژن، میزان زیادی از این نور جذب شده و در صورت تاباندن نور قرمز میزان زیادی از این نور از خون عبور میکند. خون با مقدار اکسیژن پایینتر نیز میزان نور قرمز بیشتری را جذب خود کرده و نور مادون قرمز را به میزان بیشتری از خود عبور میدهد.
ماژول MAX30102 دارای دو عدد LED با نور قرمز و مادون قرمز و همچنین یک سنسور برای اندازهگیری میزان نور برگشتی از خون میباشد. با تاباندن نور بر روی پوست و عبور آن از خون، مقدار مشخصی از آن توسط خون جذب شده و مقداری انعکاس پیدا میکند. این ماژول با اندازهگیری میزان برگشت هرکدام از این نورها میزان اکسیژن خون و ضربان قلب را محاسبه مینماید.
مشخصات فنی ماژول :
ولتاژ مورد نیاز : 3.3 تا 5 ولت
آمپر کاری : >5 mA
آمپر مورد نیاز برای LED ها : 0-50 mA
پروتکل ارتباطی : I2C
آدرس I2C : 0X57
دمای کاری : -40 تا 85 درجه سلسیوس
نحوه اتصال به برد :
همانطور که گفته شد پروتکل ارتباطی این ماژول I2C میباشد و برای متصل کردن این ماژول به کنترلر باید پایه های SDA و SCL موجود روی ماژول را به پایههای همنام بر روی کنترلر خود متصل نمایید. در جدول زیر نحوه اتصال این ماژول به چند برد پرکاربرد مشخص شده است.
Raspberry Pi [1] |
Lolin 32 [1] | NodeMCU [2] | Arduino UNO [3] | پایه روی ماژول MAX30102 |
GPIO2 |
GPIO5 |
روی تمام پایه های GPIO به صورت نرم افزاری قابل تعریف است |
A4 |
SDA |
GPIO3 |
GPIO4 |
روی تمام پایه های GPIO به صورت نرم افزاری قابل تعریف است |
A5 |
SCL |
5 V |
5 V |
3 V |
5 V |
VCC |
ground | GND | GND | GND |
GND |
در این مقاله از برد Wemos Lolin32 OLED استفاده میشود که در شکل زیر می توانید نحوه اتصال ماژول حسگر به این برد را مشاهده نمایید.
نصب کتابخانه مورد نیاز در Arduino
برای کار با این ماژول دو کتابخانه اصلی وجود دارد. یکی توسط Sparkfun [5] و دیگری توسط DFROBOT [6] توسعه داده شده است. ما در این مقاله به دلیل راحتتر بودن و دسترسی به دادههای خام در حسگر، از کتابخانه DFROBOT استفاده میکنیم.
جهت نصب این کتابخانه، ابتدا آن را از اینجا دانلود نمایید. سپس از منوی sketch ← include Library ← Add .ZIP Library فایل زیپ دانلود شده را انتخاب نمایید.
توابع استفاده شده در کتابخانه [7]
جهت کار با این ماژول میتوانید از توابع پیاده سازی شده در این کتابخانه استفاده نمایید. لیست توابع و پارامترها در زیر مشخص می باشد.
[toggle title=”لیست توابع و پارامترها” state=”close”]
/*/*
Macro definition options in sensor configuration
sampleAverage: SAMPLEAVG_1 SAMPLEAVG_2 SAMPLEAVG_4
SAMPLEAVG_8 SAMPLEAVG_16 SAMPLEAVG_32
ledMode: MODE_REDONLY MODE_RED_IR MODE_MULTILED
sampleRate: PULSEWIDTH_69 PULSEWIDTH_118 PULSEWIDTH_215 PULSEWIDTH_411
pulseWidth: SAMPLERATE_50 SAMPLERATE_100 SAMPLERATE_200 SAMPLERATE_400
SAMPLERATE_800 SAMPLERATE_1000 SAMPLERATE_1600 SAMPLERATE_3200
adcRange: ADCRANGE_2048 ADCRANGE_4096 ADCRANGE_8192 ADCRANGE_16384
*/
/*!
*@brief Use macro definition to configure sensor
*@param ledBrightness LED brightness, default value: 0x1F(6.4mA), Range: 0~255(0=Off, 255=50mA)
*@param sampleAverage Average multiple samples then draw once, reduce data throughput, default 4 samples average
*@param ledMode LED mode, default to use red light and IR at the same time
*@param sampleRate Sampling rate, default 400 samples every second
*@param pulseWidth Pulse width: the longer the pulse width, the wider the detection range. Default to be Max range
*@param adcRange ADC Measurement Range, default 4096 (nA),15.63(pA) per LSB
*/
void sensorConfiguration(uint8_t ledBrightness = 0x1F, uint8_t sampleAverage = SAMPLEAVG_4, \
uint8_t ledMode = MODE_MULTILED, uint8_t sampleRate = SAMPLERATE_400, \
uint8_t pulseWidth = PULSEWIDTH_411, uint8_t adcRange = ADCRANGE_4096);
/*!
*@brief get red value
*@return Red light reading
*/
uint32_t getRed(void);
/*!
*@brief Get IR value
*@return IR reading
*/
uint32_t getIR(void);
/*!
*@brief Calculate heart rate and SPO2
*@param *SPO2 [out]Calculated SPO2
*@param *SPO2Valid [out]If the calculated SPO2 is valid, the value is 1
*@param *heartRate [out]Calculated heart-rate
*@param *heartRateValid [out]If the calculated heart-rate is valid, the value is 1
*/
void heartrateAndOxygenSaturation(int32_t* SPO2,int8_t* SPO2Valid,int32_t* heartRate,int8_t* heartRateValid);
Macro definition options in sensor configuration
sampleAverage: SAMPLEAVG_1 SAMPLEAVG_2 SAMPLEAVG_4
SAMPLEAVG_8 SAMPLEAVG_16 SAMPLEAVG_32
ledMode: MODE_REDONLY MODE_RED_IR MODE_MULTILED
sampleRate: PULSEWIDTH_69 PULSEWIDTH_118 PULSEWIDTH_215 PULSEWIDTH_411
pulseWidth: SAMPLERATE_50 SAMPLERATE_100 SAMPLERATE_200 SAMPLERATE_400
SAMPLERATE_800 SAMPLERATE_1000 SAMPLERATE_1600 SAMPLERATE_3200
adcRange: ADCRANGE_2048 ADCRANGE_4096 ADCRANGE_8192 ADCRANGE_16384
*/
/*!
*@brief Use macro definition to configure sensor
*@param ledBrightness LED brightness, default value: 0x1F(6.4mA), Range: 0~255(0=Off, 255=50mA)
*@param sampleAverage Average multiple samples then draw once, reduce data throughput, default 4 samples average
*@param ledMode LED mode, default to use red light and IR at the same time
*@param sampleRate Sampling rate, default 400 samples every second
*@param pulseWidth Pulse width: the longer the pulse width, the wider the detection range. Default to be Max range
*@param adcRange ADC Measurement Range, default 4096 (nA),15.63(pA) per LSB
*/
void sensorConfiguration(uint8_t ledBrightness = 0x1F, uint8_t sampleAverage = SAMPLEAVG_4, \
uint8_t ledMode = MODE_MULTILED, uint8_t sampleRate = SAMPLERATE_400, \
uint8_t pulseWidth = PULSEWIDTH_411, uint8_t adcRange = ADCRANGE_4096);
/*!
*@brief get red value
*@return Red light reading
*/
uint32_t getRed(void);
/*!
*@brief Get IR value
*@return IR reading
*/
uint32_t getIR(void);
/*!
*@brief Calculate heart rate and SPO2
*@param *SPO2 [out]Calculated SPO2
*@param *SPO2Valid [out]If the calculated SPO2 is valid, the value is 1
*@param *heartRate [out]Calculated heart-rate
*@param *heartRateValid [out]If the calculated heart-rate is valid, the value is 1
*/
void heartrateAndOxygenSaturation(int32_t* SPO2,int8_t* SPO2Valid,int32_t* heartRate,int8_t* heartRateValid);
[/toggle]
تابع sensorConfiguration برای راهاندازی و تنظیمات اولیه ماژول استفاده میشود، تابع getRed(void) مقدار خوانده شده نور قرمز از LED و تابع getIR(void) مقدار خوانده شده نور مادون قرمز را بر میگرداند. با استفاده از تابع heartrateAndOxygenSaturation نیز میتوانید مقدار ضربان قلب (heartrate) و اکسیژن خون (Spo2) را در هر لحظه اندازهگیری نمایید.
اندازه گیری ضربان قلب و اکسیژن خون و نمایش آن بر روی OLED در برد Wemos Lolin32
با استفاده از کد زیر میتوانید ضربان قلب و اکسیژن خون را توسط ماژول MAX30102 اندازهگیری نموده و بر روی OLED نمایش دهید.
[toggle title=”کد اندازهگیری ضربان قلب و اکسیژن خون” state=”close”]
#include <Wire.h>
#include <DFRobot_MAX30102.h>
DFRobot_MAX30102 particleSensor;
const byte RATE_SIZE = 4; //Increase this for more averaging. 4 is good.
byte rates[RATE_SIZE]; //Array of heart rates
byte rateSpot = 0;
long lastBeat = 0; //Time at which the last beat occurred
float beatsPerMinute;
int beatAvg;
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
#define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); //Declaring the display name (display)
void setup() {
Wire.begin(5, 4);
display.begin(SSD1306_SWITCHCAPVCC, 0x3C, false, false); //Start the OLED display
display.display();
delay(3000);
// Initialize sensor
if (!particleSensor.begin()) //Use default I2C port, 400kHz speed
{
Serial.println(“MAX30105 was not found. Please check wiring/power. “);
while (1);
}
particleSensor.sensorConfiguration(/*ledBrightness=*/50, /*sampleAverage=*/SAMPLEAVG_4, \
/*ledMode=*/MODE_MULTILED, /*sampleRate=*/SAMPLERATE_100, \
/*pulseWidth=*/PULSEWIDTH_411, /*adcRange=*/ADCRANGE_16384);
}
int32_t SPO2; //SPO2
int8_t SPO2Valid; //Flag to display if SPO2 calculation is valid
int32_t heartRate; //Heart-rate
int8_t heartRateValid; //Flag to display if heart-rate calculation is valid
void loop() {
Serial.println(F(“Wait about four seconds”));
particleSensor.heartrateAndOxygenSaturation(/**SPO2=*/&SPO2, /**SPO2Valid=*/&SPO2Valid, /**heartRate=*/&heartRate, /**heartRateValid=*/&heartRateValid);
Serial.print(F(“heartRate=”));
Serial.print(heartRate, DEC);
Serial.print(F(“, heartRateValid=”));
Serial.print(heartRateValid, DEC);
Serial.print(F(“; SPO2=”));
Serial.print(SPO2, DEC);
Serial.print(F(“, SPO2Valid=”));
Serial.println(SPO2Valid, DEC);
display.clearDisplay(); //Clear the display
display.drawBitmap(0, 0, logo3_bmp, 32, 32, WHITE); //Draw the second picture (bigger heart)
display.setTextSize(1); //And still displays the average BPM
display.setTextColor(WHITE);
display.setCursor(50,0);
display.println(“BPM”);
display.setCursor(50,18);
display.println(heartRate);
display.setCursor(50,36);
display.println(“SPO2”);
display.setCursor(50,54);
display.println(SPO2);
display.display();
}
[/toggle]
منابع :
[1] “GPIO,” [Online]. Available: https://www.raspberrypi.org/documentation/usage/gpio/. [Accessed 14 04 2021].
[2] “ESP32 Built-in OLED Board (Wemos Lolin32): Pinout, Libraries and OLED Control,” [Online]. Available: https://randomnerdtutorials.com/esp32-built-in-oled-ssd1306/. [Accessed 14 04 2021].
[3] N. Sorokina, “I²C Module,” 30 08 2018. [Online]. Available: https://nodemcu.readthedocs.io/en/latest/modules/i2c/. [Accessed 14 04 2021].
[4] “Pinout-UNOrev3_latest,” [Online]. Available: https://content.arduino.cc/assets/Pinout-UNOrev3_latest.pdf. [Accessed 14 04 2021].
[5] SparkFun, “SparkFun_MAX3010x_Sensor_Library”.
[6] 2021. [Online]. Available: https://codeload.github.com/DFRobot/DFRobot_MAX30102/zip/master.
[7] “MAX30102 Pulse Oximeter & Heart Rate Sensor Arduino Wiki – DFRobot,” [Online]. Available: https://wiki.dfrobot.com/Heart_Rate_and_Oximeter_Sensor_SKU_SEN0344. [Accessed 14 04 2021].