{"id":30749704,"url":"https://github.com/arctop/mw75-streamer","last_synced_at":"2026-02-15T19:03:59.087Z","repository":{"id":312780711,"uuid":"1045372793","full_name":"arctop/mw75-streamer","owner":"arctop","description":"A clean, modular Python package for streaming EEG data from MW75 Neuro headphones","archived":false,"fork":false,"pushed_at":"2025-11-11T22:49:42.000Z","size":18855,"stargazers_count":2,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-11-12T01:38:32.843Z","etag":null,"topics":["arctop","eeg","eeg-headphones","mw75","mw75-neuro","neuro"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/arctop.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-08-27T04:11:32.000Z","updated_at":"2025-11-11T22:48:17.000Z","dependencies_parsed_at":"2025-09-02T01:10:46.348Z","dependency_job_id":"7bb6bdab-ed06-4028-a0c3-c1dc72bede09","html_url":"https://github.com/arctop/mw75-streamer","commit_stats":null,"previous_names":["arctop/mw75-streamer"],"tags_count":6,"template":false,"template_full_name":null,"purl":"pkg:github/arctop/mw75-streamer","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arctop%2Fmw75-streamer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arctop%2Fmw75-streamer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arctop%2Fmw75-streamer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arctop%2Fmw75-streamer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/arctop","download_url":"https://codeload.github.com/arctop/mw75-streamer/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arctop%2Fmw75-streamer/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29487397,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-15T15:33:17.885Z","status":"ssl_error","status_checked_at":"2026-02-15T15:32:53.698Z","response_time":118,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["arctop","eeg","eeg-headphones","mw75","mw75-neuro","neuro"],"created_at":"2025-09-04T06:44:42.569Z","updated_at":"2026-02-15T19:03:59.082Z","avatar_url":"https://github.com/arctop.png","language":"Python","funding_links":[],"categories":["Software"],"sub_categories":["Python Toolboxes"],"readme":"# 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📖 **[Full Documentation \u0026 API Reference](https://arctop.github.io/mw75-streamer/api/)**\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 µV precision\n- **Multiple outputs**: WebSocket JSON, CSV files, Lab Streaming Layer (LSL)\n- **Mock device mode**: Cross-platform development without physical hardware\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 \u0026\u0026 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# Mock device mode (development without hardware)\nuv run -m mw75_streamer --mock --csv eeg.csv\nuv run -m mw75_streamer.server --mock\n\n# WebSocket Server (remote control mode)\nuv run -m mw75_streamer.server --port 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 (\u003c 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 µV\n    print(f\"Ch1: {packet.channels[0]:.1f} µV\")\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## Mock Device Mode\n\nDevelop and test without physical MW75 hardware using the built-in mock device:\n\n```bash\n# Stream synthetic data to CSV\nuv run -m mw75_streamer --mock --csv eeg.csv\n\n# WebSocket server with mock device\nuv run -m mw75_streamer.server --mock\n\n# Test with visualization\nuv run -m mw75_streamer.testing --advanced  # Terminal 1\nuv run -m mw75_streamer --mock --ws ws://localhost:8080  # Terminal 2\n```\n\n**Features:**\n- Generates valid 63-byte EEG packets with correct checksums\n- Streams at ~500Hz with realistic random data (-200 to +200 µV)\n- Works cross-platform (Linux, Windows, macOS)\n- Perfect for development, testing, and CI/CD pipelines\n- No hardware or Bluetooth required\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 (with real or mock device)\nuv run -m mw75_streamer --ws ws://localhost:8080\nuv run -m mw75_streamer --mock --ws ws://localhost:8080  # Mock version\n```\n\n## WebSocket Server (Remote Control Mode)\n\nFor applications that need remote control of MW75 device connections, the package includes a WebSocket server mode:\n\n```bash\n# Start server\nuv run -m mw75_streamer.server --port 8080\n\n# Example client\npython examples/websocket_server_client.py\n```\n\n**Features:**\n- Remote device connection control via JSON commands\n- Real-time EEG data streaming  \n- Auto-reconnect with exponential backoff\n- Configurable log levels (DEBUG, INFO, WARNING, ERROR)\n- Single client connection with 30-second keepalive\n\nFor complete protocol documentation and examples, see the [WebSocket Server documentation](https://arctop.github.io/mw75-streamer/api/server.html).\n\n## How It Works\n\n1. **BLE Activation**: Discovers MW75 via Bluetooth LE and sends activation commands (ENABLE_EEG → 100ms → ENABLE_RAW_MODE → 500ms → BATTERY_CMD)\n2. **RFCOMM Streaming**: Connects to channel 25 and receives 63-byte packets\n3. **Data Processing**: Converts raw ADC to µV, 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 µV\n\n## Requirements\n\n- **Hardware**: MW75 Neuro headphones (paired via Bluetooth) - *not required for mock mode*\n- **OS**: macOS (fully supported for real device), Linux/Windows (mock mode only - [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 \u003e 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\nFor detailed troubleshooting, see the [Troubleshooting Guide](https://arctop.github.io/mw75-streamer/api/troubleshooting.html)\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 \u0026 Community\n- **Master \u0026 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","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Farctop%2Fmw75-streamer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Farctop%2Fmw75-streamer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Farctop%2Fmw75-streamer/lists"}