อุปกรณ์ตรวจวัดชีพจรด้วยบอร์ด ESP32

  • ผู้เขียนบทความ : นายภูริณัฐ ก้อนทอง COE 033
  • คณะวิศวกรรมศาสตร์ สาขาวิศวกรรมคอมพิวเตอร์
  • วิชา : 04-513-201 การโปรแกรมคอมพิวเตอร์ขั้นสูงสุด 1/2566

1. ความเป็นมา

       การวัดชีพจร (Pulse) เป็นกระบวนการที่มีความสำคัญในการประเมินสภาพของระบบหัวใจและหลอดเลือดในร่างกายของมนุษย์ และมีบทบาทสำคัญในการรักษาและดูแลสุขภาพของบุคคล เราสามารถพิจารณาชีพจรว่าเป็นหัวใจของร่างกาย ดังนั้น การวัดชีพจรคือวิถีทางสำคัญในการตรวจสอบสุขภาพและเพิ่มโอกาสในการรักษาชีวิตของผู้ป่วยที่อาจจะอยู่ในสถานการณ์ฉุกเฉินหรือไม่ปกติทางการแพทย์ การวัดชีพจรสามารถใช้เพื่อวิเคราะห์สภาพที่ผิดปกติในระบบหัวใจ, การตรวจสอบอารมณ์, หรือการรีบกำลังแทนที่จะถึงเวลาที่แค่ไม่กี่นาทีเท่านั้น

2. วัตถุประสงค์

  • เพื่อสร้างความกระตือรือร้นในการดำรงชีวิตให้มีสุขภาพที่ดีและยั่งยืนในอนาคตโดยการรับรู้อัตราการเต้นของชีพจร
  • เพื่อต่อยอดในด้านกีฬาการแพทย์

3. ขอบเขต

  • ตัวแสดงผลลัพธ์แสดงบนจอ oled
  • งบประมาณถูก สามารถบำรุงรักษาได้ง่าย
  • แสดงแบบเรียลไทม์ แบบกราฟและค่า BPM

4. ประโยชน์ที่คาดว่าจะได้รับ

  • สามารถนำมาตรวจติดตามสุขภาพส่วนตัว
  • ESP32 ทำให้ง่ายในการตรวจสุขภาพที่สะดวกและสามารถทำได้ที่บ้านหรือในสถานที่ที่ต้องการ ช่วยในการรักษาสุขภาพและป้องกันโรค
  • ESP32 สามารถใช้เพื่อสนับสนุนงานวิจัยทางการแพทย์และการพัฒนาอุปกรณ์สุขภาพใหม่ ๆ ที่มีการตรวจวัดชีพจร

5. ความรู้ที่เกี่ยวข้อง

5.1การเขียนโปรแกรม ESP32: ความรู้ในการเขียนโปรแกรมสำหรับ ESP32 โดยใช้ Arduino IDE, PlatformIO,หรือ ESP-IDF (ESP32 IoT Development Framework) เพื่อควบคุมเซนเซอร์และอุปกรณ์ต่าง ๆ

5.2เซนเซอร์และอุปกรณ์อิเล็กทรอนิกส์: ความเข้าใจเกี่ยวกับการทำงานของเซนเซอร์และอุปกรณ์ที่ใช้ในการวัดข้อมูล เช่น ตัว Heartrate pulse sensor และ จอ oled

5.3ตัวโมดูลที่ใช้
5.3.1Heartrate pulse sensor
Heartrate pulse sensor หรือเซ็นเซอร์วัดอัตราการเต้นของหัวใจ เป็นโมดูลอิเล็กทรอนิกส์ที่ใช้วัดอัตราการเต้นของหัวใจ โดยอาศัยหลักการทางแสงอินฟราเรด (Infrared) โดยปล่อยแสงอินฟราเรดผ่านนิ้วมือ แล้วอีกฝั่งจะมีเซนเซอร์ตรวจจับแสงอินฟราเรด ซึ่งสามารถวัดความเข้มแสงที่ถูกดูดซับโดยนิ้วมือ มาแสดงเป็นอัตราการเต้นของหัวใจได้

การทำงานของตัวโมดูลจะแบ่งออกเป็น 2 ขั้นตอนหลักๆ ดังนี้

  1. ขั้นตอนการตรวจจับการเต้นของหัวใจ

ในขั้นตอนนี้ LED อินฟราเรดจะปล่อยแสงอินฟราเรดผ่านนิ้วมือไปยังเซนเซอร์ตรวจจับแสงอินฟราเรด หากมีเลือดไหลผ่านนิ้วมือ แสงอินฟราเรดจะถูกดูดซับโดยเลือด ทำให้ความเข้มแสงที่เซนเซอร์ตรวจจับแสงอินฟราเรดลดลง วงจรอิเล็กทรอนิกส์จะตรวจจับการเปลี่ยนแปลงของความเข้มแสงนี้ เพื่อหาตำแหน่งของการเต้นของหัวใจ

  1. ขั้นตอนการคำนวณอัตราการเต้นของหัวใจ

ในขั้นตอนนี้ วงจรอิเล็กทรอนิกส์จะคำนวณอัตราการเต้นของหัวใจจากตำแหน่งของการเต้นของหัวใจ โดยอาศัยหลักการที่ว่า อัตราการเต้นของหัวใจจะแปรผันตรงกับระยะเวลาที่แสงอินฟราเรดถูกดูดซับโดยเลือด

5.3.2Oled ssd1306
โมดูล OLED SSD1306 เป็นโมดูลจอแสดงผลแบบ OLED (Organic Light-Emitting Diode) ที่ได้รับความนิยมอย่างมากสำหรับการใช้งานในโครงการอิเล็กทรอนิกส์ต่างๆ ด้วยขนาดกะทัดรัด น้ำหนักเบา ใช้งานง่าย และราคาไม่แพง การเชื่อมต่อโมดูล SSD1306 กับอุปกรณ์อื่นๆ สามารถทำได้โดยเชื่อมต่อสายสัญญาณ 4 พินเข้ากับอุปกรณ์ต่างๆ เช่น ไมโครคอนโทรลเลอร์ หรือบอร์ดพัฒนาต่างๆ การใช้งานโมดูล SSD1306 สามารถทำได้โดยเขียนโปรแกรมควบคุมการทำงานของ IC ไดรเวอร์ SSD1306 ซึ่งโปรแกรมควบคุมสามารถเขียนได้โดยใช้ภาษาโปรแกรมต่างๆ เช่น C, C++, หรือ Python

สายเชื่อมต่อของโมดูล SSD1306 โดยทั่วไปจะมี 4 พิน ได้แก่

  • GND (Ground) ทำหน้าที่เป็นสายกราวด์
  • VCC (Supply Voltage) ทำหน้าที่เป็นสายจ่ายไฟ
  • SCL (Serial Clock) ทำหน้าที่เป็นสายนาฬิกา
  • SDA (Serial Data) ทำหน้าที่เป็นสายข้อมูล


5.4การเขียน code ให้อยู่ในรูปแบบ OOP และ ฟังชันก์การทำงานของ code ต่างๆ

5.4.1 บรรทัดแรกของโค้ดทำการนำเข้าโมดูลที่จำเป็นสำหรับการทำงานของ HeartRateMonitor class ได้แก่:

  • machine: โมดูลนี้ใช้สำหรับควบคุมฮาร์ดแวร์ของไมโครคอนโทรลเลอร์ เช่น GPIO, I2C, ADC ฯลฯ
  • ssd1306: โมดูลนี้ใช้สำหรับควบคุมจอแสดงผล OLED
  • time: โมดูลนี้ใช้สำหรับทำงานกับเวลา เช่น รอคอยเวลาที่กำหนด ฯลฯ
from machine import Pin, ADC, I2C
import ssd1306
import time

5.4.2ฟังก์ชัน init() จะถูกเรียกเมื่อมีการสร้าง instance ใหม่ของ HeartRateMonitor class ฟังก์ชั่นนี้จะทำการ:

  • สร้าง instance ของ I2C bus
  • สร้าง instance ของจอแสดงผล OLED
  • สร้าง instance ของ ADC pin สำหรับอ่านสัญญาณจาก pulse sensor
  • สร้าง instance ของ GPIO pin สำหรับควบคุม LED
  • สร้าง instance ของ GPIO pin สำหรับอ่านสถานะของปุ่ม
  • สร้างตัวแปรต่างๆ ที่จำเป็นสำหรับการทำงานของ class เช่น สัญญาณจาก pulse sensor, ช่วงบนและล่างของสัญญาณ, จำนวนครั้งที่สัญญาณเกินช่วงบน, สถานะของสัญญาณ, จำนวน sample ที่ใช้ในการคำนวณ rolling BPM, ค่า BPM sample, ดัชนีของ BPM sample ปัจจุบัน, rolling BPM, พิกัด x และ y สำหรับการแสดงผลบนจอแสดงผล OLED
class HeartRateMonitor:
    def __init__(self):
        # Initialize I2C
        self.i2c = I2C(scl=Pin(22), sda=Pin(21))
        
        # Initialize OLED display
        self.oled = ssd1306.SSD1306_I2C(128, 64, self.i2c)
        
        # Initialize other pins
        self.pulse_sensor_pin = ADC(Pin(36))
        self.led_pin = Pin(23, Pin.OUT)
        self.button_pin = Pin(32, Pin.IN, Pin.PULL_UP)
        
        # Initialize variables
        self.pulse_sensor_signal = 0
        self.upper_threshold = 360
        self.lower_threshold = 100
        self.cnt_hb = 0
        self.threshold_stat = True
        self.num_bpm_samples = 5
        self.bpm_values = [0] * self.num_bpm_samples
        self.bpm_index = 0
        self.rolling_bpm = 0
        self.x = 0
        self.y = 0
        self.last_x = 0
        self.last_y = 0
        self.get_bpm = True

5.5สุขภาพและการสำรวจร่างกาย: ความเข้าใจในปัจจัยทางการแพทย์ที่สามารถมีผลต่ออัตราการเต้นของหัวใจ เช่น อุปกรณ์แพทย์,ยา,โรคเรื้อรัง, หรือปัจจัยทางสุขภาพอื่น ๆ

  • ความรู้เกี่ยวกับหัวใจ
    • หัวใจเป็นอวัยวะสำคัญของระบบไหลเวียนโลหิต ทำหน้าที่สูบฉีดเลือดไปเลี้ยงส่วนต่าง ๆ ของร่างกาย
    • หัวใจประกอบด้วย 4 ห้อง ได้แก่ ห้องบนซ้าย (left atrium) ห้องบนขวา (right atrium) ห้องล่างซ้าย (left ventricle) และห้องล่างขวา (right ventricle)
    • หัวใจเต้นเป็นจังหวะโดยเกิดจากสัญญาณไฟฟ้าจากหัวใจเอง
  • ความรู้เกี่ยวกับการวัดชีพจร
    • การวัดชีพจรเป็นวิธีวัดอัตราการเต้นของหัวใจ
    • การวัดชีพจรสามารถทำได้หลายวิธี เช่น การวัดชีพจรที่ข้อมือ การวัดชีพจรที่คอ การวัดชีพจรที่ขมับ
    • อัตราการเต้นของหัวใจปกติของผู้ใหญ่อยู่ที่ประมาณ 60-100 ครั้งต่อนาที

6.ผลการดำเนินงาน

6.1หลักการทำงานของ Heartrate pulse sensor
หลักการทำงานของ heartrate pulse sensor ในแบบจำลองการวัดชีพจร ESP32 อาศัยหลักการวัดการเปลี่ยนแปลงของความเข้มของแสงที่สะท้อนกลับจากผิวหนังบริเวณข้อมือ เมื่อหัวใจเต้น เลือดจะไหลเวียนผ่านผิวหนังบริเวณข้อมือมากขึ้น ทำให้ความเข้มของแสงที่สะท้อนกลับจากผิวหนังเพิ่มขึ้นตามไปด้วย เซ็นเซอร์วัดชีพจรจะวัดการเปลี่ยนแปลงของความเข้มของแสงนี้และแปลงเป็นสัญญาณดิจิทัล

Code ฟังก์ชัน get_heart_rate ของตัว Heartrate pulse sensor

def get_heart_rate(self):
        current_millis_get_hb = time.ticks_ms()
        
        if current_millis_get_hb - self.previous_millis_get_hb >= self.interval_get_hb:
            self.previous_millis_get_hb = current_millis_get_hb
            self.pulse_sensor_signal = self.pulse_sensor_pin.read()
            
            if self.pulse_sensor_signal > 600:
                if self.get_bpm:
                    self.cnt_hb += 1
                    if self.cnt_hb == 1:
                        self.previous_millis_result_hb = current_millis_get_hb
                self.threshold_stat = False
                self.led_pin.value(1)
                
            if self.pulse_sensor_signal < 600:
                self.threshold_stat = True
                self.led_pin.value(0)
            
            if self.get_bpm and self.cnt_hb > 0:
                mapped_bpm = self.map_value(self.cnt_hb, self.lower_threshold, self.upper_threshold, 100, 120)
                self.bpm_values[self.bpm_index] = mapped_bpm
                self.bpm_index = (self.bpm_index + 1) % self.num_bpm_samples
                self.rolling_bpm = sum(self.bpm_values) // self.num_bpm_samples
            
            self.draw_graph()
            
        current_millis_result_hb = time.ticks_ms()
        
        if current_millis_result_hb - self.previous_millis_result_hb >= self.interval_result_hb:
            self.previous_millis_result_hb = current_millis_result_hb
            
            if self.get_bpm:
                if self.cnt_hb == 0:
                    self.clear_display_area(20, 48, 108, 18)
                    self.display_text(2, 20, 48, ": N/A BPM")
                else:
                    self.clear_display_area(20, 48, 108, 18)
                    self.display_bitmap(0, 47, heart_icon, 16, 16)
                    self.display_line(0, 43, 127, 43)
                    self.display_text(2, 20, 48, f": {self.rolling_bpm} BPM")
            
                self.cnt_hb = 0

6.2หลักการทำงานของตัวโมดูล Oled SSD1306


ตัวโมดูล OLED SSD1306 แบบวาดกราฟชีพจรจะทำงานโดยอาศัยหลักการพื้นฐานของการแสดงผล OLED นั่นคือ การใช้ไฟ LED ขนาดเล็กจำนวนมากเรียงกันเป็นพิกเซลเพื่อแสดงภาพ

ตัวโมดูล OLED SSD1306 มีพิกเซลทั้งหมด 128×64 พิกเซล โดยพิกเซลแต่ละพิกเซลจะมีค่าความสว่างเป็น 0 หรือ 1 ซึ่งจะแสดงเป็นสีดำหรือสีขาวตามลำดับ

ในการวาดกราฟชีพจร จะใช้หลักการดังนี้

  1. กำหนดค่าเริ่มต้นของกราฟ เช่น ตำแหน่งเริ่มต้นของกราฟ ทิศทางของกราฟ ระยะห่างระหว่างพิกเซล
  2. คำนวณค่าความสว่างของพิกเซลแต่ละพิกเซลตามค่าความเข้มของสัญญาณชีพจร
  3. เขียนค่าความสว่างของพิกเซลแต่ละพิกเซลลงบนตัวโมดูล OLED

ค่าความเข้มของสัญญาณชีพจรจะแปรผันตามอัตราการเต้นของหัวใจ โดยอัตราการเต้นของหัวใจที่สูงจะทำให้ค่าความเข้มของสัญญาณชีพจรสูงขึ้นไปด้วย

def draw_graph(self):
        if self.x > 127:
            self.clear_display_area(0, 0, 128, 42)
            self.x = 0
            self.last_x = 0
        
        y_signal = self.pulse_sensor_signal
        if y_signal > 850:
            y_signal = 850
        if y_signal < 350:
            y_signal = 350
        
        y_signal_map = self.map_value(y_signal, 350, 850, 0, 40)
        self.y = 40 - y_signal_map
        self.display_line(self.last_x, self.last_y, self.x, self.y)
        
        self.last_x = self.x
        self.last_y = self.y
        self.x += 1

    def clear_display_area(self, x, y, width, height):
        self.oled.fill_rect(x, y, width, height, 0)

    def display_bitmap(self, x, y, bitmap, width, height):
        self.oled.blit(bitmap, x, y, width, height)

    def display_line(self, x1, y1, x2, y2):
        self.oled.line(x1, y1, x2, y2, 1)

    def display_text(self, size, x, y, text):
        self.oled.text(text, x, y, 1, size)

    def map_value(self, x, in_min, in_max, out_min, out_max):
        return (x - in_min) * (out_max - out_min) // (in_max - in_min) + out_min

    def run(self):
        while True:
            self.get_heart_rate()

6.3ตารางการดำเนินงานการวัดชีพจร โดยใช้ปัจจัย อายุ (AGE)

7. สรุปผลและข้อเสนอแนะ

สรุปผล
ผลจากการปฎิบัติการทำงานของแบบจำลองวัดชีพจรทำงานได้อย่างมีประสิทธิภาพ ตามที่ทดลอง
1. เซนเซอร์สามารถรับค่าชีพจรได้
2. ตัวจอ oled แสดงค่าตาม code ที่เขียนได้
3. โมดูลสองตัวทำงานแบบสมบูรณ์แบบ
ข้อเสนอแนะ
1.การเพิ่มความสามารถ: ลองเพิ่มความสามารถเพิ่มเติมเช่นการบันทึกข้อมูล, การแจ้งเตือน, หรือการเชื่อมต่อกับแพลตฟอร์มอื่น ๆ
2.การปรับปรุงส่วนกราฟ: ปรับปรุงกราฟในการแสดงผลข้อมูลเพื่อทำให้เข้าใจได้ง่ายขึ้น
3.การทดสอบและปรับปรุง: ทดสอบโค้ดอย่างแต่ละส่วนและปรับปรุงเพื่อความเสถียรและประสิทธิภาพ

8.ข้อมูลอ้างอิง

[8.1] AsyncTCP. การใช้งาน Library และการ installation.
GitHub – me-no-dev/AsyncTCP: Async TCP Library for ESP32

[8.2] การวาง code และการปรับแต่ง code Arduino IDE + ESP32 + Pulse Sensor + OLED Display
Arduino IDE + ESP32 + Pulse Sensor + OLED Display + Web Server | Heart Rate Monitoring with ESP32 – YouTube

คลิปอธิบาย Youtube

You may also like...

ใส่ความเห็น

อีเมลของคุณจะไม่แสดงให้คนอื่นเห็น ช่องข้อมูลจำเป็นถูกทำเครื่องหมาย *