Using ShadajL's NeuroSky MindWave Scala library

After hearing about ShadajL’s presentation at Scala Days 2013 using a MindWave headset, I decided to buy a headset to see how if it really works. After a little while I got the hang of using the headset, so I decided to try ShadajL’s NeuroSky Scala library (named neuro-thinkgear) to see how it works as well.

In short, here’s a very small example application that uses ShadajL’s NeuroSky library:

package com.alvinalexander.neurosky

import me.shadaj.neuro.thinkgear.NeuroIterator
import scala.util.{Try, Success, Failure}
import akka.actor.Actor

object Example1 extends App {
  
  val events = new NeuroSkyThread
  events.start()
  
  Thread.sleep(20*1000)
  events.stop
  println("*** STOPPED ***")

}

class NeuroSkyThread extends Thread {

  var waitingForStop = false

  private lazy val neuroskyEventPump: NeuroIterator = {
    Try(new NeuroIterator) match {
      case Success(v) => {
        v
      }

      case Failure(e) => {
        println("Please check that ThinkGearConnector is on.")
        neuroskyEventPump
      }
    }
  }

  override def run {
    while (!waitingForStop) {
      println(neuroskyEventPump.next)
    }
    neuroskyEventPump.neuroSocket.close
    waitingForStop = false
  }
}

As you can infer from the run method of the NeuroSkyThread class, the NeuroIterator object pumps NeuroSky events into the application, where they are printed with this line of code:

println(neuroskyEventPump.next)

The output from a 20-second run is shown below. I blinked twice intentionally at the beginning, then quickly began to meditate:

Blink(86)
EEG(ESense(66,77),EEGPower(176570,150702,64280,64280,53320,33150,3872,3872),PoorSignalLevel(0))
EEG(ESense(64,69),EEGPower(57758,4540,2174,2174,2550,1166,935,935),PoorSignalLevel(0))
EEG(ESense(54,70),EEGPower(368881,165429,37461,37461,28380,21887,5476,5476),PoorSignalLevel(0))
Blink(131)
EEG(ESense(37,80),EEGPower(2129996,214307,130366,130366,21551,13307,7380,7380),PoorSignalLevel(0))
EEG(ESense(35,80),EEGPower(398243,61557,12885,12885,10724,11012,4246,4246),PoorSignalLevel(0))
EEG(ESense(27,88),EEGPower(58193,26093,30148,30148,16701,4846,5113,5113),PoorSignalLevel(0))
EEG(ESense(35,93),EEGPower(1628,14876,15486,15486,12285,6739,4712,4712),PoorSignalLevel(0))
EEG(ESense(50,97),EEGPower(13316,6493,20828,20828,7210,6892,4552,4552),PoorSignalLevel(0))
EEG(ESense(51,100),EEGPower(6928,14636,18796,18796,8410,5020,2114,2114),PoorSignalLevel(0))
EEG(ESense(60,100),EEGPower(3894,5802,15801,15801,7068,5444,2536,2536),PoorSignalLevel(0))
EEG(ESense(57,100),EEGPower(7769,13686,11628,11628,10538,5624,5923,5923),PoorSignalLevel(0))
EEG(ESense(54,100),EEGPower(10192,12344,7455,7455,9885,5054,2981,2981),PoorSignalLevel(0))
EEG(ESense(51,93),EEGPower(1080,35894,4993,4993,9794,5003,3061,3061),PoorSignalLevel(0))
EEG(ESense(47,77),EEGPower(8914,30269,12273,12273,7958,4064,3991,3991),PoorSignalLevel(0))
EEG(ESense(44,77),EEGPower(8711,22480,13762,13762,9857,5154,2694,2694),PoorSignalLevel(0))
EEG(ESense(54,61),EEGPower(10971,14282,8458,8458,14815,9630,3911,3911),PoorSignalLevel(0))
EEG(ESense(64,63),EEGPower(5870,9927,2171,2171,12794,6674,1597,1597),PoorSignalLevel(0))
EEG(ESense(70,67),EEGPower(9976,13520,3404,3404,8064,6565,3918,3918),PoorSignalLevel(0))
EEG(ESense(83,64),EEGPower(12229,6683,4297,4297,12477,9735,2505,2505),PoorSignalLevel(0))
EEG(ESense(75,74),EEGPower(8206,20125,15948,15948,9044,5948,4760,4760),PoorSignalLevel(0))
*** STOPPED ***

Honestly, at this point I don’t know what the ESense, EEGPower, and PoorSignalLevel fields mean, but I just wanted to share some source code here in case anyone else is interested in doing the same thing. My next task is to read the NeuroSky developer docs to see what these fields mean.

Also, I have to say that I don’t know much about the technology behind the MindWave headset device, but I can say that after the first 24 hours of use, it seems at least relatively accurate. I bought this Brainwave Starter Kit, which comes with a free app named Brainwave Visualizer, and I was able to control the Attention and Meditation dials well by either focusing very hard, or meditating. I think there’s a slight lag in the output, but it’s not a big deal. The Blink events are also very accurate.

Of course @ShadajL is doing the hard work here. As I’m just getting started, I’m using his neuro-thinkgear library, with some of the code from his mind-snakey project.