BrainBit for developers Subscribe for updates Visit website

BrainBit 2 Devices

The BrainBit2 class is designed to work with several device families: BrainBit (new), BrainBit Pro, BrainBit Flex (new), BrainBit Flex Pro. All devices have a sampling frequency of 250Hz. All devices can work in two modes - signal and resistance separately. These devices have different number of channels - BrainBit, BrainBit Flex have 4 channels each and BrainBit Pro, BrainBit Flex Pro have 8 channels each. The main difference from BrainBit of the first version is that they do not support gain property, but have the ability to set gain for each channel separately using `BrainBit2AmplifierParam` structure. Also, devices of this type support the ping command and have an 8-digit serial number.

 

Info about channels

The device can have 4 or 8 channels. The number of channels can be determined as follows:

EEGChannelInfo channelInfs[BRAINBIT2_MAX_CH_COUNT];
int32_t chCnt = BRAINBIT2_MAX_CH_COUNT;
OpStatus st;
readSupportedChannelsBrainBit2(sensor, channelInfs, &chCnt, &st);
            
List<EEGChannelInfo> channels = sensor.getSupportedChannels();
            
var channels: List<EEGChannelInfo> = sens.supportedChannels
            
IReadOnlyList<EEGChannelInfo> channels = sensor.SupportedChannelsBrainBit2;
            
let channels: Array<EEGChannelInfo> = sensor.getSupportedChannels()
            
channels = sensor.supported_channels
            
var channels: [NTEEGChannelInfo]? = sensor?.supportedChannels
            
NSArray<NTEEGChannelInfo *>* channels = sensor.SupportedChannels;
            
List<EEGChannelInfo?> channels = await sensor.supportedChannels.value;
            

            

 

`EEGChannelInfo` contains some info:

| Field | Type | Description |
|--|--|--|
|Id|EEGChannelId|physical location of the channel. You will receive the values `O1`, `O2`, `T3`, `T4` or `Unknown`. `Unknown` means that the position of a specific electrode is free.|
|ChType|EEGChannelType|type of channel, possible values `A1`, `A2`, `Differential` or `Referent`|
|Name|char[SENSOR_CHANNEL_NAME_LEN]|channel name|
|Num|uint8_t|channel number. By this number the channel will be located in the array of signal or resistance values|
            
| Field | Type | Description |
|--|--|--|
|Id|EEGChannelId|physical location of the channel. You will receive the values `O1`, `O2`, `T3`, `T4` or `Unknown`. `Unknown` means that the position of a specific electrode is free.|
|ChType|EEGChannelType|type of channel, possible values `A1`, `A2`, `Differential` or `Referent`|
|Name|String|channel name|
|Num|short|channel number. By this number the channel will be located in the array of signal or resistance values|
            
| Field | Type | Description |
|--|--|--|
|Id|EEGChannelId!|physical location of the channel. You will receive the values `O1`, `O2`, `T3`, `T4` or `Unknown`. `Unknown` means that the position of a specific electrode is free.|
|ChType|EEGChannelType!|type of channel, possible values `A1`, `A2`, `Differential` or `Referent`|
|Name|String!|channel name|
|Num|Short|channel number. By this number the channel will be located in the array of signal or resistance values|
            
| Field | Type | Description |
|--|--|--|
|Id|EEGChannelId|physical location of the channel. You will receive the values `O1`, `O2`, `T3`, `T4` or `Unknown`. `Unknown` means that the position of a specific electrode is free.|
|ChType|EEGChannelType|type of channel, possible values `A1`, `A2`, `Differential` or `Referent`|
|Name|string|channel name|
|Num|byte|channel number. By this number the channel will be located in the array of signal or resistance values|
            
| Field | Type | Description |
|--|--|--|
|Id|EEGChannelId|physical location of the channel. You will receive the values `O1`, `O2`, `T3`, `T4` or `Unknown`. `Unknown` means that the position of a specific electrode is free.|
|ChType|EEGChannelType|type of channel, possible values `A1`, `A2`, `Differential` or `Referent`|
|Name|String|channel name|
|Num|number|channel number. By this number the channel will be located in the array of signal or resistance values|
            
| Field | Type | Description |
|--|--|--|
|Id|EEGChannelId|physical location of the channel. You will receive the values `O1`, `O2`, `T3`, `T4` or `Unknown`. `Unknown` means that the position of a specific electrode is free.|
|ChType|EEGChannelType|type of channel, possible values `A1`, `A2`, `Differential` or `Referent`|
|Name|str|channel name|
|Num|int|channel number. By this number the channel will be located in the array of signal or resistance values|
            
| Field | Type | Description |
|--|--|--|
|id|NTEEGChannelId|physical location of the channel. You will receive the values `O1`, `O2`, `T3`, `T4` or `Unknown`. `Unknown` means that the position of a specific electrode is free.|
|chType|NTEEGChannelType|type of channel, possible values `A1`, `A2`, `Differential` or `Referent`|
|name|String?|channel name|
|num|UInt8?|channel number. By this number the channel will be located in the array of signal or resistance values|
            
| Field | Type | Description |
|--|--|--|
|Id|NTEEGChannelId|physical location of the channel. You will receive the values `O1`, `O2`, `T3`, `T4` or `Unknown`. `Unknown` means that the position of a specific electrode is free.|
|ChType|NTEEGChannelType|type of channel, possible values `A1`, `A2`, `Differential` or `Referent`|
|Name|NSString*_Nonnull|channel name|
|Num|UInt8|channel number. By this number the channel will be located in the array of signal or resistance values|
            
| Field | Type | Description |
|--|--|--|
|id|EEGChannelId|physical location of the channel. You will receive the values `o1`, `o2`, `t3`, `t4` or `unknown`. `unknown` means that the position of a specific electrode is free.|
|chType|EEGChannelType|type of channel, possible values `singleA1`, `singleA2`, `differential` or `ref`|
|name|String|channel name|
|num|int|channel number. By this number the channel will be located in the array of signal or resistance values|
            

            

 

Also you can check only channels count without info:

int32_t chCount = getChannelsCountSensor(sensor);
            
int chCount = sensor.getChannelsCount();
            
val chCount: Int = sensor.channelsCount
            
int chCount = sensor.ChannelsCount;
            
let maxChCount: number = BrainBit2Sensor.getMaxChCount()

let chCount: number = sensor.getChannelsCount()
            
ch_count = sensor.channels_count
            
var channelsCount: NSNumber? = sensor?.channelsCount
            
NSNumber* channelsCount = sensor.ChannelsCount;
            
int channelsCount = await sensor.channelsCount.value;
            

            

 

AmpMode

This device can show it's current amplifier mode. It can be in the following states:

  • Invalid;
  • PowerDown;
  • Idle;
  • Signal;
  • Resist.

You can check Amp. mode by two ways:

1. By callback:

void ampModeStateChanged(Sensor* ptr, SensorAmpMode mode, void* userData)
{
	// check AmpMode
}
...
AmpModeListenerHandle ampModeHandle = nullptr;
OpStatus st;
addAmpModeCallback(sensor, ampModeStateChanged, &ampModeHandle, nullptr, &st);
...
removeAmpModeCallback(ampModeHandle);
            
sensor.sensorAmpModeChanged = mode -> {
    // check AmpMode
};
...
sensor.sensorAmpModeChanged = null;
            
sensor.sensorAmpModeChanged = SensorAmpModeChanged {mode -> 
    // check AmpMode    
}
...
sensor.sensorAmpModeChanged = null
            
private void SensorEventSensorAmpModeChanged(ISensor sensor, SensorAmpMode sensorAmpMode)
{
    Console.Writeline($"AmpMode: {sensorAmpMode}");
}
...
sensor.EventSensorAmpModeChanged += SensorEventSensorAmpModeChanged;
...
sensor.EventSensorAmpModeChanged -= SensorEventSensorAmpModeChanged;
            
sensor.AddAMPModeChanged((ampMode)=>
  { 
    console.info("ampMode: " + ampMode) 
  });
...
sensor.RemoveAMPModeChanged()
            
def on_amp_mode_changed(sensor, mode):
    print('Amp mode: {0}'.format(mode))


sensor.sensorAmpModeChanged = on_amp_mode_changed

sensor.sensorAmpModeChanged = None
            
sensor?.setAmpModeCallback({ mode in
    print("Amp mode \(mode)")
})
...
sensor?.setAmpModeCallback(nil)
            
[sensor setAmpModeCallback:^(NTSensorAmpMode mode) {
    NSLog(@"Amp mode: %@", mode);
}];
...
[sensor setAmpModeCallback:nil];
            
StreamSubscription<SensorAmpMode>? ampModeSubscription = sensor.ampModeStream.listen((mode) => print("Amp mode: $mode"));
...
ampModeSubscription.cancel();
            

            

2. Get value at any time:

SensorAmpMode ampMode;
OpStatus st;
readAmpMode(sensor, &ampMode, &st);
            
SensorAmpMode mode = sensor.getAmpMode();
            
var mode: SensorAmpMode = sensor.ampMode
            
SensorAmpMode ampMode = sensor.AmpMode;
            
var mode: SensorAmpMode = sensor.getAmpMode()
            
mode = sensor.amp_mode
            
var mode: NTSensorAmpMode? = sensor?.ampMode
            
NTSensorAmpMode mode = sensor.AmpMode;
            
SensorAmpMode mode = await sensor.ampMode.value;
            

            

It is very important parameter for BrainBit2 device because you can set amplifier parameters only if device into `PowerDown` or `Idle` mode.

 

Amplifier parameters

You can configure each channel and whole device settings by setting amplifier parameters.

int32_t chCount = getChannelsCountSensor(sensor);
BrainBit2AmplifierParam ampParam;
OpStatus st;
readAmplifierParamBrainBit2(sensor, &ampParam, &st);
for (int32_t i = 0; i < chCount; ++i) {
    ampParam.ChSignalMode[i] = BrainBit2ChannelMode::ChModeNormal;
	ampParam.ChGain[i] = SensorGain::SensorGain3;
    ampParam.ChResistUse[i] = 1;
}
ampParam.Current = GenCurrent::GenCurr6nA;
writeAmplifierParamBrainBit2(sensor, ampParam, &st);
            
BrainBit2AmplifierParam ampParam = sensor.getAmplifierParam();
for (int i = 0; i < sensor.getChannelsCount(); ++i) {
    ampParam.getChSignalMode()[i] = BrainBit2ChannelMode.ChModeNormal;
    ampParam.getChGain()[i] = SensorGain.Gain3;
    ampParam.getChResistUse()[i] = true;
}
ampParam.setCurrent(GenCurrent.GenCurr6nA);
sensor.setAmplifierParam(ampParam);
            
val ampParam: BrainBit2AmplifierParam = sensor.amplifierParam
for (i in 0 until sensor!!.channelsCount) {
    ampParam.chSignalMode[i] = BrainBit2ChannelMode.ChModeNormal
    ampParam.chGain[i] = SensorGain.Gain3
    ampParam.chResistUse[i] = true
}
ampParam.current = GenCurrent.GenCurr6nA
sensor.amplifierParam = ampParam
            
BrainBit2AmplifierParam ampParam = sensor.AmplifierParamBrainBit2;
for (int i = 0; i < ampParam.ChSignalMode.Length; ++i)
{
    ampParam.ChSignalMode[i] = BrainBit2ChannelMode.ChModeNormal;
    ampParam.ChGain[i] = SensorGain.SensorGain3;
    ampParam.ChResistUse[i] = true;
}
ampParam.Current = GenCurrent.GenCurr6nA;
sensor.AmplifierParamBrainBit2 = ampParam;
            
let chCount = sensor.getChannelsCount();

let ampParam: BrainBit2AmplifierParam = {
  Current: GenCurrent.GenCurr6nA,
  ChSignalMode: Array(chCount).fill(BrainBit2ChannelMode.ChModeNormal),
  ChResistUse: Array(chCount).fill(true),
  ChGain: Array(chCount).fill(SensorGain.Gain3),
};
sensor.setAmplifierParam(ampParam)
            
ch_count = sensor.channels_count

amp_param = sensor.amplifier_param
amp_param.ChGain = [SensorGain.Gain3 for i in range(ch_count)]
amp_param.ChSignalMode = [BrainBit2ChannelMode.ChModeNormal for i in range(ch_count)]
amp_param.ChResistUse = [True for i in range(ch_count)]
amp_param.Current = GenCurrent.GenCurr6nA
sensor.amplifier_param = amp_param
            
var param: NTBrainBit2AmplifierParam = NTBrainBit2AmplifierParam()
param.chGain = NSMutableArray(array: (0...channelsCount!.intValue).map({ _ in
    NTSensorGain.gain3.rawValue
}))
param.chSignalMode = NSMutableArray(array: (0...channelsCount!.intValue).map({ _ in
    NTBrainBit2ChannelMode.normal.rawValue
}))
param.chResistUse = NSMutableArray(array: (0...channelsCount!.intValue).map({ _ in
    NSNumber(value: true)
}))
param.current = NTGenCurrent.genCurr6nA
sensor?.amplifierParam = param
            
NTBrainBit2AmplifierParam* param = [NTBrainBit2AmplifierParam new];
param.ChGain = [NSMutableArray new];
NSNumber* gain = @(NTSensorGain3);
for(int i = 0; i < channelsCount; i++){
    [param.ChGain addObject:gain];
}
param.ChSignalMode = [NSMutableArray new];
NSNumber* sMode = @(NTBrainBit2ChannelModeNormal);
for(int i = 0; i < channelsCount; i++){
    [param.ChSignalMode addObject:sMode];
}
param.ChResistUse = [NSMutableArray new];
NSNumber* rUse = @(YES);
for(int i = 0; i < channelsCount; i++){
    [param.ChResistUse addObject:rUse];
}
param.Current = NTGenCurrentGenCurr6nA;
sensor.AmplifierParam = param;
            
int chCount = await sensor.channelsCount.value;
BrainBit2AmplifierParam param = BrainBit2AmplifierParam(
    chSignalMode: List.filled(chCount, BrainBit2ChannelMode.chModeNormal),
    chResistUse: List.filled(chCount, true),
    chGain: List.filled(chCount, SensorGain.gain3),
    current: GenCurrent.genCurr6nA);
await sensor.amplifierParam.set(param);
            

            

 

`BrainBit2AmplifierParam` contains:

| Field | Type | Description |
|--|--|--|
|ChSignalMode|BrainBit2ChannelMode[BRAINBIT2_MAX_CH_COUNT]|input type|
|ChResistUse|uint8_t[BRAINBIT2_MAX_CH_COUNT]|dont used for current version|
|ChGain|SensorGain[BRAINBIT2_MAX_CH_COUNT]|gain of an ADC signal for each channel|
|Current|GenCurrent|setting parameters of the probe current generator|
            
| Field | Type | Description |
|--|--|--|
|ChSignalMode|BrainBit2ChannelMode[]|input type|
|ChResistUse|boolean[]|dont used for current version|
|ChGain|SensorGain[]|gain of an ADC signal for each channel|
|Current|GenCurrent|setting parameters of the probe current generator|
            
| Field | Type | Description |
|--|--|--|
|ChSignalMode|Array<BrainBit2ChannelMode>|input type|
|ChResistUse|BooleanArray|dont used for current version|
|ChGain|Array<SensorGain>|gain of an ADC signal for each channel|
|Current|GenCurrent!|setting parameters of the probe current generator|
            
| Field | Type | Description |
|--|--|--|
|ChSignalMode|BrainBit2ChannelMode[]|input type|
|ChResistUse|bool[]|dont used for current version|
|ChGain|SensorGain[]|gain of an ADC signal for each channel|
|Current|GenCurrent|setting parameters of the probe current generator|
            
| Field | Type | Description |
|--|--|--|
|ChSignalMode|Array<BrainBit2ChannelMode>|input type|
|ChResistUse| Array<boolean>|dont used for current version|
|ChGain|Array<SensorGain>|gain of an ADC signal for each channel|
|Current|GenCurrent|setting parameters of the probe current generator|
            
| Field | Type | Description |
|--|--|--|
|ChSignalMode|[BrainBit2ChannelMode]|input type|
|ChResistUse| [bool]|dont used for current version|
|ChGain|[SensorGain]|gain of an ADC signal for each channel|
|Current|GenCurrent|setting parameters of the probe current generator|
            
| Field | Type | Description |
|--|--|--|
|chSignalMode|NSMutableArray<NSNumber>|input type|
|chResistUse|NSMutableArray<NSNumber>|dont used for current version|
|chGain|NSMutableArray<NSNumber>|gain of an ADC signal for each channel|
|current|NTGenCurrent|setting parameters of the probe current generator|
            
| Field | Type | Description |
|--|--|--|
|ChSignalMode|NSMutableArray<NSNumber*>* _Nonnull|input type|
|ChResistUse|NSMutableArray<NSNumber*>* _Nonnull|dont used for current version|
|ChGain|NSMutableArray<NSNumber*>* _Nonnull|gain of an ADC signal for each channel|
|Current|enum NTGenCurrent|setting parameters of the probe current generator|
            
| Field | Type | Description |
|--|--|--|
|chSignalMode|List<BrainBit2ChannelMode>|input type|
|chResistUse|List<bool>|dont used for current version|
|chGain|List<SensorGain>|gain of an ADC signal for each channel|
|current|GenCurrent|setting parameters of the probe current generator|
            

            

 

Current

Possible values for `Current`:
- 0 nA
- 6 nA
- 12 nA
- 18 nA
- 24 nA

 

Signal modes

- Short - shorted input
- Normal - bipolar input mode (used for EEG)

 

Gain

Possible `Gain` values:
- 1
- 2
- 3
- 4
- 6
- 8
- 12

 

 

Ping signal

BrainBit2 devices support signal quality check functions using signal ping. You can send a specific value (marker) to the device and it will return that marker with the next signal data packet. Marker is small value one byte in size.

OpStatus outStatus;
pingNeuroSmart(sensor, 5, &outStatus);
            
sensor.pingNeuroSmart(5);
            
sensor.pingNeuroSmart(5)
            
sensor.PingNeuroSmart(5);
            
sensor.PingNeuroSmart(5)
            
sensor.ping_neuro_smart(5)
            
sensor?.pingNeuroSmart(5)
            
[sensor PingNeuroSmart:5];
            
await sensor.pingNeuroSmart(5);
            

            

 

 

Receiving signal

To receive signal data, you need to subscribe to the corresponding callback. The values come in volts. In order for the device to start transmitting data, you need to start a signal using the `execute` command.

This method is also recommended to be run in an separate thread.

void signalBrainBit2Callback(Sensor* ptr, SignalChannelsData* data, int32_t szData, void* userData)
{
	// process data
}
...
BrainBit2SignalDataListenerHandle signalHandle = nullptr;
OpStatus st;
addSignalCallbackBrainBit2(sensor, signalBrainBit2Callback, &signalHandle, nullptr, &st);
execCommandSensor(sensor, SensorCommand::CommandStartSignal, &st);
...
removeSignalCallbackBrainBit2(signalHandle);
execCommandSensor(sensor, SensorCommand::CommandStopSignal, &st);
            
sensor.signalDataReceived = data ->{
    // process data
};
sensor.execCommand(SensorCommand.StartSignal);
...
sensor.signalDataReceived = null
sensor.execCommand(SensorCommand.StopSignal);
            
sensor.signalDataReceived = BrainBit2SignalDataReceived { data ->
    // process data
}
sensor.execCommand(SensorCommand.StartSignal)
...
sensor.signalDataReceived = null
sensor.execCommand(SensorCommand.StopSignal)
            
private static void SensorEventBrainBit2SignalDataRecived(ISensor sensor, SignalChannelsData[] data)
{
    foreach (var it in data)
    {
        Console.WriteLine($"[{it.PackNum}][{it.Marker}][{it.Samples[0]}][{it.Samples[1]}][{it.Samples[2]}][{it.Samples[3]}]");
    }
}
...
sensor.EventBrainBit2SignalDataRecived += SensorEventBrainBit2SignalDataRecived;
sensor.ExecCommand(SensorCommand.CommandStartSignal);
...
sensor.EventBrainBit2SignalDataRecived -= SensorEventBrainBit2SignalDataRecived;
sensor.ExecCommand(SensorCommand.CommandStopSignal);
            
sensor.AddSignalReceived((data)=>{
    console.log(data)
}); 
sensor.execute(SensorCommand.StartSignal)
...
sensor.RemoveSignalReceived();
sensor.execute(SensorCommand.StopSignal)
            
def on_signal_data_received(sensor, data):
    print(data)


sensor.signalDataReceived = on_signal_data_received
sensor.exec_command(SensorCommand.StartSignal)
...
sensor.signalDataReceived = None
sensor.exec_command(SensorCommand.StopSignal)
            
sensor?.setSignalDataCallback({ data in
    //process data
})
sensor?.execCommand(.startSignal)
...
sensor?.setSignalDataCallback(nil)
sensor?.execCommand(.stopSignal)]
            
[sensor setSignalDataCallback:^(NSArray<NTSignalChannelsData *> * _Nonnull data) {
    // process data
}];
[sensor ExecCommand:NTSensorCommandStartSignal];
...
[sensor setSignalDataCallback:nil];
[sensor ExecCommand:NTSensorCommandStopSignal];
            
StreamSubscription<List<SignalChannelsData>>? signalSubscription = sensor.signalDataStream.listen((data) => print("Signal values: $data"));
await sensor.execute(SensorCommand.startSignal);
...
signalSubscription.cancel();
await sensor.execute(SensorCommand.stopSignal);
            

            

You get signal values as a list of samples (`SignalChannelsData`), each containing:

| Field | Type | Description |
|--|--|--|
|PackNum|uint32_t|number for each packet|
|Marker|uint8_t|marker of sample|
|SzSamples|uint32_t|samples count|
|Samples|double*|array of samples in V. Each sample number into array consistent with `Num` value of [EEGChannelInfo](#info-about-channels) from `getSupportedChannels()` method.|
            
| Field | Type | Description |
|--|--|--|
|PackNum|int|number for each packet|
|Marker|short|marker of sample|
|Samples|double[]|array of samples in V. Each sample number into array consistent with `Num` value of [EEGChannelInfo](#info-about-channels) from `getSupportedChannels()` method.|
            
| Field | Type | Description |
|--|--|--|
|PackNum|Int|number for each packet|
|Marker|Short|marker of sample|
|Samples|DoubleArray|array of samples in V. Each sample number into array consistent with `Num` value of [EEGChannelInfo](#info-about-channels) from `getSupportedChannels()` method.|
            
| Field | Type | Description |
|--|--|--|
|PackNum|uint|number for each packet|
|Marker|byte|marker of sample|
|Samples|double[]|array of samples in V. Each sample number into array consistent with `Num` value of [EEGChannelInfo](#info-about-channels) from `getSupportedChannels()` method.|
            
| Field | Type | Description |
|--|--|--|
|PackNum|number|number for each packet|
|Marker|number|marker of sample|
|Samples|Array<number>|array of samples in V. Each sample number into array consistent with `Num` value of [EEGChannelInfo](#info-about-channels) from `getSupportedChannels()` method.|
            
| Field | Type | Description |
|--|--|--|
|PackNum|int|number for each packet|
|Marker|int|marker of sample|
|Samples|[float]|array of samples in V. Each sample number into array consistent with `Num` value of [EEGChannelInfo](#info-about-channels) from `getSupportedChannels()` method.|
            
| Field | Type | Description |
|--|--|--|
|packNum|UInt32?|number for each packet|
|marker|UInt8?|marker of sample|
|samples|[NSNumber]|array of samples in V. Each sample number into array consistent with `Num` value of [EEGChannelInfo](#info-about-channels) from `getSupportedChannels()` method.|
            
| Field | Type | Description |
|--|--|--|
|PackNum|UInt32|number for each packet|
|Marker|UInt8|marker of sample|
|Samples|NSArray<NSNumber*>* _Nonnull|array of samples in V. Each sample number into array consistent with `Num` value of [EEGChannelInfo](#info-about-channels) from `getSupportedChannels()` method.|
            
|--|--|--|
|packNum|int|number for each packet|
|marker|int|marker of sample|
|samples|List<double>|array of samples in V. Each sample number into array consistent with `num` value of [EEGChannelInfo](#info-about-channels) from `supportedChannels` field.|
            

            

 

Receiving resistance

BrainBit2 also allow you to get resistance values. With their help, you can determine the quality of the electrodes to the skin. Initial resistance values are infinity. The values change when the device is on the head.

void resistBrainBit2Callback(Sensor* ptr, ResistRefChannelsData* data, int32_t szData, void* userData)
{
	// process resistance
}
...
BrainBit2ResistDataListenerHandle resistHandle = nullptr;
OpStatus st;
addResistCallbackBrainBit2(sensor, resistBrainBit2Callback, &resistHandle, nullptr, &st);
execCommandSensor(sensor, SensorCommand::CommandStartResist, &st);
...
removeResistCallbackBrainBit2(resistHandle);
execCommandSensor(sensor, SensorCommand::CommandStopResist, &st);
            
sensor.resistDataReceived = data ->{
    // process data
};
sensor.execCommand(SensorCommand.StartResist);
...
sensor.resistDataReceived = null
sensor.execCommand(SensorCommand.StopResist);
            
sensor.resistDataReceived = BrainBit2ResistDataReceived { data ->
    // process data
}
sensor.execCommand(SensorCommand.StartResist)
...
sensor.resistDataReceived = null
sensor.execCommand(SensorCommand.StopResist)
            
private static void SensorEventBrainBit2ResistDataRecived(ISensor sensor, ResistRefChannelsData[] data)
{
    if (data.Length < 1) return;
    ResistRefChannelsData lastData = data[data.Length - 1];
    Console.WriteLine($"0: {lastData.Samples[0]} 1: {lastData.Samples[1]} 2: {lastData.Samples[2]} 3: {lastData.Samples[3]}");
}
...
sensor.EventBrainBit2ResistDataRecived += SensorEventBrainBit2ResistDataRecived;
sensor.ExecCommand(SensorCommand.CommandStartResist);
...
sensor.EventBrainBit2ResistDataRecived -= SensorEventBrainBit2ResistDataRecived;
sensor.ExecCommand(SensorCommand.CommandStopResist);
            
sensor.AddResistanceReceived((data)=>{
    console.log(data)
}); 
sensor.execute(SensorCommand.StartResist)
...
sensor.RemoveResistanceReceived();
sensor.execute(SensorCommand.StopResist)
            
def on_resist_data_received(sensor, data):
    print(data)


sensor.resistDataReceived = on_resist_data_received
sensor.exec_command(SensorCommand.StartResist)
...
sensor.resistDataReceived = None
sensor.exec_command(SensorCommand.StopResist)
            
sensor?.setResistCallback({ data in
    //process data
})
sensor?.execCommand(.startResist)
...
sensor?.setResistCallback(nil)
sensor?.execCommand(.stopResist)]
            
[sensor setResistDataCallback:^(NSArray<NTResistRefChannelsData*>*_Nonnull resists) {
    // process data
}];
[sensor ExecCommand:NTSensorCommandStartResist];
...
[sensor setResistDataCallback:nil];
[sensor ExecCommand:NTSensorCommandStopResist];
            
StreamSubscription<List<ResistRefChannelsData>>? resistSubscription = sensor.resistDataStream.listen((data) => print("resist values: $data"));
await sensor.execute(SensorCommand.startResist);
...
resistSubscription.cancel();
await sensor.execute(SensorCommand.stopResist);
            

            

 

You can get resistance values structure of samples (`ResistRefChannelsData`) for each channel:

| Field | Type | Description |
|--|--|--|
|PackNum|uint32_t|number for each packet|
|SzSamples|uint32_t|samples count|
|SzReferents|uint32_t|referents count|
|Samples|double*|array of samples in V. Each sample number into array consistent with `Num` value of [EEGChannelInfo](#info-about-channels) from `SupportedChannels` property.|
|Referents|double*|array of values for referents channels. For BrainBit2 sensor is empty now.|
            
| Field | Type | Description |
|--|--|--|
|PackNum|int|number for each packet|
|Samples|double[]|array of samples in V. Each sample number into array consistent with `Num` value of [EEGChannelInfo](#info-about-channels) from `getSupportedChannels()` method.|
|Referents|double[]|array of values for referents channels. For BrainBit2 sensor is empty now.|
            
| Field | Type | Description |
|--|--|--|
|PackNum|Int|number for each packet|
|Samples|DoubleArray|array of samples in V. Each sample number into array consistent with `Num` value of [EEGChannelInfo](#info-about-channels) from `getSupportedChannels()` method.|
|Referents|DoubleArray|array of values for referents channels. For BrainBit2 sensor is empty now.|
            
| Field | Type | Description |
|--|--|--|
|PackNum|uint|number for each packet|
|Samples|double[]|array of samples in V. Each sample number into array consistent with `Num` value of [EEGChannelInfo](#info-about-channels) from `SupportedChannelsBrainBit2` property.|
|Referents|double[]|array of values for referents channels. For BrainBit2 sensor is empty now.|
            
| Field | Type | Description |
|--|--|--|
|PackNum|number|number for each packet|
|Samples|Array<number>|array of samples in V. Each sample number into array consistent with `Num` value of [EEGChannelInfo](#info-about-channels) from `getSupportedChannels()` method.|
|Referents|Array<number>|array of values for referents channels. For BrainBit2 sensor is empty now.|
            
| Field | Type | Description |
|--|--|--|
|PackNum|int|number for each packet|
|Samples|[float]|array of samples in V. Each sample number into array consistent with `Num` value of [EEGChannelInfo](#info-about-channels) from `getSupportedChannels()` method.|
|Referents|[float]|array of values for referents channels. For BrainBit2 sensor is empty now.|
            
| Field | Type | Description |
|--|--|--|
|packNum|UInt32?|number for each packet|
|samples|NSMutableArray<NSNumber>|array of samples in V. Each sample number into array consistent with `Num` value of [EEGChannelInfo](#info-about-channels) from `getSupportedChannels()` method.|
|referents|NSMutableArray<NSNumber>|array of values for referents channels. For BrainBit2 sensor is empty now.|
            
| Field | Type | Description |
|--|--|--|
|PackNum|UInt32|number for each packet|
|Samples|NSMutableArray<NSNumber*>* _Nonnull|array of samples in V. Each sample number into array consistent with `Num` value of [EEGChannelInfo](#info-about-channels) from `getSupportedChannels()` method.|
|Referents|NSMutableArray<NSNumber*>* _Nonnull|array of values for referents channels. For BrainBit2 sensor is empty now.|
            
| Field | Type | Description |
|--|--|--|
|packNum|int|number for each packet|
|samples|List<double>|array of samples in V. Each sample number into array consistent with `Num` value of [EEGChannelInfo](#info-about-channels) from `supportedChannels` field.|
|referents|List<double>|array of values for referents channels. For BrainBit2 sensor is empty now.|