mw75-streamer


Namemw75-streamer JSON
Version 1.0.2 PyPI version JSON
download
home_pageNone
SummaryStream EEG data from MW75 Neuro headphones using BLE and RFCOMM
upload_time2025-09-04 23:21:55
maintainerNone
docs_urlNone
authorNone
requires_python>=3.9
licenseNone
keywords eeg mw75 neurotechnology bluetooth streaming arctop
VCS
bugtrack_url
requirements bleak pyobjc pyobjc-framework-IOBluetooth websocket-client
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # MW75 Neuro Streamer

[![CI](https://github.com/arctop/mw75-streamer/actions/workflows/ci.yml/badge.svg)](https://github.com/arctop/mw75-streamer/actions/workflows/ci.yml)
[![Python 3.9+](https://img.shields.io/badge/python-3.9+-blue.svg)](https://www.python.org/downloads/)
[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)

Stream 12-channel EEG data from MW75 Neuro headphones with WebSocket, CSV, and LSL output support.

**About `uv`:** This project uses [uv](https://docs.astral.sh/uv/) for fast, reliable Python package management. Benefits include faster installs, better dependency resolution, and reproducible environments. All commands can be run with regular Python too (see [Alternative: Using Python Directly](#alternative-using-python-directly)), but we use `uv` throughout this documentation for consistency.

## Features

- **Real-time streaming**: 500Hz, 12-channel EEG with µV precision
- **Multiple outputs**: WebSocket JSON, CSV files, Lab Streaming Layer (LSL)
- **Built-in testing**: WebSocket servers with browser visualization
- **Robust protocol**: Checksum validation and error detection  

## Installation

**Option 1: Install from PyPI (recommended)**

```bash
uv pip install mw75-streamer
```

For additional features (WebSocket, LSL support):
```bash
uv pip install "mw75-streamer[all]"
```

**Option 2: Install from source**

```bash
# Clone this repository
git clone https://github.com/arctop/mw75-streamer.git
cd mw75_streamer
```

![Installation Demo](docs/assets/installation.gif)

```bash
# Install uv if needed (see installation guide: https://docs.astral.sh/uv/getting-started/installation)
brew install uv

# Create environment and install package
uv venv && uv pip install -e ".[all]"
```

## Usage

```bash
# Basic streaming
uv run -m mw75_streamer --browser
uv run -m mw75_streamer --csv eeg.csv
uv run -m mw75_streamer --ws ws://localhost:8080
uv run -m mw75_streamer --lsl MW75_EEG

# Combined outputs
uv run -m mw75_streamer --csv eeg.csv --ws ws://localhost:8080
```
![Browser Visualization](docs/assets/browser.gif)


## Developer Examples

For advanced integration into your own applications, see the [examples/](examples/) folder:

- **[simple_callback.py](examples/simple_callback.py)** - Quick start example for basic callback usage
- **[callback_integration.py](examples/callback_integration.py)** - Comprehensive example showing real-time EEG processing using custom callbacks  
- **[threaded_processing.py](examples/threaded_processing.py)** - Threading patterns for heavy processing (recommended for ML/filtering)
- **Custom Callbacks**: Process EEG packets, raw data, and events directly in your code  
- **Performance Guidance**: Keep callbacks fast (< 1ms) or use threading for heavy work
- **Integration Patterns**: Combine callbacks with existing outputs (CSV, WebSocket, LSL)

```python
# Quick callback example
from mw75_streamer import MW75Streamer, EEGPacket

def process_eeg(packet: EEGPacket):
    # packet.channels = 12 EEG channels in µV
    print(f"Ch1: {packet.channels[0]:.1f} µV")

streamer = MW75Streamer(eeg_callback=process_eeg)
await streamer.start_streaming()
```

See [examples/README.md](examples/README.md) for complete documentation.

## Testing

```bash
# 1. Start test server
uv run -m mw75_streamer.testing --advanced
# Optional: Press 'b' + Enter in server terminal to open browser visualization

# 2. Start EEG streaming
uv run -m mw75_streamer --ws ws://localhost:8080
```

## How It Works

1. **BLE Activation**: Discovers MW75 via Bluetooth LE and sends activation commands
2. **RFCOMM Streaming**: Connects to channel 25 and receives 63-byte packets
3. **Data Processing**: Converts raw ADC to µV, validates checksums, outputs to CSV/WebSocket/LSL

## Data Formats

**CSV**: `Timestamp,EventId,Counter,Ref,DRL,Ch1RawEEG,...,Ch12RawEEG,FeatureStatus`

**WebSocket JSON**: Real-time streaming with timestamp, counter, ref/drl, and 12 channel values in µV

## Requirements

- **Hardware**: MW75 Neuro headphones (paired via Bluetooth)
- **OS**: macOS (fully supported), Linux (planned - [contributions welcome](CONTRIBUTING.md))
- **Python**: 3.9+

## macOS Setup for LSL

```bash
# Install LSL library (for LSL support)
brew install labstreaminglayer/tap/lsl
export DYLD_LIBRARY_PATH="/opt/homebrew/lib:$DYLD_LIBRARY_PATH"

# Pair MW75 headphones in System Preferences > Bluetooth
```


## Performance Optimization

For improved real-time performance and reduced packet drops, run with elevated priority:

```bash
# Run with high priority (requires sudo for optimal performance)
sudo uv run -m mw75_streamer --csv eeg.csv

# The streamer automatically sets:
# - Process priority (niceness -10)
# - Thread real-time scheduling policy
# - Optimized RFCOMM event loop timing (1ms intervals)
```

**Note**: Running without `sudo` will still work but may have higher packet drop rates under system load.

## Troubleshooting

- **MW75 not found**: Ensure headphones are powered on and paired
- **Connection failed**: Re-pair device in Bluetooth settings
- **Dropped packets**: Reduce Bluetooth interference, move away from WiFi routers and other 2.4GHz devices

## Alternative: Using Python Directly

All `uv` commands can be replaced with regular Python. Simply activate your virtual environment first:

```bash
# Example: Replace 'uv run -m mw75_streamer' with 'python -m mw75_streamer'
source .venv/bin/activate
python -m mw75_streamer --csv eeg.csv --ws ws://localhost:8080
python -m mw75_streamer.testing --advanced

# Or replace 'uv pip install' with 'pip install'  
pip install mw75-streamer
```

## Development

See [CONTRIBUTING.md](CONTRIBUTING.md) for development setup and contribution guidelines.

## License

MIT License - see [LICENSE](LICENSE) for details.

## About

**MW75 EEG Streamer** was developed by [Arctop](https://arctop.com), a neurotechnology company focused on making brain-computer interfaces accessible and practical.

## Acknowledgments

### AI Assistance
- **[Claude Code (by Anthropic)](https://claude.ai/code)** - AI coding assistant used for development support and code optimization.

### Open Source Dependencies
This project builds upon excellent open source libraries:

- **[bleak](https://github.com/hbldh/bleak)** - Cross-platform Bluetooth Low Energy library for Python
- **[PyObjC](https://github.com/ronaldoussoren/pyobjc)** - Python bridge to Objective-C for macOS integration
- **[websocket-client](https://github.com/websocket-client/websocket-client)** - WebSocket client library for real-time streaming
- **[websockets](https://github.com/aaugustin/websockets)** - WebSocket server implementation for testing tools
- **[pylsl](https://github.com/labstreaminglayer/liblsl-Python)** - Python bindings for Lab Streaming Layer
- **[black](https://github.com/psf/black)** - Python code formatter for consistent style
- **[mypy](https://github.com/python/mypy)** - Static type checker for Python
- **[flake8](https://github.com/PyCQA/flake8)** - Python linting tool for code quality

### Hardware & Community
- **Master & Dynamic** for creating the MW75 Neuro headphones and making EEG accessible
- The **Python community** for excellent Bluetooth libraries and frameworks
---

For detailed technical information about the MW75 protocol, see the inline documentation in the source code.

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "mw75-streamer",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.9",
    "maintainer_email": "Arctop <opensource@arctop.com>",
    "keywords": "eeg, mw75, neurotechnology, bluetooth, streaming, arctop",
    "author": null,
    "author_email": "Eitan Kay <opensource@arctop.com>",
    "download_url": "https://files.pythonhosted.org/packages/31/d9/febde9d1a22f78e937112da230e993f1be4d156d74a5e99cc73cca0769b3/mw75_streamer-1.0.2.tar.gz",
    "platform": null,
    "description": "# MW75 Neuro Streamer\n\n[![CI](https://github.com/arctop/mw75-streamer/actions/workflows/ci.yml/badge.svg)](https://github.com/arctop/mw75-streamer/actions/workflows/ci.yml)\n[![Python 3.9+](https://img.shields.io/badge/python-3.9+-blue.svg)](https://www.python.org/downloads/)\n[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)\n\nStream 12-channel EEG data from MW75 Neuro headphones with WebSocket, CSV, and LSL output support.\n\n**About `uv`:** This project uses [uv](https://docs.astral.sh/uv/) for fast, reliable Python package management. Benefits include faster installs, better dependency resolution, and reproducible environments. All commands can be run with regular Python too (see [Alternative: Using Python Directly](#alternative-using-python-directly)), but we use `uv` throughout this documentation for consistency.\n\n## Features\n\n- **Real-time streaming**: 500Hz, 12-channel EEG with \u00b5V precision\n- **Multiple outputs**: WebSocket JSON, CSV files, Lab Streaming Layer (LSL)\n- **Built-in testing**: WebSocket servers with browser visualization\n- **Robust protocol**: Checksum validation and error detection  \n\n## Installation\n\n**Option 1: Install from PyPI (recommended)**\n\n```bash\nuv pip install mw75-streamer\n```\n\nFor additional features (WebSocket, LSL support):\n```bash\nuv pip install \"mw75-streamer[all]\"\n```\n\n**Option 2: Install from source**\n\n```bash\n# Clone this repository\ngit clone https://github.com/arctop/mw75-streamer.git\ncd mw75_streamer\n```\n\n![Installation Demo](docs/assets/installation.gif)\n\n```bash\n# Install uv if needed (see installation guide: https://docs.astral.sh/uv/getting-started/installation)\nbrew install uv\n\n# Create environment and install package\nuv venv && uv pip install -e \".[all]\"\n```\n\n## Usage\n\n```bash\n# Basic streaming\nuv run -m mw75_streamer --browser\nuv run -m mw75_streamer --csv eeg.csv\nuv run -m mw75_streamer --ws ws://localhost:8080\nuv run -m mw75_streamer --lsl MW75_EEG\n\n# Combined outputs\nuv run -m mw75_streamer --csv eeg.csv --ws ws://localhost:8080\n```\n![Browser Visualization](docs/assets/browser.gif)\n\n\n## Developer Examples\n\nFor advanced integration into your own applications, see the [examples/](examples/) folder:\n\n- **[simple_callback.py](examples/simple_callback.py)** - Quick start example for basic callback usage\n- **[callback_integration.py](examples/callback_integration.py)** - Comprehensive example showing real-time EEG processing using custom callbacks  \n- **[threaded_processing.py](examples/threaded_processing.py)** - Threading patterns for heavy processing (recommended for ML/filtering)\n- **Custom Callbacks**: Process EEG packets, raw data, and events directly in your code  \n- **Performance Guidance**: Keep callbacks fast (< 1ms) or use threading for heavy work\n- **Integration Patterns**: Combine callbacks with existing outputs (CSV, WebSocket, LSL)\n\n```python\n# Quick callback example\nfrom mw75_streamer import MW75Streamer, EEGPacket\n\ndef process_eeg(packet: EEGPacket):\n    # packet.channels = 12 EEG channels in \u00b5V\n    print(f\"Ch1: {packet.channels[0]:.1f} \u00b5V\")\n\nstreamer = MW75Streamer(eeg_callback=process_eeg)\nawait streamer.start_streaming()\n```\n\nSee [examples/README.md](examples/README.md) for complete documentation.\n\n## Testing\n\n```bash\n# 1. Start test server\nuv run -m mw75_streamer.testing --advanced\n# Optional: Press 'b' + Enter in server terminal to open browser visualization\n\n# 2. Start EEG streaming\nuv run -m mw75_streamer --ws ws://localhost:8080\n```\n\n## How It Works\n\n1. **BLE Activation**: Discovers MW75 via Bluetooth LE and sends activation commands\n2. **RFCOMM Streaming**: Connects to channel 25 and receives 63-byte packets\n3. **Data Processing**: Converts raw ADC to \u00b5V, validates checksums, outputs to CSV/WebSocket/LSL\n\n## Data Formats\n\n**CSV**: `Timestamp,EventId,Counter,Ref,DRL,Ch1RawEEG,...,Ch12RawEEG,FeatureStatus`\n\n**WebSocket JSON**: Real-time streaming with timestamp, counter, ref/drl, and 12 channel values in \u00b5V\n\n## Requirements\n\n- **Hardware**: MW75 Neuro headphones (paired via Bluetooth)\n- **OS**: macOS (fully supported), Linux (planned - [contributions welcome](CONTRIBUTING.md))\n- **Python**: 3.9+\n\n## macOS Setup for LSL\n\n```bash\n# Install LSL library (for LSL support)\nbrew install labstreaminglayer/tap/lsl\nexport DYLD_LIBRARY_PATH=\"/opt/homebrew/lib:$DYLD_LIBRARY_PATH\"\n\n# Pair MW75 headphones in System Preferences > Bluetooth\n```\n\n\n## Performance Optimization\n\nFor improved real-time performance and reduced packet drops, run with elevated priority:\n\n```bash\n# Run with high priority (requires sudo for optimal performance)\nsudo uv run -m mw75_streamer --csv eeg.csv\n\n# The streamer automatically sets:\n# - Process priority (niceness -10)\n# - Thread real-time scheduling policy\n# - Optimized RFCOMM event loop timing (1ms intervals)\n```\n\n**Note**: Running without `sudo` will still work but may have higher packet drop rates under system load.\n\n## Troubleshooting\n\n- **MW75 not found**: Ensure headphones are powered on and paired\n- **Connection failed**: Re-pair device in Bluetooth settings\n- **Dropped packets**: Reduce Bluetooth interference, move away from WiFi routers and other 2.4GHz devices\n\n## Alternative: Using Python Directly\n\nAll `uv` commands can be replaced with regular Python. Simply activate your virtual environment first:\n\n```bash\n# Example: Replace 'uv run -m mw75_streamer' with 'python -m mw75_streamer'\nsource .venv/bin/activate\npython -m mw75_streamer --csv eeg.csv --ws ws://localhost:8080\npython -m mw75_streamer.testing --advanced\n\n# Or replace 'uv pip install' with 'pip install'  \npip install mw75-streamer\n```\n\n## Development\n\nSee [CONTRIBUTING.md](CONTRIBUTING.md) for development setup and contribution guidelines.\n\n## License\n\nMIT License - see [LICENSE](LICENSE) for details.\n\n## About\n\n**MW75 EEG Streamer** was developed by [Arctop](https://arctop.com), a neurotechnology company focused on making brain-computer interfaces accessible and practical.\n\n## Acknowledgments\n\n### AI Assistance\n- **[Claude Code (by Anthropic)](https://claude.ai/code)** - AI coding assistant used for development support and code optimization.\n\n### Open Source Dependencies\nThis project builds upon excellent open source libraries:\n\n- **[bleak](https://github.com/hbldh/bleak)** - Cross-platform Bluetooth Low Energy library for Python\n- **[PyObjC](https://github.com/ronaldoussoren/pyobjc)** - Python bridge to Objective-C for macOS integration\n- **[websocket-client](https://github.com/websocket-client/websocket-client)** - WebSocket client library for real-time streaming\n- **[websockets](https://github.com/aaugustin/websockets)** - WebSocket server implementation for testing tools\n- **[pylsl](https://github.com/labstreaminglayer/liblsl-Python)** - Python bindings for Lab Streaming Layer\n- **[black](https://github.com/psf/black)** - Python code formatter for consistent style\n- **[mypy](https://github.com/python/mypy)** - Static type checker for Python\n- **[flake8](https://github.com/PyCQA/flake8)** - Python linting tool for code quality\n\n### Hardware & Community\n- **Master & Dynamic** for creating the MW75 Neuro headphones and making EEG accessible\n- The **Python community** for excellent Bluetooth libraries and frameworks\n---\n\nFor detailed technical information about the MW75 protocol, see the inline documentation in the source code.\n",
    "bugtrack_url": null,
    "license": null,
    "summary": "Stream EEG data from MW75 Neuro headphones using BLE and RFCOMM",
    "version": "1.0.2",
    "project_urls": {
        "Bug Tracker": "https://github.com/arctop/mw75-streamer/issues",
        "Company": "https://arctop.com",
        "Documentation": "https://github.com/arctop/mw75-streamer#readme",
        "Homepage": "https://github.com/arctop/mw75-streamer",
        "Repository": "https://github.com/arctop/mw75-streamer"
    },
    "split_keywords": [
        "eeg",
        " mw75",
        " neurotechnology",
        " bluetooth",
        " streaming",
        " arctop"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "4c94182f7755e30f88e23b50ef4e4d1aa838257d4b4f7793fc5719b106e703c8",
                "md5": "6f61a04c5c1d3b0592aba277d51fb8f8",
                "sha256": "92d2a1065a85f82e9e4d7be26c49e36ad1c4f5d4cb7f1f825f374aaa8fb985d2"
            },
            "downloads": -1,
            "filename": "mw75_streamer-1.0.2-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "6f61a04c5c1d3b0592aba277d51fb8f8",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.9",
            "size": 124549,
            "upload_time": "2025-09-04T23:21:53",
            "upload_time_iso_8601": "2025-09-04T23:21:53.658095Z",
            "url": "https://files.pythonhosted.org/packages/4c/94/182f7755e30f88e23b50ef4e4d1aa838257d4b4f7793fc5719b106e703c8/mw75_streamer-1.0.2-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "31d9febde9d1a22f78e937112da230e993f1be4d156d74a5e99cc73cca0769b3",
                "md5": "51b75d7cfecd0e557a5433b7016de7d9",
                "sha256": "1236125e471eb360358738089da0a2a5601bfe19f11099c6f577f76131e38a74"
            },
            "downloads": -1,
            "filename": "mw75_streamer-1.0.2.tar.gz",
            "has_sig": false,
            "md5_digest": "51b75d7cfecd0e557a5433b7016de7d9",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.9",
            "size": 13260094,
            "upload_time": "2025-09-04T23:21:55",
            "upload_time_iso_8601": "2025-09-04T23:21:55.765459Z",
            "url": "https://files.pythonhosted.org/packages/31/d9/febde9d1a22f78e937112da230e993f1be4d156d74a5e99cc73cca0769b3/mw75_streamer-1.0.2.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-09-04 23:21:55",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "arctop",
    "github_project": "mw75-streamer",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "requirements": [
        {
            "name": "bleak",
            "specs": [
                [
                    ">=",
                    "0.20.0"
                ]
            ]
        },
        {
            "name": "pyobjc",
            "specs": [
                [
                    ">=",
                    "9.0"
                ]
            ]
        },
        {
            "name": "pyobjc-framework-IOBluetooth",
            "specs": [
                [
                    ">=",
                    "9.0"
                ]
            ]
        },
        {
            "name": "websocket-client",
            "specs": [
                [
                    ">=",
                    "1.6.0"
                ]
            ]
        }
    ],
    "lcname": "mw75-streamer"
}
        
Elapsed time: 3.12824s