ECG Module

这个库是 Module13.2 ECG 的驱动程序,模块通过 UART 进行通信。

支持以下产品:

Module13.2 ECG

UiFlow2 应用示例:

心率检测显示

在 UiFlow2 上打开 cores3_ecg_module_base_example.m5f2 项目。

本示例程序用于实时读取心率并显示心电波形。测量过程中,设备将连续绘制 ECG(心电图)波形,并在信号稳定后自动计算并显示心率数据。

心电电极连接:请按照以下方法正确连接心电电极:

  • 右上(RA):右上导联线放在胸骨右缘,锁骨中线第2肋间靠近右肩的位置。

  • 左上(LA):左上导联线位于胸骨左缘,锁骨中线第2肋间靠近左肩的位置。

  • 左下(LL):左下导联线放在左侧下腹部,髂嵴(hip bone)上方,或腹部左下侧。

测量注意事项:为了获得稳定、准确的心电信号,请遵循以下注意事项:

  • 身体放松: 避免肌肉紧张,以减少干扰信号。

  • 静止不动: 测量过程中尽量避免移动,以获得稳定的心电信号。

UiFlow2 代码块:

cores3_ecg_module_base_example.png

示例输出:

None

MicroPython 应用示例:

心率检测显示

本示例程序用于实时读取心率并显示心电波形。测量过程中,设备将连续绘制 ECG(心电图)波形,并在信号稳定后自动计算并显示心率数据。

心电电极连接:请按照以下方法正确连接心电电极:

  • 右上(RA):右上导联线放在胸骨右缘,锁骨中线第2肋间靠近右肩的位置。

  • 左上(LA):左上导联线位于胸骨左缘,锁骨中线第2肋间靠近左肩的位置。

  • 左下(LL):左下导联线放在左侧下腹部,髂嵴(hip bone)上方,或腹部左下侧。

测量注意事项:为了获得稳定、准确的心电信号,请遵循以下注意事项:

  • 身体放松: 避免肌肉紧张,以减少干扰信号。

  • 静止不动: 测量过程中尽量避免移动,以获得稳定的心电信号。

MicroPython 应用示例:

  1# SPDX-FileCopyrightText: 2025 M5Stack Technology CO LTD
  2#
  3# SPDX-License-Identifier: MIT
  4
  5import os, sys, io
  6import M5
  7from M5 import *
  8from module import ECGModule
  9import time
 10import m5utils
 11
 12
 13label0 = None
 14title0 = None
 15label_hr = None
 16ecg_0 = None
 17display_width = None
 18ecg_data = None
 19last_time = None
 20points = None
 21heartrate = None
 22new_ecg_data = None
 23new_ecg_data_len = None
 24data_max = None
 25data_min = None
 26i = None
 27y0 = None
 28y1 = None
 29
 30
 31def setup():
 32    global \
 33        label0, \
 34        title0, \
 35        label_hr, \
 36        ecg_0, \
 37        display_width, \
 38        ecg_data, \
 39        last_time, \
 40        points, \
 41        heartrate, \
 42        new_ecg_data, \
 43        new_ecg_data_len, \
 44        data_max, \
 45        data_min, \
 46        y0, \
 47        i, \
 48        y1
 49
 50    M5.begin()
 51    label0 = Widgets.Label("HearRate:", 5, 35, 1.0, 0xFF0000, 0x000000, Widgets.FONTS.DejaVu24)
 52    title0 = Widgets.Title("ECGModule Example", 3, 0xFFFFFF, 0x0000FF, Widgets.FONTS.DejaVu24)
 53    label_hr = Widgets.Label("  BPM", 142, 35, 1.0, 0xFF0000, 0x000000, Widgets.FONTS.DejaVu24)
 54
 55    ecg_0 = ECGModule(1, tx=7, rx=1)
 56    display_width = M5.Lcd.width()
 57    ecg_data = [0] * display_width
 58    points = [0] * display_width
 59
 60
 61def loop():
 62    global \
 63        label0, \
 64        title0, \
 65        label_hr, \
 66        ecg_0, \
 67        display_width, \
 68        ecg_data, \
 69        last_time, \
 70        points, \
 71        heartrate, \
 72        new_ecg_data, \
 73        new_ecg_data_len, \
 74        data_max, \
 75        data_min, \
 76        y0, \
 77        i, \
 78        y1
 79    M5.update()
 80    ecg_0.poll_data()
 81    if (time.ticks_diff((time.ticks_ms()), last_time)) > 200:
 82        last_time = time.ticks_ms()
 83        heartrate = ecg_0.read_heartrate()
 84        if heartrate > 0:
 85            label0.setColor(0x00FF00, 0x000000)
 86            label_hr.setColor(0x00FF00, 0x000000)
 87            label_hr.setText(str((str(heartrate) + str("BPM"))))
 88        else:
 89            label0.setColor(0xFF0000, 0x000000)
 90            label_hr.setText(str(" "))
 91        new_ecg_data = ecg_0.read_raw_ecg_data()
 92        if new_ecg_data:
 93            new_ecg_data_len = len(new_ecg_data)
 94            ecg_data = ecg_data[int((new_ecg_data_len + 1) - 1) :]
 95            ecg_data = ecg_data + new_ecg_data
 96            data_max = max(ecg_data)
 97            data_min = min(ecg_data)
 98            data_max = data_max + data_max / 10
 99            data_min = data_min - data_min / 10
100            if data_min < 0:
101                data_min = 0
102            for i in range(display_width):
103                points[int((i + 1) - 1)] = m5utils.remap(
104                    ecg_data[int((i + 1) - 1)], data_min, data_max, 150, 0
105                )
106
107            M5.Lcd.fillRect(0, 70, display_width, 155, 0x000000)
108            for i in range(display_width - 1):
109                y0 = int(70 + points[int((i + 1) - 1)])
110                y1 = int(70 + points[int((i + 2) - 1)])
111                M5.Lcd.drawLine(i + 1, y0, i + 2, y1, 0xFF0000)
112
113
114if __name__ == "__main__":
115    try:
116        setup()
117        while True:
118            loop()
119    except (Exception, KeyboardInterrupt) as e:
120        try:
121            from utility import print_error_msg
122
123            print_error_msg(e)
124        except ImportError:
125            print("please update to latest firmware")

示例输出:

None

API应用

ECGModule

class module.ecg.ECGModule(id=1, tx=7, rx=1)

基类:object

创建一个 ECGModule 对象。

参数:
  • id (int) – UART 端口号。

  • tx (int) – UART 发送引脚。

  • rx (int) – UART 接收引脚。

UiFlow2 代码块:

init.png

MicroPython 应用示例:

from module import ECGModule

module_ecg = ECGModule(id = 1, tx = 7, rx = 1)
poll_data()

轮询数据。

此函数用于检查模块是否有新数据,应在循环中重复调用,以确保持续获取数据。

UiFlow2 代码块:

poll_data.png

MicroPython 应用示例:

module_ecg.poll_data()
返回类型:

None

read_heartrate()

读取心率。

返回:

心率

返回类型:

int

如果心率数据无效,则返回 -1。

UiFlow2 代码块:

read_heartrate.png

MicroPython 应用示例:

module_ecg.read_heartrate()
read_raw_ecg_data()

读取原始 ECG 数据。

返回:

ECG 数据

返回类型:

list

UiFlow2 代码块:

read_raw_ecg_data.png

MicroPython 应用示例:

module_ecg.read_raw_ecg_data()