Skip to content

Latest commit

Β 

History

History
303 lines (228 loc) Β· 8.78 KB

File metadata and controls

303 lines (228 loc) Β· 8.78 KB

ECG DAQ - High-Performance ECG Data Acquisition System

Python Version License: MIT Code Style: Black

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.

πŸš€ Features

Core Capabilities

  • 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

Advanced Features

  • 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

Testing & Simulation

  • 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

πŸ“¦ Installation

From PyPI (when published)

pip install ecg-daq

From Source

git clone https://github.com/mehrshad/ecg-daq.git
cd ecg-daq
pip install -e .

Development Installation

git clone https://github.com/mehrshad/ecg-daq.git
cd ecg-daq
pip install -e ".[dev]"

🎯 Quick Start

Basic ECG Monitoring

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

Command Line Usage

# 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 500

πŸ”§ Configuration

ECG Configuration

from 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 = 50

Packet Format

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

πŸ“Š Data Analysis & Visualization

Plotting ECG Data

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

CSV Output Format

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

πŸ§ͺ Testing with Mock Hardware

AAMI EC13 Test Waveforms

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

Hardware Setup Options

  1. USB-to-Serial Adapters: Cross-connect TX/RX between two adapters
  2. Virtual Serial Ports: Use com0com (Windows) or socat (Linux)
  3. Physical Loopback: Single port with TX/RX connected

πŸ“ˆ Performance

Benchmarks

  • 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

Optimization Features

  • 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

πŸ₯ Medical Compliance

Standards Compliance

  • AAMI EC13:2002: Cardiac monitor testing standards
  • IEC 60601-2-27: ECG equipment safety requirements
  • FDA 21 CFR 820: Quality system regulations

Data Integrity

  • CRC Validation: Ensures packet integrity
  • Timestamp Precision: Microsecond accuracy
  • Missing Packet Detection: Data continuity verification
  • Lead-off Detection: Electrode connection monitoring

πŸ”Œ Hardware Compatibility

Supported Interfaces

  • 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

Tested Hardware

  • ECG Acquisition Boards: Custom FPGA-based systems
  • USB-Serial Adapters: FTDI, Prolific, CP2102
  • Development Boards: Arduino, Raspberry Pi, STM32

πŸ“š API Reference

Core Classes

# 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_crc

Examples

πŸ› Troubleshooting

Common Issues

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

Debug Mode

import logging
logging.basicConfig(level=logging.DEBUG)

# Enable detailed packet logging
config.debug.enable_packet_logging = True

🀝 Contributing

We welcome contributions! Please see our Contributing Guide for details.

Development Setup

git clone https://github.com/mehrshad/ecg-daq.git
cd ecg-daq
pip install -e ".[dev]"
pre-commit install

Running Tests

pytest tests/
pytest --cov=ecg_daq tests/

πŸ“„ License

This project is licensed under the MIT License - see the LICENSE file for details.

πŸ™ Acknowledgments

  • PhysioNet: For providing AAMI EC13 test waveforms
  • AAMI: For ECG testing standards
  • Python Community: For excellent async and scientific libraries

πŸ“ž Support


βš•οΈ 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.