Skip to main content

MW75 Neuro Streamer

CI Python 3.9+ Code style: black

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

📖 Full Documentation & API Reference

About uv: This project uses 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), 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)

uv pip install mw75-streamer

For additional features (WebSocket, LSL support):

uv pip install "mw75-streamer[all]"

Option 2: Install from source

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

Installation Demo

# 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

# 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

# WebSocket Server (remote control mode)
uv run -m mw75_streamer.server --port 8080

Browser Visualization

Developer Examples

For advanced integration into your own applications, see the examples/ folder:

  • simple_callback.py - Quick start example for basic callback usage
  • callback_integration.py - Comprehensive example showing real-time EEG processing using custom callbacks
  • 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)
# 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 for complete documentation.

Testing

# 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

WebSocket Server (Remote Control Mode)

For applications that need remote control of MW75 device connections, the package includes a WebSocket server mode:

# Start server
uv run -m mw75_streamer.server --port 8080

# Example client
python examples/websocket_server_client.py

Features:

  • Remote device connection control via JSON commands
  • Real-time EEG data streaming
  • Auto-reconnect with exponential backoff
  • Configurable log levels (DEBUG, INFO, WARNING, ERROR)
  • Single client connection with 30-second keepalive

For complete protocol documentation and examples, see the WebSocket Server documentation.

How It Works

  1. BLE Activation: Discovers MW75 via Bluetooth LE and sends activation commands (ENABLE_EEG → 100ms → ENABLE_RAW_MODE → 500ms → BATTERY_CMD)
  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)
  • Python: 3.9+

macOS Setup for LSL

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

# 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

For detailed troubleshooting, see the Troubleshooting Guide

Alternative: Using Python Directly

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

# 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 for development setup and contribution guidelines.

License

MIT License - see LICENSE for details.

About

MW75 EEG Streamer was developed by Arctop, a neurotechnology company focused on making brain-computer interfaces accessible and practical.

Acknowledgments

AI Assistance

Open Source Dependencies

This project builds upon excellent open source libraries:

  • bleak - Cross-platform Bluetooth Low Energy library for Python
  • PyObjC - Python bridge to Objective-C for macOS integration
  • websocket-client - WebSocket client library for real-time streaming
  • websockets - WebSocket server implementation for testing tools
  • pylsl - Python bindings for Lab Streaming Layer
  • black - Python code formatter for consistent style
  • mypy - Static type checker for Python
  • 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.

Metadata

Release files for mw75-streamer 1.0.8

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for mw75-streamer 1.0.8
File Size Uploaded
mw75_streamer-1.0.8.tar.gz 13.3 MB Details

Built distribution (wheel)

Table of built distributions (wheels) for mw75-streamer 1.0.8
File Interpreter ABI Platform
mw75_streamer-1.0.8-py3-none-any.whl Python 3 none any Details

Total release size: 13.5 MB

Release files / mw75_streamer-1.0.8.tar.gz

Download URL mw75_streamer-1.0.8.tar.gz
Size 13.3 MB
Tags Source
SHA-256 checksum
How to use checksums
c33e2bf23d1d897267e01aa7f8732438b01da3e51617317ba0cb4752972715ea
BLAKE2b-256 checksum
How to use checksums
5dd59a0e785fcab4b4522dea0e49938bb68a25633a6e5c081dbedb0290b3a495
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 15, 2025.

Transparency log

Release files / mw75_streamer-1.0.8-py3-none-any.whl

Download URL mw75_streamer-1.0.8-py3-none-any.whl
Size 135.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
e576b6e3e4f0f939e4b50013ae0f96e1f30c97120fbc35719ea2e2bbefac993e
BLAKE2b-256 checksum
How to use checksums
09d2554a3cb7cdb872417322da263b7e9c34d13e20c9031810f02c16b6adf38d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 15, 2025.

Transparency log

Release history Release notifications | RSS feed

This release

1.0.8 This release

2 release files

1.0.7

2 release files

1.0.6

2 release files

1.0.5

2 release files

1.0.4

2 release files

1.0.3

2 release files

1.0.2

2 release files

1.0.1

2 release files

1.0.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page