{"id":4641,"date":"2025-12-24T09:08:16","date_gmt":"2025-12-24T17:08:16","guid":{"rendered":"https:\/\/www.donluc.com\/?p=4641"},"modified":"2025-12-24T09:08:16","modified_gmt":"2025-12-24T17:08:16","slug":"project-28-sensors-max30102-ppg-sensor-mk21","status":"publish","type":"post","link":"https:\/\/www.donluc.com\/?p=4641","title":{"rendered":"Project #28 \u2013 Sensors \u2013 MAX30102 PPG Sensor \u2013 Mk21"},"content":{"rendered":"<div style=\"width: 1200px;\" class=\"wp-video\"><video class=\"wp-video-shortcode\" id=\"video-4641-1\" width=\"1200\" height=\"675\" preload=\"metadata\" controls=\"controls\"><source type=\"video\/mp4\" src=\"https:\/\/www.donluc.com\/wp-content\/uploads\/2025\/12\/DL2512Mk03W.mp4?_=1\" \/><a href=\"https:\/\/www.donluc.com\/wp-content\/uploads\/2025\/12\/DL2512Mk03W.mp4\">https:\/\/www.donluc.com\/wp-content\/uploads\/2025\/12\/DL2512Mk03W.mp4<\/a><\/video><\/div>\n<p>&#8212;&#8212;<\/p>\n<p>#DonLucElectronics #DonLuc #MAX30102PPG  #FireBeetle2ESP32E #ESP32 #DFRobot #Display #IoT #Project #Fritzing #Programming #Electronics #Microcontrollers #Consultant<\/p>\n<p>&#8212;&#8212;<\/p>\n<p><a href=\"https:\/\/www.donluc.com\/wp-content\/uploads\/2025\/12\/DL2512Mk03a.jpg\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.donluc.com\/wp-content\/uploads\/2025\/12\/DL2512Mk03a.jpg\" alt=\"MAX30102 PPG Sensor \" width=\"720\" height=\"653\" class=\"alignnone size-full wp-image-4643\" srcset=\"https:\/\/www.donluc.com\/wp-content\/uploads\/2025\/12\/DL2512Mk03a.jpg 720w, https:\/\/www.donluc.com\/wp-content\/uploads\/2025\/12\/DL2512Mk03a-300x272.jpg 300w\" sizes=\"auto, (max-width: 720px) 100vw, 720px\" \/><\/a><\/p>\n<p>&#8212;&#8212;<\/p>\n<p><a href=\"https:\/\/www.donluc.com\/wp-content\/uploads\/2025\/12\/DL2512Mk03b.jpg\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.donluc.com\/wp-content\/uploads\/2025\/12\/DL2512Mk03b.jpg\" alt=\"MAX30102 PPG Sensor \" width=\"720\" height=\"480\" class=\"alignnone size-full wp-image-4644\" srcset=\"https:\/\/www.donluc.com\/wp-content\/uploads\/2025\/12\/DL2512Mk03b.jpg 720w, https:\/\/www.donluc.com\/wp-content\/uploads\/2025\/12\/DL2512Mk03b-300x200.jpg 300w\" sizes=\"auto, (max-width: 720px) 100vw, 720px\" \/><\/a><\/p>\n<p>&#8212;&#8212;<\/p>\n<p><a href=\"https:\/\/www.donluc.com\/wp-content\/uploads\/2025\/12\/DL2512Mk03c.jpg\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/www.donluc.com\/wp-content\/uploads\/2025\/12\/DL2512Mk03c.jpg\" alt=\"MAX30102 PPG Sensor \" width=\"720\" height=\"480\" class=\"alignnone size-full wp-image-4645\" srcset=\"https:\/\/www.donluc.com\/wp-content\/uploads\/2025\/12\/DL2512Mk03c.jpg 720w, https:\/\/www.donluc.com\/wp-content\/uploads\/2025\/12\/DL2512Mk03c-300x200.jpg 300w\" sizes=\"auto, (max-width: 720px) 100vw, 720px\" \/><\/a><\/p>\n<p>&#8212;&#8212;<\/p>\n<p><strong>Photoplethysmography<\/strong><\/p>\n<p>A PPG sensor is a non-invasive optical device that uses light (usually LEDs) and a photodetector to measure changes in blood volume in tissues, commonly used in wearables for monitoring heart rate, oxygen saturation (SpO2), and respiration by detecting fluctuations in light absorption or reflection as blood pumps through vessels. These sensors are cost-effective and popular in smartwatches and fitness trackers, working by shining light into the skin and analyzing how much light returns, which varies with each heartbeat. <\/p>\n<p><strong>Gravity: MAX30102 PPG Heart Rate and Oximeter Sensor<\/strong><\/p>\n<p>DFRobot Gravity: MAX30102 heart rate and blood oxygen sensor module integrates the Maxim MAX30102 chip and an MCU with heart rate and blood oxygen algorithm. The MAX30102 uses PPG to measure data, which will be converted into heart rate and oximetry values when processed by the MCU, then output through I2C or UART, making the sensor easy to use and greatly reducing resource occupation of the main controller. The pressure may change when the finger is directly pressed down the sensor, which will affect the data output. So please try to fix the sensor on your finger. Wear the sensor on your finger and there is no difference in the direction of wearing.<\/p>\n<p><strong>DL2512Mk03<\/strong><\/p>\n<p>1 x DFRobot FireBeetle 2 ESP32-E<br \/>\n1 x Fermion: 3.5\u201d 480&#215;320 TFT LCD Capacitive<br \/>\n1 x GDL Line 10 CM<br \/>\n1 x Gravity: IO Shield for FireBeetle 2<br \/>\n1 x Terminal Block Board for FireBeetle 2 ESP32-E IoT<br \/>\n1 x Gravity: MAX30102 PPG Heart Rate and Oximeter Sensor<br \/>\n1 x Lithium Ion Battery &#8211; 1000mAh<br \/>\n1 x USB 3.0 to Type-C Cable<\/p>\n<p><strong>DL2512Mk03p<\/strong><\/p>\n<p><strong>DL2512Mk03p.ino<\/strong><\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"arduino\" data-enlighter-title=\"\">\r\n\/****** Don Luc Electronics \u00a9 ******\r\nSoftware Version Information\r\nProject #28 \u2013 Sensors \u2013 MAX30102 PPG Sensor \u2013 Mk21\r\n28-21\r\nDL2512Mk03p.ino\r\nDL2512Mk03\r\n1 x DFRobot FireBeetle 2 ESP32-E\r\n1 x Fermion: 3.5\u201d 480x320 TFT LCD Capacitive\r\n1 x GDL Line 10 CM\r\n1 x Gravity: IO Shield for FireBeetle 2\r\n1 x Terminal Block Board for FireBeetle 2 ESP32-E IoT\r\n1 x Gravity: MAX30102 PPG Heart Rate and Oximeter Sensor\r\n1 x Lithium Ion Battery - 1000mAh\r\n1 x USB 3.0 to Type-C Cable\r\n*\/\r\n\r\n\/\/ Include the Library Code\r\n\/\/ EEPROM Library to Read and Write EEPROM\r\n\/\/ with Unique ID for Unit\r\n#include &quot;EEPROM.h&quot;\r\n\/\/ Arduino\r\n#include &quot;Arduino.h&quot;\r\n\/\/ DFRobot Display GDL API\r\n#include &lt;DFRobot_GDL.h&gt;\r\n\/\/ MAX30102 PPG Heart Rate and Oximeter\r\n#include &lt;DFRobot_BloodOxygen_S.h&gt;\r\n\r\n\/\/ Use I2C for communication, but use the \r\n\/\/serial port for communication if the \r\n\/\/line of codes were masked\r\n#define I2C_COMMUNICATION\r\n\/\/ Address\r\n#define I2C_ADDRESS    0x57\r\n\/\/ MAX30102 PPG Heart Rate and Oximeter\r\nDFRobot_BloodOxygen_S_I2C MAX30102(&amp;Wire ,I2C_ADDRESS);\r\nfloat fSPO2 = 0;\r\nfloat fHeartBeat = 0;\r\nfloat fTempB = 0;\r\n\r\n\/\/ Defined ESP32\r\n#define TFT_DC  D2\r\n#define TFT_CS  D6\r\n#define TFT_RST D3\r\n\r\n\/*dc=*\/ \/*cs=*\/ \/*rst=*\/\r\n\/\/ DFRobot Display 320x480\r\nDFRobot_ILI9488_320x480_HW_SPI screen(TFT_DC, TFT_CS, TFT_RST);\r\n\r\n\/\/ EEPROM Unique ID Information\r\n#define EEPROM_SIZE 64\r\nString uid = &quot;&quot;;\r\n\r\n\/\/ Software Version Information\r\nString sver = &quot;28-21&quot;;\r\n\r\nvoid loop() {\r\n  \r\n  \/\/ PPG\r\n  isPPG();\r\n\r\n  \/\/ isDisplayPPG\r\n  isDisplayPPG();\r\n\r\n  \/\/ Delay\r\n  delay( 1000 );\r\n  \r\n}\r\n<\/pre>\n<p><strong>getDisplay.ino<\/strong><\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"arduino\" data-enlighter-title=\"\">\r\n\/\/ DFRobot Display 320x480\r\n\/\/ DFRobot Display 320x480 - UID\r\nvoid isDisplayUID(){\r\n\r\n  \/\/ DFRobot Display 320x480\r\n  \/\/ Text Display\r\n  \/\/ Text Wrap\r\n  screen.setTextWrap(false);\r\n  \/\/ Rotation\r\n  screen.setRotation(3);\r\n  \/\/ Fill Screen =&gt; black\r\n  screen.fillScreen(0x0000);\r\n  \/\/ Text Color =&gt; white\r\n  screen.setTextColor(0xffff);\r\n  \/\/ Font =&gt; Free Sans Bold 12pt\r\n  screen.setFont(&amp;FreeSansBold12pt7b);\r\n  \/\/ TextSize =&gt; 1.5\r\n  screen.setTextSize(1.5);\r\n  \/\/ Don Luc Electronics\r\n  screen.setCursor(0, 30);\r\n  screen.println(&quot;Don Luc Electronics&quot;);\r\n  \/\/ SD\r\n  screen.setCursor(0, 60);\r\n  screen.println(&quot;PPG Sensor&quot;);\r\n  \/\/ Version\r\n  screen.setCursor(0, 90);\r\n  screen.println(&quot;Version&quot;);\r\n  screen.setCursor(0, 120);\r\n  screen.println( sver );\r\n  \/\/ EEPROM\r\n  screen.setCursor(0, 150);\r\n  screen.println(&quot;EEPROM&quot;);\r\n  screen.setCursor(0, 180);\r\n  screen.println( uid );\r\n\r\n}\r\n\/\/ isDisplayPPG\r\nvoid isDisplayPPG(){\r\n\r\n  \/\/ DFRobot Display 320x480\r\n  \/\/ Text Display\r\n  \/\/ Text Wrap\r\n  screen.setTextWrap(false);\r\n  \/\/ Rotation\r\n  screen.setRotation(3);\r\n  \/\/ Fill Screen =&gt; white\r\n  screen.fillScreen(0xffff);\r\n  \/\/ Text Color =&gt; blue\r\n  screen.setTextColor(0x001F);\r\n  \/\/ Font =&gt; Free Sans Bold 12pt\r\n  screen.setFont(&amp;FreeSansBold12pt7b);\r\n  \/\/ TextSize =&gt; 1.5\r\n  screen.setTextSize(1.5);\r\n  \/\/ Accelerometer\r\n  screen.setCursor(0, 30);\r\n  screen.println(&quot;PPG Sensor&quot;);\r\n  \/\/ SPO2\r\n  screen.setCursor(0, 60);\r\n  screen.println(&quot;SPO2: &quot;);\r\n  screen.setCursor(190, 60);\r\n  screen.println( fSPO2 );\r\n  screen.setCursor(260, 60);\r\n  screen.println(&quot; %&quot;);\r\n  \/\/ Heartbeat\r\n  screen.setCursor(0, 90);\r\n  screen.println(&quot;Heartbeat: &quot;);\r\n  screen.setCursor(190, 90);\r\n  screen.println( fHeartBeat );\r\n  screen.setCursor(260, 90);\r\n  screen.println(&quot; Times\/Min&quot;);\r\n  \/\/ Temperature Board\r\n  screen.setCursor(0, 120);\r\n  screen.println(&quot;Temp Board: &quot;);\r\n  screen.setCursor(190, 120);\r\n  screen.println( fTempB );\r\n  screen.setCursor(260, 120);\r\n  screen.println(&quot; C&quot;);\r\n\r\n}\r\n<\/pre>\n<p><strong>getEEPROM.ino<\/strong><\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"arduino\" data-enlighter-title=\"\">\r\n\/\/ EEPROM\r\n\/\/ isUID EEPROM Unique ID\r\nvoid isUID() {\r\n  \r\n  \/\/ Is Unit ID\r\n  uid = &quot;&quot;;\r\n  for (int x = 0; x &lt; 7; x++)\r\n  {\r\n    uid = uid + char(EEPROM.read(x));\r\n  }\r\n\r\n}\r\n<\/pre>\n<p><strong>getPPG.ino<\/strong><\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"arduino\" data-enlighter-title=\"\">\r\n\/\/ MAX30102 PPG Heart Rate and Oximeter\r\n\/\/ Setup PPG\r\nvoid iSetupPPG(){\r\n\r\n  \/\/ Setup PPG\r\n  while (false == MAX30102.begin())\r\n  {\r\n    \r\n    delay(1000);\r\n    \r\n  }\r\n\r\n  \/\/ Begin\r\n  MAX30102.sensorStartCollect();\r\n  \r\n}\r\n\/\/ is PPG\r\nvoid isPPG(){\r\n\r\n  \/\/ MAX30102 PPG Heart Rate and Oximeter\r\n  MAX30102.getHeartbeatSPO2();\r\n  \/\/ SPO2\r\n  fSPO2 = MAX30102._sHeartbeatSPO2.SPO2;\r\n  \/\/ Heartbeat\r\n  fHeartBeat = MAX30102._sHeartbeatSPO2.Heartbeat;\r\n  \/\/ Temperature Board\r\n  fTempB = MAX30102.getTemperature_C();\r\n  \r\n}\r\n<\/pre>\n<p><strong>setup.ino<\/strong><\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"arduino\" data-enlighter-title=\"\">\r\n\/\/ Setup\r\nvoid setup()\r\n{\r\n \r\n  \/\/ Delay\r\n  delay( 100 );\r\n\r\n  \/\/ EEPROM Size\r\n  EEPROM.begin(EEPROM_SIZE);\r\n\r\n  \/\/ EEPROM Unique ID\r\n  isUID();\r\n\r\n  \/\/ Delay\r\n  delay( 100 );\r\n\r\n  \/\/ Wire\r\n  Wire.begin();\r\n\r\n  \/\/ Delay\r\n  delay( 100 );\r\n\r\n  \/\/ Setup PPG\r\n  iSetupPPG();\r\n\r\n  \/\/ Delay\r\n  delay( 100 );\r\n  \r\n  \/\/ DFRobot Display 320x480\r\n  screen.begin();\r\n\r\n  \/\/ Delay\r\n  delay(100);\r\n\r\n  \/\/ DFRobot Display 320x480 - UID\r\n  \/\/ Don Luc Electronics\r\n  \/\/ Version\r\n  \/\/ EEPROM\r\n  isDisplayUID();\r\n\r\n  \/\/ Delay 5 Second\r\n  delay( 5000 );\r\n\r\n}\r\n<\/pre>\n<p>&#8212;&#8212;<\/p>\n<p><strong>People can contact us:<\/strong> https:\/\/www.donluc.com\/?page_id=1927<\/p>\n<p><strong>Consultant, R&#038;D, Electronics, IoT, Teacher and Instructor<\/strong><\/p>\n<ul>\n<li>Programming Language<\/li>\n<li>Single-Board Microcontrollers (PIC, Arduino, Raspberry Pi, Arm, Silicon Labs, Espressif, Etc&#8230;)<\/li>\n<li>IoT<\/li>\n<li>Wireless (Radio Frequency, Bluetooth, WiFi, Etc&#8230;)<\/li>\n<li>Robotics<\/li>\n<li>Automation<\/li>\n<li>Camera and Video Capture Receiver Stationary, Wheel\/Tank , Underwater and UAV Vehicle<\/li>\n<li>Unmanned Vehicles Terrestrial,  Marine and UAV<\/li>\n<li>Machine Learning<\/li>\n<li>Artificial Intelligence (AI)<\/li>\n<li>RTOS<\/li>\n<li>Sensors, eHealth Sensors, Biosensor, and Biometric<\/li>\n<li>Research &#038; Development (R &#038; D)<\/li>\n<li>Consulting<\/li>\n<\/ul>\n<p><strong>Follow Us<\/strong><\/p>\n<p><strong>Luc Paquin \u2013 Curriculum Vitae &#8211; 2024<\/strong><br \/>\nhttps:\/\/www.donluc.com\/luc\/<\/p>\n<p><strong>Web:<\/strong> https:\/\/www.donluc.com\/<br \/>\n<strong>Facebook:<\/strong> https:\/\/www.facebook.com\/neosteam.labs.9\/<br \/>\n<strong>YouTube:<\/strong> https:\/\/www.youtube.com\/@thesass2063<br \/>\n<strong>DFRobot:<\/strong> https:\/\/learn.dfrobot.com\/user-10186.html<br \/>\n<strong>Elecrow:<\/strong> https:\/\/www.elecrow.com\/share\/sharepj\/center\/no\/760816d385ebb1edc0732fd873bfbf13<br \/>\n<strong>TikTok:<\/strong> https:\/\/www.tiktok.com\/@luc.paquin8<br \/>\n<strong>Hackster:<\/strong> https:\/\/www.hackster.io\/luc-paquin<br \/>\n<strong>LinkedIn:<\/strong> https:\/\/www.linkedin.com\/in\/jlucpaquin\/<\/p>\n<p><strong>Don Luc<\/strong><\/p>\n","protected":false},"excerpt":{"rendered":"<p>&#8212;&#8212; #DonLucElectronics #DonLuc #MAX30102PPG #FireBeetle2ESP32E #ESP32 #DFRobot #Display #IoT #Project #Fritzing #Programming #Electronics #Microcontrollers #Consultant &#8212;&#8212; &#8212;&#8212; &#8212;&#8212; &#8212;&#8212; Photoplethysmography A PPG sensor is a non-invasive optical device that uses light (usually LEDs) and a photodetector to measure changes in blood volume in tissues, commonly used in wearables for monitoring heart rate, oxygen saturation (SpO2), &#8230; <a title=\"Project #28 \u2013 Sensors \u2013 MAX30102 PPG Sensor \u2013 Mk21\" class=\"read-more\" href=\"https:\/\/www.donluc.com\/?p=4641\" aria-label=\"Read more about Project #28 \u2013 Sensors \u2013 MAX30102 PPG Sensor \u2013 Mk21\">Read more<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[294,50,49,317,38,80,59,115,5,287,58,82,10],"tags":[6,92,102,4,320,87,19,83,85,407,24,9,84,27,248,33,34,108],"class_list":["post-4641","post","type-post","status-publish","format-standard","hentry","category-sensors","category-arduino","category-consultant","category-dfrobot","category-digitalelectronics","category-esp32","category-fritzing","category-e-mentor","category-microcontrollers","category-program","category-arduino-programming","category-program-esp32","category-projects","tag-arduino","tag-battery","tag-components","tag-consultant","tag-dfrobot","tag-display","tag-electronics","tag-esp32","tag-fritzing","tag-max30102-ppg-sensor","tag-microcontroller","tag-programming","tag-programming-esp32","tag-projects-2","tag-sensors","tag-technology","tag-video-blog","tag-vlog"],"_links":{"self":[{"href":"https:\/\/www.donluc.com\/index.php?rest_route=\/wp\/v2\/posts\/4641","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.donluc.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.donluc.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.donluc.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.donluc.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=4641"}],"version-history":[{"count":1,"href":"https:\/\/www.donluc.com\/index.php?rest_route=\/wp\/v2\/posts\/4641\/revisions"}],"predecessor-version":[{"id":4646,"href":"https:\/\/www.donluc.com\/index.php?rest_route=\/wp\/v2\/posts\/4641\/revisions\/4646"}],"wp:attachment":[{"href":"https:\/\/www.donluc.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=4641"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.donluc.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=4641"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.donluc.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=4641"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}