Difference between revisions of "Device (C++)"
NateColeman (talk | contribs) (→Non-member functions) |
NateColeman (talk | contribs) |
||
(11 intermediate revisions by the same user not shown) | |||
Line 3: | Line 3: | ||
Defined in header [https://github.com/NeurotechLtd/neuro-sdk/blob/master/core/include/device/device.h <span style="color:#0033CC;"><device/device.h></span>] | Defined in header [https://github.com/NeurotechLtd/neuro-sdk/blob/master/core/include/device/device.h <span style="color:#0033CC;"><device/device.h></span>] | ||
− | '''<span style="color:#0033CC;">class</span> Device <span style="color:#0033CC;">final</span>'''; | + | '''<span style="font-size:1.3em; line-height:130%"><span style="color:#0033CC;">class</span> Device <span style="color:#0033CC;">final</span></span>'''; |
− | The Device class is an abstraction for NeuroMD BLE devices. This abstraction provides functions for changing of device state by executing commands and setting parameters. Each device have different sets of supported commands and parameters, Device class has functions designed to get information about these sets. | + | The Device class is an abstraction for NeuroMD BLE devices. This abstraction provides functions for changing of device state by executing commands and setting parameters. Each device have different sets of supported commands and parameters, Device class has functions designed to get information about these sets. Callibri and Braibit devices has different parameters sets and provides different ways to access them. Device class hides all differences behind its interface and provides universal way to read and write parameters, execute commands and receive biopotential signals. |
==Member functions== | ==Member functions== | ||
Line 48: | Line 48: | ||
|} | |} | ||
− | + | ==Notes== | |
− | + | In general all parameter read/write operations, command executions and data read operations through channels must be done on connected devices. Only Name, State and Address parameters could be read on a disconnected device. Performing another operations on a disconnected device cause device-dependent behavior. For Callibri device most of operations on disconnected device will cause exception throwing, for Brainbit some read operations may be performed but it is not guaranteed to be stable for all versions of SDK. | |
− | |||
− | |||
− | |||
− | + | ==Example== | |
− | + | This example shows how a to find device, establish connection with it and to list device features | |
− | < | + | <syntaxhighlight lang="c++"> |
− | + | #include <iostream> | |
− | + | #include <vector> | |
+ | #include "device_scanner.h" | ||
+ | #include "device/param_values.h" | ||
− | < | + | std::vector<std::shared_ptr<Neuro::Device>> FoundDevices; |
− | |||
− | |||
− | |||
− | |||
+ | template <typename T> | ||
+ | void displayDeviceFeatures(T&& device_ptr){ | ||
+ | using Neuro::to_string; | ||
− | < | + | std::cout << "Device can execute:" << std::endl; |
− | < | + | auto commands = device_ptr->commands(); |
− | < | + | for (auto& cmd : commands){ |
+ | std::cout << "-" << to_string(cmd) << std::endl; | ||
+ | } | ||
+ | std::cout << std::endl; | ||
− | < | + | std::cout << "Device has parameters:" << std::endl; |
− | < | + | auto params = device_ptr->parameters(); |
− | < | + | for (auto& paramPair : params){ |
− | + | std::cout << "-" << to_string(paramPair.first) << " {" << to_string(paramPair.second) << "}" <<std::endl; | |
− | < | + | } |
+ | std::cout << std::endl; | ||
− | < | + | std::cout << "Device has channels:" << std::endl; |
− | + | auto channels = device_ptr->channels(); | |
− | + | for (auto& channel : channels){ | |
− | < | + | std::cout << "-" << channel.getName() << std::endl; |
− | + | } | |
+ | std::cout << std::endl; | ||
+ | } | ||
− | |||
− | |||
− | |||
− | |||
− | |||
+ | template <typename T> | ||
+ | void connectDevice(T&& device_ptr){ | ||
+ | using Neuro::Parameter; | ||
+ | std::cout << "Connecting device [" | ||
+ | << device_ptr->readParam<Parameter::Address>() | ||
+ | << "]" << std::endl; | ||
− | < | + | using device_t = typename std::remove_reference_t<decltype(device_ptr)>::element_type; |
− | < | + | auto weakDevice = std::weak_ptr<device_t>(device_ptr); |
− | < | + | device_ptr->setParamChangedCallback([weakDevice](auto param){ |
+ | if (param == Parameter::State){ | ||
+ | auto device = weakDevice.lock(); | ||
+ | if (device != nullptr) { | ||
+ | auto state = device->readParam<Parameter::State>(); | ||
+ | if (state == Neuro::DeviceState::Connected) { | ||
+ | std::cout << "Device [" | ||
+ | << device->readParam<Parameter::Address>() | ||
+ | << "] connected" << std::endl; | ||
+ | displayDeviceFeatures(device); | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | }); | ||
+ | device_ptr->connect(); | ||
+ | FoundDevices.push_back(device_ptr); | ||
+ | } | ||
− | < | + | template <typename T> |
− | + | void onDeviceFound(T&& device_ptr){ | |
− | + | using Neuro::Parameter; | |
− | + | using Neuro::DeviceState; | |
− | + | using Neuro::to_string; | |
− | + | ||
− | + | auto deviceName = device_ptr->readParam<Parameter::Name>(); | |
− | + | auto deviceAddress = device_ptr->readParam<Parameter::Address>(); | |
− | + | auto deviceState = device_ptr->readParam<Parameter::State>(); | |
− | + | std::cout << deviceName | |
− | + | << " [" << deviceAddress << "] " | |
− | + | << to_string(deviceState) | |
− | + | << std::endl; | |
− | < | + | |
− | < | + | using device_t = typename std::remove_reference_t<decltype(device_ptr)>::element_type; |
− | < | + | auto sharedDevice = std::shared_ptr<device_t>(std::forward<T>(device_ptr)); |
− | + | if (deviceState != DeviceState::Connected) { | |
− | + | connectDevice(sharedDevice); | |
− | + | } | |
− | + | else{ | |
− | + | displayDeviceFeatures(sharedDevice); | |
− | std | + | } |
− | + | } | |
− | + | ||
− | + | int main(int argc, char *argv[]){ | |
− | + | auto scanner = Neuro::createDeviceScanner(); | |
− | + | scanner->subscribeDeviceFound([](auto&& device_ptr){ | |
− | + | onDeviceFound(std::forward<decltype(device_ptr)>(device_ptr)); | |
− | + | }); | |
− | + | scanner->startScan(0);//zero timeout for infinity | |
− | + | while (std::cin.get() != '\n'); | |
− | + | } | |
− | + | ||
− | + | </syntaxhighlight> | |
− | + | ||
− | + | Possible output: | |
− | + | <syntaxhighlight lang="bash"> | |
− | + | Neurotech_Callibri_R [2a:90:37:c0:ec:d4] Disconnected | |
− | + | Connecting device [2a:90:37:c0:ec:d4] | |
− | + | Device [2a:90:37:c0:ec:d4] connected | |
− | + | Device can execute: | |
− | + | -FindMe | |
− | + | -StartSignal | |
− | + | -StopSignal | |
− | < | + | |
− | + | Device has parameters: | |
− | + | -Name {Read} | |
− | + | -State {ReadNotify} | |
− | + | -Address {Read} | |
− | </ | + | -SerialNumber {Read} |
+ | -FirmwareMode {Read} | ||
+ | -SamplingFrequency {ReadWrite} | ||
+ | -ADCInputState {ReadWrite} | ||
+ | -ExternalSwitchState {ReadWrite} | ||
+ | -HardwareFilterState {ReadWrite} | ||
+ | -Gain {ReadWrite} | ||
+ | -Offset {ReadWrite} | ||
+ | -AccelerometerSens {ReadWrite} | ||
+ | -GyroscopeSens {ReadWrite} | ||
+ | |||
+ | Device has channels: | ||
+ | -Signal | ||
+ | -ElectrodesState | ||
+ | -ConnectionStats | ||
+ | -Battery | ||
+ | </syntaxhighlight> | ||
− | + | ==See also== | |
− | + | [[NeuroMD SDK Manual]] | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | [[Device (Java)]] | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− |
Latest revision as of 02:43, 1 May 2018
Contents
Neuro::Device
Defined in header <device/device.h>
class Device final;
The Device class is an abstraction for NeuroMD BLE devices. This abstraction provides functions for changing of device state by executing commands and setting parameters. Each device have different sets of supported commands and parameters, Device class has functions designed to get information about these sets. Callibri and Braibit devices has different parameters sets and provides different ways to access them. Device class hides all differences behind its interface and provides universal way to read and write parameters, execute commands and receive biopotential signals.
Member functions
(constructor)[private] | constructs device, inaccessible from user code, new device object could be constructed only by DeviceScanner instance |
(destructor) | destroys device |
operator=[deleted] | not copy assignable |
Supported features | |
---|---|
channels | returns information about channels which could be created with this device, contains information about channels types and names |
commands | returns vector containing supported commands |
parameters | returns |
Non-member functions
checkHasChannel | returns true if device has channel with same channel information |
checkHasCommand | returns true if device supports specified command |
checkHasParameter | returns true if device has specified parameter |
countChannelsWithType | returns number of channels with specified type in channel info section |
getParameterAccess | if device has specified parameter returns access modifier for it, otherwise throws |
Notes
In general all parameter read/write operations, command executions and data read operations through channels must be done on connected devices. Only Name, State and Address parameters could be read on a disconnected device. Performing another operations on a disconnected device cause device-dependent behavior. For Callibri device most of operations on disconnected device will cause exception throwing, for Brainbit some read operations may be performed but it is not guaranteed to be stable for all versions of SDK.
Example
This example shows how a to find device, establish connection with it and to list device features
#include <iostream> #include <vector> #include "device_scanner.h" #include "device/param_values.h" std::vector<std::shared_ptr<Neuro::Device>> FoundDevices; template <typename T> void displayDeviceFeatures(T&& device_ptr){ using Neuro::to_string; std::cout << "Device can execute:" << std::endl; auto commands = device_ptr->commands(); for (auto& cmd : commands){ std::cout << "-" << to_string(cmd) << std::endl; } std::cout << std::endl; std::cout << "Device has parameters:" << std::endl; auto params = device_ptr->parameters(); for (auto& paramPair : params){ std::cout << "-" << to_string(paramPair.first) << " {" << to_string(paramPair.second) << "}" <<std::endl; } std::cout << std::endl; std::cout << "Device has channels:" << std::endl; auto channels = device_ptr->channels(); for (auto& channel : channels){ std::cout << "-" << channel.getName() << std::endl; } std::cout << std::endl; } template <typename T> void connectDevice(T&& device_ptr){ using Neuro::Parameter; std::cout << "Connecting device [" << device_ptr->readParam<Parameter::Address>() << "]" << std::endl; using device_t = typename std::remove_reference_t<decltype(device_ptr)>::element_type; auto weakDevice = std::weak_ptr<device_t>(device_ptr); device_ptr->setParamChangedCallback([weakDevice](auto param){ if (param == Parameter::State){ auto device = weakDevice.lock(); if (device != nullptr) { auto state = device->readParam<Parameter::State>(); if (state == Neuro::DeviceState::Connected) { std::cout << "Device [" << device->readParam<Parameter::Address>() << "] connected" << std::endl; displayDeviceFeatures(device); } } } }); device_ptr->connect(); FoundDevices.push_back(device_ptr); } template <typename T> void onDeviceFound(T&& device_ptr){ using Neuro::Parameter; using Neuro::DeviceState; using Neuro::to_string; auto deviceName = device_ptr->readParam<Parameter::Name>(); auto deviceAddress = device_ptr->readParam<Parameter::Address>(); auto deviceState = device_ptr->readParam<Parameter::State>(); std::cout << deviceName << " [" << deviceAddress << "] " << to_string(deviceState) << std::endl; using device_t = typename std::remove_reference_t<decltype(device_ptr)>::element_type; auto sharedDevice = std::shared_ptr<device_t>(std::forward<T>(device_ptr)); if (deviceState != DeviceState::Connected) { connectDevice(sharedDevice); } else{ displayDeviceFeatures(sharedDevice); } } int main(int argc, char *argv[]){ auto scanner = Neuro::createDeviceScanner(); scanner->subscribeDeviceFound([](auto&& device_ptr){ onDeviceFound(std::forward<decltype(device_ptr)>(device_ptr)); }); scanner->startScan(0);//zero timeout for infinity while (std::cin.get() != '\n'); }
Possible output:
Neurotech_Callibri_R [2a:90:37:c0:ec:d4] Disconnected Connecting device [2a:90:37:c0:ec:d4] Device [2a:90:37:c0:ec:d4] connected Device can execute: -FindMe -StartSignal -StopSignal Device has parameters: -Name {Read} -State {ReadNotify} -Address {Read} -SerialNumber {Read} -FirmwareMode {Read} -SamplingFrequency {ReadWrite} -ADCInputState {ReadWrite} -ExternalSwitchState {ReadWrite} -HardwareFilterState {ReadWrite} -Gain {ReadWrite} -Offset {ReadWrite} -AccelerometerSens {ReadWrite} -GyroscopeSens {ReadWrite} Device has channels: -Signal -ElectrodesState -ConnectionStats -Battery