Table of Contents for MetroEEG Introduction

Getting Started

1. Start a new WP8 project in VS2012, download the release DLL and add a reference to it.

2. Open up the WmAppManifest.xml file in your project, and under the "Capabilities" tag add the IDCAPPROXIMITY capability which is used for Bluetooth.
<Capability Name="ID_CAP_PROXIMITY" />
3. Make sure your Mindwave Mobile Headset is on, the phone's Bluetooth is on and both are paired.

4 Add the following code snippet which will start the connection with the Mindwave Mobile headset and print out the readings.
    private void MainPage_Loaded(object sender, RoutedEventArgs e)
    {
        if (!Mindwave.Current.IsConnected)
        {
            Mindwave.Current.CurrentValueChanged += Current_CurrentValueChanged;
            Mindwave.Current.Start();
        }
    }

    private void Current_CurrentValueChanged(object sender, MindwaveReadingEventArgs e)
    {
        Debug.WriteLine(e.SensorReading.ToString());
    }
5. Change the application to deploy to a "Device" (and not an emulator) and see the following output:
2012-09-24_14-38-49.png

Mindwave Reading: EEG Bands

Once activated the Mindwave class will report every second on multiple pieces of data. The majority of those items are brainwave EEG reading in the following wavelengths.
Brainwave Type Frequency range Mental states and conditions MindwaveReading property
Delta 0.5Hz to 2.75Hz Deep, dreamless sleep, non-REM sleep, unconscious Delta
Theta 3.5Hz to 6.75Hz Intuitive, creative, recall, fantasy, imaginary, dream Theta
Low Alpha 7.5Hz to 9.25Hz Relaxed, but not drowsy, tranquil, conscious AlphaLow
High Alpha 10Hz to 11.75Hz Formerly SMR, relaxed yet focused, integrated AlphaHigh
Low Beta 13Hz to 16.75Hz Thinking, aware of self & surroundings BetaLow
High Beta 18Hz to 29.75Hz Alertness, agitation BetaHigh
Low Gamma 31Hz to 39.75Hz Motor Functions, higher mental activity GammaLow
Midrange Gamma 41Hz to 49.75Hz Motor Functions, higher mental activity GammaMid

The values of these properties aren't measured in absolute Hz/sec units. Power spectrum bands values are computed using are computed using FFT distribution and cannot be reversed back to Hz/sec. Because of that these values are only useful when comparing them against previous or future measurements of the same property. For more on wavelengths see the documentation at Brain Wave Signal (EEG) of NueroSky and MindSet Communications Protocol.

We can print out these readings to the screen by using simple DataBinding.
    private void Current_CurrentValueChanged(object sender, MindwaveReadingEventArgs e)
    {
        this.DataContext = e.SensorReading;
    }
    <StackPanel>
        <TextBlock Text="{Binding Delta}" />
        <TextBlock Text="{Binding Theta}" />
        <TextBlock Text="{Binding AlphaLow}" />
        <TextBlock Text="{Binding AlphaHigh}" />
        <TextBlock Text="{Binding BetaLow}" />
        <TextBlock Text="{Binding BetaHigh}" />
        <TextBlock Text="{Binding GammaLow}" />
        <TextBlock Text="{Binding GammaMid}" />
    </StackPanel>
When we run this code snippet we can see the following print out:
Printout.png

We can even class up the example a bit add some nicer XAML around it.
Lumia920Yellow_TextData_small.png

Mindwave Reading: eSense

Besides raw EEG reading, the Mindwave Mobile Headset provides two additional values. Using a trademarked and private algorithm the Mindwave headset calculates how calm ("Attention") and how relaxed ("Meditation") is the wearer. For more information on this algorithm see NeuroSky’s eSense™ Meters and Detection of Mental State and Mindset Communication Protocol.

We can read out the computed values for MindwaveReading.eSenseAttention and MindwaveReading.eSenseMeditation with each Mindwave Sensor reading. The values range between 0 and 100. Anything between 40 to 60 is considered "neutral", values between 60 and 80 are considered "slightly elevated" and values between 80 to 100 are considered "elevated". Elevated values indicate a higher value of that eSense. In practice, most of NeuroSky's apps use 70 as the Boolean minimum to determine if an eSense is on or off.
    private void Current_CurrentValueChanged(object sender, MindwaveReadingEventArgs e)
    {
        this.DataContext = e.SensorReading;
        txtIsAttentionOn.Text = e.SensorReading.eSenseAttention => 70 ? "Yes" : "No";
        txtIsMeditationOn.Text = e.SensorReading.eSenseMeditation >= 70 ? "Yes" : "No";
    }
    <StackPanel>
        <TextBlock Text="{Binding eSenseAttention}" />
        <TextBlock Text="{Binding eSenseMeditation}" />
        <TextBlock x:Name="txtIsAttentionOn" />
        <TextBlock x:Name="txtIsMeditationOn" />
    </StackPanel>
When we run this code snippet on a device we can see the following:
esensePrintout.png

We can class up the XAML on this how this is displayed and include game-like instructions for users on how to elevate their eSense values.
Lumia920Yellow_Gauges_small.png

Mindwave Reading: Unreliable data

One important thing to remember is that receiving readings from the Headset isn't enough to assure the validity of the data received. Each MindwaveReading has a Quality property that denotes the overall quality of the reading. Quality values range between 0 and 200 and the lower the value the more reliable the data. Any data that isn't reliable might be considered junk data.

It's recommended developers always check the Quality property value prior to using any reading.
       private void Current_CurrentValueChanged(object sender, MindwaveReadingEventArgs e)
        {
            if (e.SensorReading.Quality == 0)
            {
                this.DataContext = e.SensorReading;
            }
        }
As a shorthand developers can use IsDataReliable which simply checks if Quality==0.
       private void Current_CurrentValueChanged(object sender, MindwaveReadingEventArgs e)
        {
            if (e.SensorReading.IsDataReliable)
            {
                this.DataContext = e.SensorReading;
            }
        }
As an app developer it's up to you to decide how your app handles faults from the headset. In most apps any value higher then 0 in Quality might denote ignoring the entire reading. Quality property values could be higher then 0 when:
  • Sensor, ground, or reference contacts not being on a person's head (i.e. when nobody is wearing the ThinkGear).
  • Poor contact of the sensor, ground, or reference contacts to a person's skin (i.e. hair in the way, or headset which does not properly ët a person's head, or headset not properly placed on the head).
  • Excessive motion of the wearer (i.e. moving head or body excessively, jostling the headset).
  • Excessive environmental electrostatic noise (some environments have strong electric signals or static electricity buildup in the person wearing the sensor).
  • Excessive non-EEG biometric noise (i.e. EMG, EKG/ECG, EOG, etc)

Connecting, disconnecting and Sensor States

Developers should invoke Mindwave.Start() and Stop() methods depending on when reading from the sensor. When connected to the Mindwave headset there's considerable data processing going on so it's recommended app developers turn off the connection whenever it's not needed.
    private void btnConnect_Click(object sender, RoutedEventArgs e)
    {
        if (!Mindwave.Current.IsConnected)
        {
            Mindwave.Current.Start();
        }
    }

    private void btnDisconnect_Click(object sender, RoutedEventArgs e)
    {
        if (Mindwave.Current.IsConnected)
        {
            Mindwave.Current.Stop();
        }
    }
During the lifecycle of the app the Mindwave sensor will exists in multiple states and it's important you know them:
MindwaveServiceState value When is it seen
NotConnected Default value. Not connected to Mindwave Mobile and no connection was ever attempted. Also used when a connection was successfully established and then successfully disconnected.
Connecting Indicates that a connection is being attempted. PeerFinder is looking for paired devices and attempting to open a socket.
ConnectedWithNoDataYet A Bluetooth Socket has been established but no data has been recieved yet.
ConnectedWithUnreliableData The latest MindwaveReading received has a Quality higher then 0. Expected state in the first few seconds after connecting to the sensor.
ConnectedWithData A connection has been established and reliable data is being received.
FailedConnection A connection was attempted and wasn't successful. Read more on the causes in the next section.
FailedDuringExecution An unexpected error occurred while reading the bluetooth device.


We can track the current state of the Mindwave sensor by listening to the StateChanged event.
    Mindwave.Current.StateChanged += Current_StateChanged;

    private void Current_StateChanged(object sender, MindwaveStateChangedEventArgs e)
    {
        Debug.WriteLine(e.CurrentState);
    }
We can create a small sample page that'll allow us to connect and disconnect from the Mindwave Headset and printout the state in each step.
    <StackPanel>
        <Button x:Name="btnConnect" Content="Connect" Click="btnConnect_Click" />
        <Button x:Name="btnDisconnect" Content="Disconnect" Click="btnDisconnect_Click" />
        <TextBlock Text="Connection State" Margin="12,20,12,0" />
        <ListBox x:Name="lstOutput" Height="400" />
    </StackPanel>
    public partial class ManualConnection : PhoneApplicationPage
    {
        public ManualConnection()
        {
            InitializeComponent();

            lstOutput.Items.Add(Mindwave.Current.State);
        }

        protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
        {
            Mindwave.Current.StateChanged += Current_StateChanged;

            base.OnNavigatedTo(e);
        }

        protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)
        {
            Mindwave.Current.StateChanged -= Current_StateChanged;

            base.OnNavigatedFrom(e);
        }

        void Current_StateChanged(object sender, MindwaveStateChangedEventArgs e)
        {
            lstOutput.Items.Add(e.CurrentState.ToString());
        }

        private void btnConnect_Click(object sender, RoutedEventArgs e)
        {
            Mindwave.Current.Start();
        }

        private void btnDisconnect_Click(object sender, RoutedEventArgs e)
        {
            Mindwave.Current.Stop();
        }
    }
When we run this app, attempt a simple connection and wait, we can see the following states are used in every Mindwave sensor startup.
Lumia920Yellow_Connection_small.png

As a shorthand it's possible to use Mindwave.IsConnected property to determine if a connection is possible or not.
    btnConnect.IsEnabled = !Mindwave.Current.IsConnected;
    btnDisconnect.IsEnabled = Mindwave.Current.IsConnected;

Why could connections fail?

There are multiple known causes as to why the FailedConnection state can occur.
  • Missing Capability: an app without IDCAPPROXIMITY will always fail to open a Bluetooth connection to the Mindwave Mobile headset.
  • Executed in the emulator: The WP8 emulator doesn't support Bluetooth connection.
  • The headset isn't on: Make sure you the headset is close by and turned on.
  • The phone's Bluetooth is off: Make sure the phone's Bluetooth is on.
  • Devices aren't paired: As a rule WP8 apps can only speak to paired devices.

It's recommended developers show a dialogue to users asking them to turn on their headset, the phone's Bluetooth and pair the devices.
Lumia920Yellow_Setup_small.png

Additionally developers can link to the Bluetooth settings page.
        private void btnOpenBluetoothSettings_Click(object sender, RoutedEventArgs e)
        {
            Launcher.LaunchUriAsync(new System.Uri("ms-settings-bluetooth:"));
        }

Custom Drag & Drop Controls

In order to make it easier to get off the ground running with this Mindwave SDK we've created some drag & drop controls that simply need to be positioned on a Page with no C# coding required.
        <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">

        	<Controls:MindwaveConnectionIndicator HorizontalAlignment="Left" Height="62" VerticalAlignment="Top" Width="303" Margin="0,13,0,0"/>
        	<Controls:MindwaveConnectButton HorizontalAlignment="Left" Height="75" Margin="284,0,0,0" VerticalAlignment="Top" Width="172"/>
        	<Controls:MindwaveAttentionProgressBar HorizontalAlignment="Left" Height="230" Margin="0,97,0,0" VerticalAlignment="Top" Width="456"/>
        	<Controls:MindwaveMeditationProgressBar HorizontalAlignment="Left" Height="251" Margin="0,356,0,0" VerticalAlignment="Top" Width="456"/>

        </Grid>

We can see the following view in Visual Studio's / Blend's design view:
2012-09-24_16-49-48.png

And when we run the app we can see the following screen.
Lumia920Yellow_customControls_small.png

The MetroEEG SDK has the following sample controls:
  • MindwaveConnectionIndicator: Has a visual state for each connection status. Developers can override the default display by editing the template of this control.
  • MindwaveConnectButton: Displays "Connect" and "Disconnect" button based on the state of the current Mindwave sensor.
  • MindwaveAttentionProgressBar / MindwaveMeditationProgressBar: Show a progress bar for the eSenses of Attention and Meditation. Includes instructions for users on how to elevate levels for these eSenses. Each custom control also has a visual state whenever the eSense is considered elevated.

Last edited Sep 24, 2012 at 11:53 PM by JustinJosefAngel, version 8

Comments

No comments yet.