A high-performance, real-time ECG (Electrocardiogram) data acquisition system built in Python. This system provides robust serial communication, advanced packet parsing, and comprehensive data logging capabilities for medical-grade ECG devices.
- Real-time ECG Data Acquisition via UART/Serial communication
- High-throughput Processing with asynchronous architecture and ring buffers
- Medical-grade Precision with microsecond timing accuracy
- Multi-channel Support for up to 8 ECG channels
- Robust Packet Processing with CRC validation and error handling
- Data Continuity Tracking with missing packet detection and recovery
- Ring Buffer Architecture prevents data loss at high sample rates
- Multi-process Parsing using ProcessPoolExecutor for performance
- Configurable Sample Rates (100Hz to 10kHz)
- Lead-off Detection and sign bit interpretation
- CSV Data Logging with high-precision timestamps
- Real-time Status Monitoring with comprehensive metrics
- Mock Hardware Simulator using AAMI EC13 standard test waveforms
- Medical-grade Test Signals from PhysioNet database
- Comprehensive Plotting Tools for data analysis and visualization
- Signal Resampling for different acquisition rates
pip install ecg-daqgit clone https://github.com/mehrshad/ecg-daq.git
cd ecg-daq
pip install -e .git clone https://github.com/mehrshad/ecg-daq.git
cd ecg-daq
pip install -e ".[dev]"import asyncio
from ecg_daq.core.config import Config
from examples.real_time_monitor import RealTimeMonitor
async def main():
# Create configuration
config = Config.create_default("COM5") # Windows
# config = Config.create_default("/dev/ttyUSB0") # Linux
config.uart.baudrate = 115200
config.ecg.sample_rate = 500.0 # 500 Hz
# Start monitoring
monitor = RealTimeMonitor(config)
await monitor.start()
if __name__ == "__main__":
asyncio.run(main())# Start ECG monitoring
ecg-monitor --port COM5 --baudrate 115200 --sample-rate 500
# Plot saved ECG data
ecg-plot data/ecg_data_20231215_143022.csv --channels 1,2,3 --time-window 10
# Run mock hardware for testing
ecg-mock-hardware --port COM6 --waveform aami3a --sample-rate 500from ecg_daq.core.config import Config, CRCMethod
config = Config.create_default("COM5")
# UART Settings
config.uart.baudrate = 115200
config.uart.timeout = 1.0
# ECG Settings
config.ecg.sample_rate = 500.0 # Hz
config.ecg.channel_count = 8
# Protocol Settings
config.protocol.crc_method = CRCMethod.SUM
config.protocol.enable_crc = True
config.protocol.samples_per_packet = 50The system uses a robust binary packet format:
4B STX (0x11223344) + 1B Packet Type + 4B Packet Num + 2B Data Len +
19Γ50B Data + 1B CRC + 4B ETX (0xAABBCCDD)
Each 19-byte sample contains:
- 3 bytes metadata: Flags, lead-off detection, sign bits
- 16 bytes channel data: 8 channels Γ 2 bytes (10Β΅V resolution)
from plot_ecg_data import ECGPlotter
# Create plotter
plotter = ECGPlotter("data/ecg_data.csv")
# Plot specific channels
plotter.plot_channels(channels=[1, 2, 3], time_window=10.0)
# Overview of all channels
plotter.plot_overview()
# Statistical analysis
plotter.plot_statistics()time_seconds,packet_number,packet_type,sample_index,channel_1,channel_2,...,channel_8,saturation,pace_detected,lead_off_bits,sign_bits
0.000000,0,1,0,0.123456,-0.098765,...,0.234567,False,False,0,128
0.002000,0,1,1,0.145678,-0.087654,...,0.245678,False,False,0,128
The system includes a mock hardware simulator using medical-grade AAMI EC13 test waveforms:
# Download AAMI test waveforms (done automatically)
python mock_daq_hardware.py --list-waveforms
# Run mock hardware
python mock_daq_hardware.py --port COM6 --waveform aami3a --sample-rate 500
# Full system test
python test_uart_with_mock.py --mock-port COM6 --receiver-port COM5- USB-to-Serial Adapters: Cross-connect TX/RX between two adapters
- Virtual Serial Ports: Use com0com (Windows) or socat (Linux)
- Physical Loopback: Single port with TX/RX connected
- Sample Rate: Up to 10 kHz per channel
- Channels: Up to 8 simultaneous channels
- Latency: < 10ms packet processing time
- Throughput: > 100 MB/s data processing
- Memory Usage: < 50MB typical operation
- Ring Buffer: Lock-free, high-performance circular buffer
- Process Pool: Multi-core packet parsing
- Async I/O: Non-blocking serial communication
- Memory Mapping: Efficient large file handling
- AAMI EC13:2002: Cardiac monitor testing standards
- IEC 60601-2-27: ECG equipment safety requirements
- FDA 21 CFR 820: Quality system regulations
- CRC Validation: Ensures packet integrity
- Timestamp Precision: Microsecond accuracy
- Missing Packet Detection: Data continuity verification
- Lead-off Detection: Electrode connection monitoring
- UART/Serial: RS-232, RS-485, USB-Serial
- Baud Rates: 9600 to 921600 bps
- Data Formats: 8N1, 8E1, 8O1
- Flow Control: None, RTS/CTS, XON/XOFF
- ECG Acquisition Boards: Custom FPGA-based systems
- USB-Serial Adapters: FTDI, Prolific, CP2102
- Development Boards: Arduino, Raspberry Pi, STM32
# Configuration management
from ecg_daq.core.config import Config, ECGConfig, UARTConfig, ProtocolConfig
# Data models
from ecg_daq.core.models import Packet, Sample, ECGData
# Data acquisition
from ecg_daq.data_acquisition.uart_receiver import AsyncUARTReceiver
from ecg_daq.data_acquisition.packet_parser import PacketParser
# Protocol handling
from ecg_daq.protocols.crc import CRCMethod, validate_crcexamples/real_time_monitor.py: Complete monitoring systemmock_daq_hardware.py: Hardware simulatorplot_ecg_data.py: Data visualization toolstest_uart_with_mock.py: System testing
No Data Received
# Check serial port permissions (Linux)
sudo usermod -a -G dialout $USER
# Verify port availability
python -c "import serial.tools.list_ports; print([p.device for p in serial.tools.list_ports.comports()])"Packet Parsing Errors
- Verify baud rate matches hardware
- Check CRC method configuration
- Ensure proper packet format
High CPU Usage
- Reduce sample rate if not needed
- Increase packet size (samples_per_packet)
- Enable hardware flow control
import logging
logging.basicConfig(level=logging.DEBUG)
# Enable detailed packet logging
config.debug.enable_packet_logging = TrueWe welcome contributions! Please see our Contributing Guide for details.
git clone https://github.com/mehrshad/ecg-daq.git
cd ecg-daq
pip install -e ".[dev]"
pre-commit installpytest tests/
pytest --cov=ecg_daq tests/This project is licensed under the MIT License - see the LICENSE file for details.
- PhysioNet: For providing AAMI EC13 test waveforms
- AAMI: For ECG testing standards
- Python Community: For excellent async and scientific libraries
- Documentation: GitHub Wiki
- Issues: GitHub Issues
- Discussions: GitHub Discussions
βοΈ Medical Device Notice: This software is intended for research and development purposes. For clinical use, ensure compliance with local medical device regulations and obtain appropriate certifications.