BrainBit foe developers Visit website
Home
SDK
Device

Tutorial Java

Software development kit for Android operating system is represented as Java libraries.

 

Platform requirements

OS: Android 4.3 API 18 or higher

Hardware: Bluetooth v4.0

 

Development requirements

Software: Android Studio 2.3.3 or higher, Download link

 

SDK Install

Used the standard Android project dependency loading mechanism of Gradle.

Core library (required) 

    
implementation 'com.neuromd.neurosdk:neuro-sdk:1.3+'
    

 

Extensions library (optional) 

    
implementation 'com.neuromd.neurosdk:neuro-sdk-ext:1.2+'
    

 

Step-by-step 

  • Create android project with Android Studio:

Create project

 

  • Choose your project - "Emtpty Activity" (for example):

Choose template

  • Configure your project and select API 18 or higher:

Configure your project

  • Open "build.gradle" your app module in "Gradle Scripts":

build.gradle file

  • Add dependency fore core functionality (required):

Core functionality dependency

  • Add dependency fore extended functionality (optional):

Extended functionality dependency

  • In the menu bar go to Build->Make Project to build project or just press Ctrl+F9. Dependencies will loaded automatically:

Start buildSuccessful build

 

Running Java example applications

Your can download example from git.

You can find three examples in "android" directory. To build and run example applications first open one of the example in Android Studio.

  • Open exmaple

  • In the menu bar go to Build->Make Project to build example or just press Ctrl+F9

  •  Click Run or press Shift+F10 to run application

Run example

  •  DeviceInfo example will show you available devices and basic information about your device

 

Preparation to work 

In order to use Bluetooth features in your application, you must declare the Bluetooth permission BLUETOOTH. You need this permission to perform any Bluetooth communication, such as requesting a connection, accepting a connection, and transferring data.

Declare the Bluetooth permissions in your application manifest file

    
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
    


Require permission to use Bluetooth

    
String[] BLE_PERM = (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) ?
        new String[] {Manifest.permission.BLUETOOTH_ADMIN, Manifest.permission.BLUETOOTH, Manifest.permission.ACCESS_COARSE_LOCATION} :
        new String[] {Manifest.permission.BLUETOOTH_ADMIN, Manifest.permission.BLUETOOTH};
ActivityCompat.requestPermissions(this, BLE_PERM, 1);
    

Next step your need to turn on Bluetooth and GPS if the user has confirmed permission.

 

Scanning for devices

To find nearby Brainbit devices use DeviceScanner

    
DeviceScanner mScanner = new DeviceScanner(getApplicationContext());
mScanner.deviceFound.subscribe(new INotificationCallback<Device>() {
            @Override
            public void onNotify(Object o, Device device) {
                onDeviceFound(device);
            }
        });
mScanner.startScan(0); //zero is for infinity
    

onNotify from INotificationCallback event will hit when a new device appears.

 

To get information about are device, use methods from class Device. You could read that every time onNotify event hits.

    
private void onDeviceFound(final Device device) {
        String name = device.readParam(ParameterName.Name);
        String address = device.readParam(ParameterName.Address);
        DeviceState state = device.readParam(ParameterName.State);
        Log.d("[DEV_INFO]", name + " [" + address + "] [" + state + "]");
}
    

 

Connecting to the device 

To receive data from the Brainbit device and to send commands to it first you need to connect to it

    
device.connect();
//Do work
device.disconnect();
    

 

You could read the device state to check whether it is connected or not. You also could subscribe parameterChanged event to receive notifications when the device goes out of range.

    
device.parameterChanged.subscribe(new INotificationCallback<ParameterName>() {
    @Override
    public void onNotify(Object sender, ParameterName nParam) {
        if (nParam == ParameterName.State) {
            DeviceState state = device.readParam(ParameterName.State);
            Log.d("[DEV_STATE]", "[" + state + "]");
        }
    }
});
DeviceState state = device.readParam(ParameterName.State);
if (state == DeviceState.Disconnected) {
    device.connect();
}
    

 

When the device is connected you could read lists of supported parameters, signal channels, available commands. You could read the device name and address in string format and firmware version. 

    
String name = device.readParam(ParameterName.Name);
String address = device.readParam(ParameterName.Address);
FirmwareVersion firmwareVersion = device.readParam(ParameterName.FirmwareVersion);
Log.d("[DEV_INFO]", name + " [" + address + "] [v. " + firmwareVersion.version() + "]");
    

 

To get list of command and channels use appropriate properties.

    
for (Command cmd : device.commands()) {
    Log.d("[DEV_INFO]", "Command: " + cmd);
}
for (ChannelInfo channel : device.channels()) {
    Log.d("[DEV_INFO]", "Channel: " + channel.getType() + "-" + channel.getName());
}
    

 

Retrieving signal data 

For Brainbit device, actual channels are Signal, Battery and Resistance. To get channel records from the device with a specific type, Channel classes could be used. To subscribe for new data notifications Use dataLengthChanged property of Channel classes. There are four commands for managing device measuring state: StartSignal, StopSignal, StartResist, StopResist.

    
final BatteryChannel batteryChannel = new BatteryChannel(device);
batteryChannel.dataLengthChanged.subscribe(new INotificationCallback<Long>() {
    @Override
    public void onNotify(Object dev, Long nParam) {
        onBatteryChargeChanged(device, batteryChannel);
    }
});

for (ChannelInfo channelInfo : device.channels()) {
    if (channelInfo.getType() == ChannelType.Signal) {
        final SignalChannel signalChannel = new SignalChannel(device, channelInfo);
        signalChannel.dataLengthChanged.subscribe(new INotificationCallback<Long>() {
            @Override
            public void onNotify(Object dev, Long nParam) {
                onSignalReceived(device, signalChannel);
            }
        });
    }
}
device.execute(Command.StartSignal);
    

 

Battery data channel contains data as int values, Resistance and Signal channels as double values. Write callback methods to handle new data.

    
private void onBatteryChargeChanged(final Device device, BatteryChannel batteryChannel) {
    Integer batteryCharge = batteryChannel.readData(batteryChannel.totalLength() - 1, 1)[0];
}

private void onSignalReceived(final Device device, SignalChannel signalChannel) {
    Double[] data = signalChannel.readData(signalChannel.totalLength() - 1, 1); // or another size and offset
    // alternative
    // double[] data = signalChannel.readFast(signalChannel.totalLength() - 1, 1); // or another size and offset
}
    

 

To simplify receiving and storing signal data you could use Channel buffer classes. There is a set of different channel buffers in the SDK. One of them is called EegChannel. This buffer receives data from the device and applies special filters to signal to get perfect EEG signal. Pass offset (samples count from buffer start) and length to readData method to get EEG signal.

    
EegChannel eegChannel = new EegChannel(device, channelInfo);
eegChannel.dataLengthChanged.subscribe(new INotificationCallback<Long>() {
    @Override
    public void onNotify(Object sender, Long nParam) {
        //Handle changed data length event
    }
});
long length = eegChannel.totalLength();
Double[] eegData = eegChannel.readData(0, length); //read all data from channel buffer
    

 

You could also use a channel buffer without filters or select filters you need. There are different variants of Signal channel to do it. You could use following filters for Brainbit signals: LowPass_30Hz_SF250, LowPass_30Hz_SF250_Reverse, HighPass_2Hz_SF250, HighPass_2Hz_SF250_Reverse, BandStop_45_55Hz_SF250.

    
//Signal channel without filters
EegChannel eegChannel = new EegChannel(device, channelInfo);

//Signal channel with 50 Hz bandstop filter
Filter[] filters = new Filter[]{Filter.BandStop_45_55Hz_SF250};
SignalChannel signalChannel = new SignalChannel(device, filters, channelInfo);
    

  

Channel buffers collection 

 There is a set of different channel buffers for storing and processing signal data.

    
//Resistance channel. Receives and stores information about the resistance of electrodes
ResistanceChannel resistanceChannel = new ResistanceChannel(device, channelInfo);

//Spectrum channel. Calculates signal spectrum for a selected signal region.
//readData returns array with spectrum samples of length provided in totalLength property
//offset and length parameters relate to source signal channel which was used to make spectrum channel
SpectrumChannel spectrumChannel = new SpectrumChannel(anyDoubleChannel);
double frequencyStep = spectrumChannel.hzPerSpectrumSample();
long totalLength = spectrumChannel.totalLength();