# MW75 Neuro Streamer
[](https://github.com/arctop/mw75-streamer/actions/workflows/ci.yml)
[](https://www.python.org/downloads/)
[](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
```

```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
```

## 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[](https://github.com/arctop/mw75-streamer/actions/workflows/ci.yml)\n[](https://www.python.org/downloads/)\n[](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\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\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"
}