ECG Module

This library is the driver for Module13.2 ECG, and the module communicates via UART.

Support the following products:

Module13.2 ECG

UiFlow2 Example:

Heart Rate Monitoring Display

Open the cores3_ecg_module_base_example.m5f2 project in UiFlow2.

This example program is used for real-time heart rate monitoring and ECG waveform display. During measurement, the device continuously plots the ECG (Electrocardiogram) waveform and automatically calculates and displays the heart rate data once the signal stabilizes.

Electrode Placement Instructions: Please follow the guidelines below to correctly connect the ECG electrodes:

  • Right Arm (RA): Place the right arm electrode on the right edge of the sternum, at the 2nd intercostal space along the midclavicular line, near the right shoulder.

  • Left Arm (LA): Place the left arm electrode on the left edge of the sternum, at the 2nd intercostal space along the midclavicular line, near the left shoulder.

  • Left Leg (LL): Place the left leg electrode above the iliac crest (hip bone) on the left lower abdomen, or on the lower left side of the abdomen.

Measurement Precautions: To ensure stable and accurate ECG signals, please follow these precautions:

  • Stay relaxed: Avoid muscle tension to reduce signal interference.

  • Remain still: Minimize movement during measurement to obtain a stable ECG signal.

UiFlow2 Code Block:

cores3_ecg_module_base_example.png

Example output:

None

MicroPython Example:

Heart Rate Monitoring Display

This example program is used for real-time heart rate monitoring and ECG waveform display. During measurement, the device continuously plots the ECG (Electrocardiogram) waveform and automatically calculates and displays the heart rate data once the signal stabilizes.

Electrode Placement Instructions: Please follow the guidelines below to correctly connect the ECG electrodes:

  • Right Arm (RA): Place the right arm electrode on the right edge of the sternum, at the 2nd intercostal space along the midclavicular line, near the right shoulder.

  • Left Arm (LA): Place the left arm electrode on the left edge of the sternum, at the 2nd intercostal space along the midclavicular line, near the left shoulder.

  • Left Leg (LL): Place the left leg electrode above the iliac crest (hip bone) on the left lower abdomen, or on the lower left side of the abdomen.

Measurement Precautions: To ensure stable and accurate ECG signals, please follow these precautions:

  • Stay relaxed: Avoid muscle tension to reduce signal interference.

  • Remain still: Minimize movement during measurement to obtain a stable ECG signal.

MicroPython Code Block:

  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")

Example output:

None

API

ECGModule

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

Bases: object

Create an ECGModule object.

Parameters:
  • id (int) – UART id.

  • tx (int) – the UART TX pin.

  • rx (int) – the UART RX pin.

UiFlow2 Code Block:

init.png

MicroPython Code Block:

from module import ECGModule

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

Poll data.

This function checks for new data from the module and should be called repeatedly in a loop to ensure continuous data retrieval.

UiFlow2 Code Block:

poll_data.png

MicroPython Code Block:

module_ecg.poll_data()
Return type:

None

read_heartrate()

Read heartrate.

Returns:

heart rate

Return type:

int

If heart rate is no valid, return -1.

UiFlow2 Code Block:

read_heartrate.png

MicroPython Code Block:

module_ecg.read_heartrate()
read_raw_ecg_data()

Read raw ECG data.

Returns:

ECG data

Return type:

list

UiFlow2 Code Block:

read_raw_ecg_data.png

MicroPython Code Block:

module_ecg.read_raw_ecg_data()