Giter Site home page Giter Site logo

urish / muse-js Goto Github PK

View Code? Open in Web Editor NEW
272.0 16.0 75.0 916 KB

Muse 2016 EEG Headset JavaScript Library (using Web Bluetooth)

Home Page: https://medium.com/@urish/reactive-brain-waves-af07864bb7d4

License: MIT License

TypeScript 98.84% JavaScript 1.16%
web-bluetooth eeg eeg-headset eeg-headband eeg-data bci brain-computer-interface brain-connectivity typescript-library

muse-js's Introduction

muse-js

Build Status

Muse 1, Muse 2, and Muse S EEG Headset JavaScript Library (using Web Bluetooth).

Running the demo app

yarn
yarn start

and then open http://localhost:4445/

Usage example

import { MuseClient } from 'muse-js';

async function main() {
  let client = new MuseClient();
  await client.connect();
  await client.start();
  client.eegReadings.subscribe(reading => {
    console.log(reading);
  });
  client.telemetryData.subscribe(telemetry => {
    console.log(telemetry);
  });
  client.accelerometerData.subscribe(acceleration => {
    console.log(acceleration);
  });
}

main();

Using in node.js

You can use this library to connect to the Muse EEG headset from your node.js application. Use the bleat package which emulates the Web Bluetooth API on top of noble:

const noble = require('noble');
const bluetooth = require('bleat').webbluetooth;

async function connect() {
    let device = await bluetooth.requestDevice({
        filters: [{ services: [MUSE_SERVICE] }]
    });
    const gatt = await device.gatt.connect();
    const client = new MuseClient();
    await client.connect(gatt);
    await client.start();
    // Now do whatever with muse client...
}

noble.on('stateChange', (state) => {
    if (state === 'poweredOn') {
        connect();
    }
});

You can find a fully working example in the muse-lsl repo.

Auxiliary Electrode

The Muse 2016 EEG headsets contains four electrodes, and you can connect an additional Auxiliary electrode through the Micro USB port. By default, muse-js does not read data from the Auxiliary electrode channel. You can change this behavior and enable the Auxiliary electrode by setting the enableAux property to true, just before calling the connect method:

async function main() {
  let client = new MuseClient();
  client.enableAux = true;
  await client.connect();
}

PPG (Photoplethysmography) / Optical Sensor

The Muse 2 and Muse S contain PPG/optical blood sensors, which this library supports. There are three signal streams, ppg1, ppg2, and ppg3. These are ambient, infrared, and red (respectively) on the Muse 2, and (we think, unconfirmed) infrared, green, and unknown (respectively) on the Muse S. To use PPG, ensure you enable it before connecting to a Muse. PPG is not present and thus will not work on Muse 1/1.5, and enabling it may have unexpected consequences.

To enable PPG:

async function main() {
  let client = new MuseClient();
  client.enablePpg = true;
  await client.connect();
}

To subscribe and receive values from PPG, it's just like subscribing to EEG (see Usage Example):

client.ppgReadings.subscribe((ppgreading) => {
    console.log(ppgreading);
});

Event Markers

For convenience, there is an eventMarkers stream included in MuseClient that you can use in order to introduce timestamped event markers into your project. Just subscribe to eventMarkers and use the injectMarker method with the value and optional timestamp of an event to send it through the stream.

async function main() {
    let client = new MuseClient();
    client.eventMarkers.subscribe((event) => {
        console.log(event);
    });
    client.injectMarker("house")
    client.injectMarker("face")
    client.injectMarker("dog")
}

Projects using muse-js

  • EEGEdu - Interactive Brain Playground. Source code using React, Polaris and chartjs.
  • EEG Explorer - Visual EEG readings from the Muse EEG Headset. Source code using Angular, Material Design and smoothie charts.

muse-js's People

Contributors

caydenpierce avatar dependabot[bot] avatar jdpigeon avatar kylemath avatar sophiedeziel avatar urish avatar wtcross avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

muse-js's Issues

issue starting on fedora

Hey, I'm trying to test this out on my linux machine. I'm using Fedora 25.
I'm not the best at debugging node/javascript tracebacks. :\

[jnaulty@emarginata muse-js]$ yarn --version
1.3.2
[jnaulty@emarginata muse-js]$ npm -v
3.10.10
[jnaulty@emarginata muse-js]$ node -v
v6.12.0
[jnaulty@emarginata muse-js]$ yarn start
yarn run v1.3.2
$ node demo/fuse
app ->
└──  (6 files,  29.5 kB) default
     demo/src/main.js
     src/muse.js
     src/lib/muse-interfaces.js
     src/lib/muse-parse.js
     src/lib/muse-utils.js
     src/lib/zip-samples.js
└── [email protected] 1.8 kB (0 files)
└── [email protected] 2.9 kB (0 files)
└── [email protected] 9.8 kB (0 files)
└── [email protected] 171.6 kB (0 files)
Size: 215.5 kB in 139ms

---------------------------------------------------
Development server running http://localhost:4445
---------------------------------------------------

events.js:160
      throw er; // Unhandled 'error' event
      ^

Error: watch /home/jnaulty/github/muse-js/node_modules/rxjs/operators/publishLast.js ENOSPC
    at exports._errnoException (util.js:1020:11)
    at FSWatcher.start (fs.js:1451:19)
    at Object.fs.watch (fs.js:1478:11)
    at createFsWatchInstance (/home/jnaulty/github/muse-js/node_modules/chokidar/lib/nodefs-handler.js:37:15)
    at setFsWatchListener (/home/jnaulty/github/muse-js/node_modules/chokidar/lib/nodefs-handler.js:80:15)
    at FSWatcher.NodeFsHandler._watchWithNodeFs (/home/jnaulty/github/muse-js/node_modules/chokidar/lib/nodefs-handler.js:228:14)
    at FSWatcher.NodeFsHandler._handleFile (/home/jnaulty/github/muse-js/node_modules/chokidar/lib/nodefs-handler.js:255:21)
    at FSWatcher.<anonymous> (/home/jnaulty/github/muse-js/node_modules/chokidar/lib/nodefs-handler.js:473:21)
    at FSReqWrap.oncomplete (fs.js:123:15)
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
[jnaulty@emarginata muse-js]$ 

Muse S compatibility

Hello,

This is a question rather than an issue. Would muse-js work with Muse S?

Absolute Band Powers?

Amazing project! Thought our new Muse (2016 model) would be unusable with our Mac/PC based neurofeedback apps until we found Muse-JS:)

As I understand it, Muse-JS reads raw EEG data from each electrode (TP9, AF7, AF8, TP10), but is there a simple way to read absolute band powers (delta, theta, alpha, etc.), or other data, from Muse-JS, without needing to manually decode the raw EEG data from Muse-JS?

I looked through your code, but didn't spot any way to simply parse or decode/compute band powers. Muse-IO & Muse Monitor both provided live band powers data (via OSC paths muse/elements/delta_absolute etc), as well as raw EEG data, but they're no longer feasible options & we'd love to consider using Muse-JS moving forward. Thanks for any feedback!

Use preset 21 when `enableAux` is false

The Muse 2016 device has several presets, enabling different features. Currently we always use preset number 20, which includes the AUX electrode. However, for users who don't need the AUX electrode, we can use present number 21, which excludes this electrode.

See this page for more information about the presets.

High incidence of NaNs running in Electron

I've been noticing a high incidence of NaN values in some of the experimental data collected in the BrainWave app.

One of the most recent experiments collected on OSX has NaNs throughout the entire dataset.
NaNDataset.zip

I'll back when I get to the bottom of this. My suspicion is that this might be a web bluetooth specific issue

Sample rate and chunk size

I'm getting data each 460ms. and 12 readings per electrode.

Is there a way to decrease the sample rate or increment the 12 readings?

Support for 2014 Muse hardware?

I have a muse 2014 headset and would love to get it working with Node. Can someone point me in the right direction of how to add support for it? Are there any technical limitations I should be aware of?

Protocol Advice

Is anyone discussing how to code for these devices anywhere? Would this wiki be a place?

I'm trying to manually access my Muse S and I keep getting access error reading from the gatt data, or trying to bond. What am I missing?

Reconnection

Hi!
My friend @Th4n05 and I have worked with Muse2016 and your packet for a few month. Sometimes Muse disconnect during the acquisition. We know that Muse is a strange stuff but when it disconnect we want that it reconnect automatically. You could say 'you can do it, create a new MuseClient or something else'. We don't know why but after reconnection the EEG stream don't work.
@Th4n05 understands that if we remove takeUntil() in muse-utils.js the problem is resolved but we don't understand why this happens also when we create a new MuseClient instance.

Do you have any ideas?

Raw EEG processing

Raw EEG is cool, but FFT'ed absolute readings are more practical.. I'm not sure if it should be included in this package, or via external dependency (eeg-processing.js and eeg-algorithms.js), but I'm adding this issue here as placeholder because the need is real.

Looking at muse-io - Muse Elements Data for couple of processed streams that would be great to mirror:
/muse/elements/*_absolute (relative are easy to calculate from these)
/muse/elements/horseshoe ffff, /muse/elements/is_good iiii
Muscle Movement: /muse/elements/blink i, /muse/elements/jaw_clench i

Your package has a potential to solve a big problem, as muse left the 2016 headset without muse-io, nor a normal desktop SDK (no mac/linux, win10 UWP sucks..) your solution is better for developers who need to package client-apps, and not simply run single-machine research.

Thanks!

Where did you get information?

I need information on Muse 2 Headband Bluetooth protocol. How did you get this information on the Muse? Can you help me?

Not getting any eeg data.

Hi,

Following your demo I was trying to connect my Muse device in my implementation.

I can see the I can connect to device as I can reach this line of code, also I get the message Connected to Device name: Muse-7144 and then Client Started! which is here.

But after that I don't get any thing, I wear my device and I have tested it with other implementations like eeg-explorer and it works pretty good.

Not sure what is going wrong here.

Any help ??

question about unsubscribing

Hey,

Not an issue, just a question. I've noticed the Client doesn't have an "unsubscribe" function - is that automatic on disconnect()? I ask because I'm going to be using it in an office setting, so I want to make certain Person A's dataset doesn't accidentally get mixed with Person N's.

Connect issue breaks web software with Muse 2016 - Edit

on eegedu.com
when I try to connect to a muse 2016 ** (edit) with
await window.source.connect();
I get
Connection error: NotFoundError: No Characteristics matching UUID 273e000b-4c4d-454d-96be-f03bac821358 found in Service with UUID 0000fe8d-0000-1000-8000-00805f9b34fb.
and cannot connect

This does not occur when using a newer muse-S.

How to integrate with LSL?

Thank you Urish for this really amazing project.
I have a project that is using LSL and wondering how to make RxJS data stream visible to LSL?

Cheers

What type of window does muse js use?

What type of window does muse js use?

For example there are these windows

Window types:

boxcar

triang

blackman

hamming

hann

bartlett

flattop

parzen

bohman

blackmanharris

nuttall

barthann

kaiser (needs beta)

gaussian (needs standard deviation)

general_gaussian (needs power, width)

slepian (needs width)

dpss (needs normalized half-bandwidth)

chebwin (needs attenuation)

exponential (needs decay scale)

tukey (needs taper fraction)

Simultaneous EEG / PPG and zipping samples

I run into some strange behaviour trying to plot EEG and PPG simultaneously. I'm using a Muse-S.

Below I added the basic code to reproduce the behaviour. Connect to the muse and then subscribe to both the zipped Observables.

try {         
         this.muse.enablePpg = true;
         await this.muse.connect();
         await this.muse.start();     
         await this.muse.deviceInfo();  
         zipSamples(this.muse.eegReadings).subscribe(console.log); 
         zipSamplesPpg(this.muse.ppgReadings).subscribe(console.log);     
        } catch (err) {
         window.alert(err.toString());
         this.connectionError.next('Connection failed: ' + err.toString());  
       } finally {
         this.connecting.next(false);
       }    
  • This logs the zipped eegSamples to the console, but it does not print out the zipped ppg values. It only prints out 6 of the zipped ppgSamples on disconnection.
  • When not subscribing to eeg, but only to ppg, it does print the zipped ppgSamples to console like expected.
  • The zipped EegSamples always get printed to the console, regardless of the subscription to the ppg observable.
  • When not zipping any of the sample Observables with the zipSamples / zipSamplesPpg pipe, it does print the readings (unzipped) for both.

I hope the issue is clear, it's quite hard to describe. I suspect a bug in the zipSamplesPpg, but I can't seem to figure out how to fix it.

Support muse 2

Does muse-js support the new version of Muse (aka Muse 2)?

Unable to connect on Windows 10

Working on a Microsoft Surface Pro 3 running windows 10 with the Creators update and can't seem to get the web bluetooth to find the muse in my vicinity.

I added the Web Bluetooth Polyfill successfully but that doesn't seem to make a difference

The SP3 does seem to support Bluetooth LE but there might be an issue with how the driver works with Windows 10. I've ordered the ASUS BT400 adapter and will try that next but was wondering if there were any other suggestions to get this working.

semi off-topic: MUSE USB COM PORT

I have noticed on my Muse (2016), that when I connect it to my PC using USB, a COM port appears.
Typing "h" or "v" i get some strings back.
I wonder what else is possible to do using the USB port directly.

Connect Muse on Mac OS 10.14.5

OS: Mac OS 10.14.5
Node: 12.4

I used the Node.js example:

const noble = require('noble');
const bluetooth = require('bleat').webbluetooth;
const { MUSE_SERVICE, MuseClient } = require('muse-js');

async function connect() {
    let device = await bluetooth.requestDevice({
        filters: [{ services: [MUSE_SERVICE] }]
    });
    const gatt = await device.gatt.connect();
    const client = new MuseClient();
    await client.connect(gatt);
    await client.start();
    // Now do whatever with muse client...
    client.eventMarkers.subscribe((event) => {
        console.log(event);
    });
}

noble.on('stateChange', (state) => {
    if (state === 'poweredOn') {
        connect();
    }
});

The headset is switched on. Are there any prerequisites:

  • Do I need to connect it first to my MAC, it's not available in the Bluetooth settings, or will this be done through the app?
  • I opened http://localhost:4445/ (but I guess this is just for running it in the browser, right?)
  • Do I need the Mac OS SDK? The SDK seems to be deprecated and not available anymore: https://choosemuse.com/development/

I get the err after stating my index.js:

(node:29173) UnhandledPromiseRejectionWarning: requestDevice error: no devices found
(node:29173) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:29173) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

PS: I changed the package from xpc-connection to xpc-connect in noble because xpc-connection was deprecated.

Add `injectMarker` function

In order to perform ERP experiments with Muse js, event markers corresponding to stimulus presentation onset will have to be added to the stream of EEG data with as much temporal accuracy as possible.

Emotiv includes this feature in their API: an injectMarker function that allows you to add an event annotation included in EEG data stream based on a label and timestamp passed to it.

To make my app compatible with both devices I plan on adding this feature to muse-js over the next few weeks. Off the top of my head I think adding a new eventMarkers Observable that can be triggered imperatively with a Subject and then merged with the EEG data at some point should be able to do this

Handle bootloader connection issue

Just noticed that muse-js is running into a similar issue that Muse LSL did before this PR: alexandrebarachant/muse-lsl#37

When a headband is charged from empty all the way to full, it will often go into a different preset mode ('bootloader') and require a 'reset to headset mode' command (0x03 2a 31 0a) before it's BLE characteristics are made available for connection.

Attempting to connect to the headset in this mode leads to the following error:
No Characteristics matching UUID 273e000b-4c4d-454d-96be-f03bac821358 found in Service with UUID 0000fe8d-0000-1000-8000-00805f9b34fb.

I suggest that we add a getDeviceInfo check to the connect function and handle a 'bootloader' device state by sending a reset command with the sendCommand function

Muse S optical sensor support

Hey @urish can I open this one back up and suggest a feature I can help with to expose the PPG data in the Muse 2 and Muse S headbands.

based on the address of the data in the raw packets here:
#42 (comment)

I think the main parsing of the data files happens here:
https://github.com/urish/muse-js/blob/master/src/muse.spec.ts

I believe a function would be needed here to parse the data, and define data types in another file:
https://github.com/urish/muse-js/blob/master/src/lib/muse-parse.ts

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.