diff --git a/include/BLE_Common.h b/include/BLE_Common.h index 061b3bf0..fcce8cff 100644 --- a/include/BLE_Common.h +++ b/include/BLE_Common.h @@ -37,9 +37,16 @@ #define FITNESSMACHINEPOWERRANGE_UUID BLEUUID((uint16_t)0x2AD8) // GATT service/characteristic UUIDs for Flywheel Bike from ptx2/gymnasticon/ -#define FLYWHEEL_UART_SERVICE_UUID BLEUUID((uint16_t)0xCA9E) -#define FLYWHEEL_UART_RX_UUID BLEUUID((uint16_t)0xCA9E) -#define FLYWHEEL_UART_TX_UUID BLEUUID((uint16_t)0xCA9E) +#define FLYWHEEL_UART_SERVICE_UUID BLEUUID("6e400001b5a3f393e0a9e50e24dcca9e") +#define FLYWHEEL_UART_RX_UUID BLEUUID("6e400002b5a3f393e0a9e50e24dcca9e") +#define FLYWHEEL_UART_TX_UUID BLEUUID("6e400003b5a3f393e0a9e50e24dcca9e") + +// The Echelon Services +#define ECHELON_DEVICE_UUID BLEUUID("0bf669f0-45f2-11e7-9598-0800200c9a66") +#define ECHELON_SERVICE_UUID BLEUUID("0bf669f1-45f2-11e7-9598-0800200c9a66") +#define ECHELON_WRITE_UUID BLEUUID("0bf669f2-45f2-11e7-9598-0800200c9a66") +#define ECHELON_DATA_UUID BLEUUID("0bf669f4-45f2-11e7-9598-0800200c9a66") + // macros to convert different types of bytes into int The naming here sucks and should be fixed. #define bytes_to_s16(MSB, LSB) (((signed int)((signed char)MSB))) << 8 | (((signed char)LSB)) diff --git a/include/sensors/CyclePowerData.h b/include/sensors/CyclePowerData.h index 60734906..bafd3b3e 100644 --- a/include/sensors/CyclePowerData.h +++ b/include/sensors/CyclePowerData.h @@ -1,3 +1,10 @@ +// SmartSpin2K code +// This software registers an ESP32 as a BLE FTMS device which then uses a stepper motor to turn the resistance knob on a regular spin bike. +// BLE code based on examples from https://github.com/nkolban +// Copyright 2020 Anthony Doud & Joel Baranick +// This work is licensed under the GNU General Public License v2 +// Prototype hardware build from plans in the SmartSpin2k repository are licensed under Cern Open Hardware Licence version 2 Permissive + #pragma once #include diff --git a/include/sensors/EchelonData.h b/include/sensors/EchelonData.h new file mode 100644 index 00000000..b9880509 --- /dev/null +++ b/include/sensors/EchelonData.h @@ -0,0 +1,31 @@ +// SmartSpin2K code +// This software registers an ESP32 as a BLE FTMS device which then uses a stepper motor to turn the resistance knob on a regular spin bike. +// BLE code based on examples from https://github.com/nkolban +// Copyright 2020 Anthony Doud & Joel Baranick +// This work is licensed under the GNU General Public License v2 +// Prototype hardware build from plans in the SmartSpin2k repository are licensed under Cern Open Hardware Licence version 2 Permissive + +#pragma once + +#include "SensorData.h" + +class EchelonData : public SensorData +{ +public: + EchelonData() : SensorData("ECH"), cadence(NAN), resistance(INT_MIN), power(INT_MIN) {}; + + bool hasHeartRate(); + bool hasCadence(); + bool hasPower(); + bool hasSpeed(); + int getHeartRate(); + float getCadence(); + int getPower(); + float getSpeed(); + void decode(uint8_t *data, size_t length); + +private: + float cadence; + int resistance; + int power; +}; \ No newline at end of file diff --git a/include/sensors/FitnessMachineIndoorBikeData.h b/include/sensors/FitnessMachineIndoorBikeData.h index 97415679..be7e6fc0 100644 --- a/include/sensors/FitnessMachineIndoorBikeData.h +++ b/include/sensors/FitnessMachineIndoorBikeData.h @@ -1,3 +1,10 @@ +// SmartSpin2K code +// This software registers an ESP32 as a BLE FTMS device which then uses a stepper motor to turn the resistance knob on a regular spin bike. +// BLE code based on examples from https://github.com/nkolban +// Copyright 2020 Anthony Doud & Joel Baranick +// This work is licensed under the GNU General Public License v2 +// Prototype hardware build from plans in the SmartSpin2k repository are licensed under Cern Open Hardware Licence version 2 Permissive + #pragma once #include diff --git a/include/sensors/FlywheelData.h b/include/sensors/FlywheelData.h index 3289563b..737ecf94 100644 --- a/include/sensors/FlywheelData.h +++ b/include/sensors/FlywheelData.h @@ -1,3 +1,10 @@ +// SmartSpin2K code +// This software registers an ESP32 as a BLE FTMS device which then uses a stepper motor to turn the resistance knob on a regular spin bike. +// BLE code based on examples from https://github.com/nkolban +// Copyright 2020 Anthony Doud & Joel Baranick +// This work is licensed under the GNU General Public License v2 +// Prototype hardware build from plans in the SmartSpin2k repository are licensed under Cern Open Hardware Licence version 2 Permissive + #pragma once #include "SensorData.h" diff --git a/include/sensors/HeartRateData.h b/include/sensors/HeartRateData.h index ec7c4c91..dca77950 100644 --- a/include/sensors/HeartRateData.h +++ b/include/sensors/HeartRateData.h @@ -1,3 +1,10 @@ +// SmartSpin2K code +// This software registers an ESP32 as a BLE FTMS device which then uses a stepper motor to turn the resistance knob on a regular spin bike. +// BLE code based on examples from https://github.com/nkolban +// Copyright 2020 Anthony Doud & Joel Baranick +// This work is licensed under the GNU General Public License v2 +// Prototype hardware build from plans in the SmartSpin2k repository are licensed under Cern Open Hardware Licence version 2 Permissive + #pragma once #include "SensorData.h" diff --git a/include/sensors/SensorData.h b/include/sensors/SensorData.h index 87492646..4c5349d4 100644 --- a/include/sensors/SensorData.h +++ b/include/sensors/SensorData.h @@ -1,3 +1,10 @@ +// SmartSpin2K code +// This software registers an ESP32 as a BLE FTMS device which then uses a stepper motor to turn the resistance knob on a regular spin bike. +// BLE code based on examples from https://github.com/nkolban +// Copyright 2020 Anthony Doud & Joel Baranick +// This work is licensed under the GNU General Public License v2 +// Prototype hardware build from plans in the SmartSpin2k repository are licensed under Cern Open Hardware Licence version 2 Permissive + #pragma once #include diff --git a/include/sensors/SensorDataFactory.h b/include/sensors/SensorDataFactory.h index 8ae14912..dc8691e7 100644 --- a/include/sensors/SensorDataFactory.h +++ b/include/sensors/SensorDataFactory.h @@ -1,3 +1,10 @@ +// SmartSpin2K code +// This software registers an ESP32 as a BLE FTMS device which then uses a stepper motor to turn the resistance knob on a regular spin bike. +// BLE code based on examples from https://github.com/nkolban +// Copyright 2020 Anthony Doud & Joel Baranick +// This work is licensed under the GNU General Public License v2 +// Prototype hardware build from plans in the SmartSpin2k repository are licensed under Cern Open Hardware Licence version 2 Permissive + #pragma once #include @@ -8,6 +15,7 @@ #include "FlywheelData.h" #include "FitnessMachineIndoorBikeData.h" #include "HeartRateData.h" +#include "EchelonData.h" class SensorDataFactory { diff --git a/src/BLE_Client.cpp b/src/BLE_Client.cpp index 2dbeebb7..f1f9ad88 100644 --- a/src/BLE_Client.cpp +++ b/src/BLE_Client.cpp @@ -122,6 +122,12 @@ bool SpinBLEClient::connectToServer() charUUID = FITNESSMACHINEINDOORBIKEDATA_UUID; debugDirector("trying to connect to Fitness machine service"); } + else if (myDevice->isAdvertisingService(ECHELON_DEVICE_UUID)) + { + serviceUUID = ECHELON_SERVICE_UUID; + charUUID = ECHELON_DATA_UUID; + debugDirector("Trying to connect to Echelon Bike"); + } else if (myDevice->isAdvertisingService(HEARTSERVICE_UUID)) { serviceUUID = HEARTSERVICE_UUID; @@ -200,7 +206,7 @@ bool SpinBLEClient::connectToServer() } if (pRemoteCharacteristic->canNotify()) - { + { debugDirector("Found " + String(pRemoteCharacteristic->getUUID().toString().c_str()) + " on reconnect."); reconnectTries = MAX_RECONNECT_TRIES; //VV Is this really needed? Shouldn't it just carry over from the previous connection? VV @@ -242,7 +248,6 @@ bool SpinBLEClient::connectToServer() pClient->connect(myDevice->getAddress()); // if you pass BLEAdvertisedDevice instead of address, it will be recognized type of peer device address (public or private) debugDirector(" - Connected to server", true); debugDirector(" - RSSI " + pClient->getRssi(), true); - // Obtain a reference to the service we are after in the remote BLE server. BLERemoteService *pRemoteService = pClient->getService(serviceUUID); if (pRemoteService == nullptr) @@ -313,7 +318,7 @@ bool SpinBLEClient::connectToServer() void SpinBLEClient::MyClientCallback::onConnect(NimBLEClient *pClient) { - //debugDirector("Connect Called"); This callback happens so early for us it's nearly useless. + //debugDirector("Connect Called"); This callback happens so early for us it's nearly useless. } void SpinBLEClient::MyClientCallback::onDisconnect(NimBLEClient *pclient) @@ -340,7 +345,7 @@ void SpinBLEClient::MyClientCallback::onDisconnect(NimBLEClient *pclient) //spinBLEClient.myBLEDevices[i].connectedClientID = BLE_HS_CONN_HANDLE_NONE; debugDirector("Detected " + String(spinBLEClient.myBLEDevices[i].serviceUUID.toString().c_str()) + " Disconnect"); spinBLEClient.myBLEDevices[i].doConnect = true; - if ((spinBLEClient.myBLEDevices[i].charUUID == CYCLINGPOWERMEASUREMENT_UUID) || (spinBLEClient.myBLEDevices[i].charUUID == FITNESSMACHINEINDOORBIKEDATA_UUID) || (spinBLEClient.myBLEDevices[i].charUUID == FLYWHEEL_UART_RX_UUID)) + if ((spinBLEClient.myBLEDevices[i].charUUID == CYCLINGPOWERMEASUREMENT_UUID) || (spinBLEClient.myBLEDevices[i].charUUID == FITNESSMACHINEINDOORBIKEDATA_UUID) || (spinBLEClient.myBLEDevices[i].charUUID == FLYWHEEL_UART_RX_UUID) || (spinBLEClient.myBLEDevices[i].charUUID == ECHELON_SERVICE_UUID)) { debugDirector("Deregistered PM on Disconnect"); @@ -394,7 +399,7 @@ void SpinBLEClient::MyAdvertisedDeviceCallback::onResult(BLEAdvertisedDevice *ad { aDevName = ""; } - if ((advertisedDevice->haveServiceUUID()) && (advertisedDevice->isAdvertisingService(CYCLINGPOWERSERVICE_UUID) || advertisedDevice->isAdvertisingService(FLYWHEEL_UART_SERVICE_UUID) || advertisedDevice->isAdvertisingService(FITNESSMACHINESERVICE_UUID) || advertisedDevice->isAdvertisingService(HEARTSERVICE_UUID))) + if ((advertisedDevice->haveServiceUUID()) && (advertisedDevice->isAdvertisingService(CYCLINGPOWERSERVICE_UUID) || advertisedDevice->isAdvertisingService(FLYWHEEL_UART_SERVICE_UUID) || advertisedDevice->isAdvertisingService(FITNESSMACHINESERVICE_UUID) || advertisedDevice->isAdvertisingService(HEARTSERVICE_UUID) || advertisedDevice->isAdvertisingService(ECHELON_DEVICE_UUID))) { //if ((aDevName == c_PM) || (advertisedDevice->getAddress().toString().c_str() == c_PM) || (aDevName == c_HR) || (advertisedDevice->getAddress().toString().c_str() == c_HR) || (String(c_PM) == ("any")) || (String(c_HR) == ("any"))) //{ //notice the subtle difference vv getServiceUUID(int) returns the index of the service in the list or the 0 slot if not specified. @@ -410,7 +415,8 @@ void SpinBLEClient::MyAdvertisedDeviceCallback::onResult(BLEAdvertisedDevice *ad { debugDirector("Skipping non-selected HRM |" + aDevName + "|" + String(userConfig.getconnectedHeartMonitor())); return; - }else if (aDevName == String(userConfig.getconnectedHeartMonitor())) + } + else if (aDevName == String(userConfig.getconnectedHeartMonitor())) { debugDirector("HR String Matched " + aDevName); } @@ -426,7 +432,8 @@ void SpinBLEClient::MyAdvertisedDeviceCallback::onResult(BLEAdvertisedDevice *ad { debugDirector("Skipping non-selected PM |" + aDevName + "|" + String(userConfig.getconnectedPowerMeter())); return; - }else if (aDevName == String(userConfig.getconnectedPowerMeter())) + } + else if (aDevName == String(userConfig.getconnectedPowerMeter())) { debugDirector("PM String Matched " + aDevName); } @@ -456,6 +463,7 @@ void SpinBLEClient::scanProcess() pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallback()); pBLEScan->setInterval(550); pBLEScan->setWindow(500); + pBLEScan->setDuplicateFilter(true); pBLEScan->setActiveScan(true); BLEScanResults foundDevices = pBLEScan->start(10, false); // Load the scan into a Json String @@ -468,7 +476,7 @@ void SpinBLEClient::scanProcess() for (int i = 0; i < count; i++) { BLEAdvertisedDevice d = foundDevices.getDevice(i); - if (d.isAdvertisingService(CYCLINGPOWERSERVICE_UUID) || d.isAdvertisingService(HEARTSERVICE_UUID) || d.isAdvertisingService(FLYWHEEL_UART_SERVICE_UUID) || d.isAdvertisingService(FITNESSMACHINESERVICE_UUID)) + if (d.isAdvertisingService(CYCLINGPOWERSERVICE_UUID) || d.isAdvertisingService(HEARTSERVICE_UUID) || d.isAdvertisingService(FLYWHEEL_UART_SERVICE_UUID) || d.isAdvertisingService(FITNESSMACHINESERVICE_UUID) || d.isAdvertisingService(ECHELON_DEVICE_UUID)) { device = "device " + String(i); devices[device]["address"] = d.getAddress().toString(); @@ -566,14 +574,29 @@ void SpinBLEClient::resetDevices() void SpinBLEClient::postConnect(NimBLEClient *pClient) { - for (size_t i = 0; i < NUM_BLE_DEVICES; i++) + for (size_t i = 0; i < NUM_BLE_DEVICES; i++) { if (pClient->getPeerAddress() == this->myBLEDevices[i].peerAddress) { - if ((this->myBLEDevices[i].charUUID == CYCLINGPOWERMEASUREMENT_UUID) || (this->myBLEDevices[i].charUUID == FITNESSMACHINEINDOORBIKEDATA_UUID) || (this->myBLEDevices[i].charUUID == FLYWHEEL_UART_RX_UUID)) + if ((this->myBLEDevices[i].charUUID == CYCLINGPOWERMEASUREMENT_UUID) || (this->myBLEDevices[i].charUUID == FITNESSMACHINEINDOORBIKEDATA_UUID) || (this->myBLEDevices[i].charUUID == FLYWHEEL_UART_RX_UUID)|| (this->myBLEDevices[i].charUUID == ECHELON_DATA_UUID)) { this->connectedPM = true; debugDirector("Registered PM on Connect"); + if (this->myBLEDevices[i].charUUID == ECHELON_DATA_UUID) + { + NimBLERemoteCharacteristic *writeCharacteristic = pClient->getService(ECHELON_SERVICE_UUID)->getCharacteristic(ECHELON_WRITE_UUID); + if (writeCharacteristic == nullptr) + { + debugDirector("Failed to find Echelon write characteristic UUID: ",false); + debugDirector(String(ECHELON_WRITE_UUID.toString().c_str())); + pClient->disconnect(); + return; + } + // Enable device notifications + byte message[] = {0xF0, 0xB0, 0x01, 0x01, 0xA2}; + writeCharacteristic->writeValue(message, 5); + debugDirector("Activated Echelon callbacks."); + } //spinBLEClient.removeDuplicates(pclient); return; } @@ -607,7 +630,3 @@ void SpinBLEAdvertisedDevice::print() strcat(logBufP, "|"); debugDirector(String(logBuf)); } - - - - diff --git a/src/BLE_Common.cpp b/src/BLE_Common.cpp index 0279d40c..e9a1c5f4 100644 --- a/src/BLE_Common.cpp +++ b/src/BLE_Common.cpp @@ -56,7 +56,7 @@ void BLECommunications(void *pvParameters) { logBufP += sprintf(logBufP, "%02x ", pData[i]); } - logBufP += sprintf(logBufP, "<- %s | %s", myAdvertisedDevice.serviceUUID.toString().c_str(), myAdvertisedDevice.charUUID.toString().c_str()); + logBufP += sprintf(logBufP, "<- %.8s | %.8s", myAdvertisedDevice.serviceUUID.toString().c_str(), myAdvertisedDevice.charUUID.toString().c_str()); std::shared_ptr sensorData = sensorDataFactory.getSensorData(pRemoteBLECharacteristic, pData, length); diff --git a/src/sensors/CyclePowerData.cpp b/src/sensors/CyclePowerData.cpp index 8faef074..cb72b40c 100644 --- a/src/sensors/CyclePowerData.cpp +++ b/src/sensors/CyclePowerData.cpp @@ -1,3 +1,10 @@ +// SmartSpin2K code +// This software registers an ESP32 as a BLE FTMS device which then uses a stepper motor to turn the resistance knob on a regular spin bike. +// BLE code based on examples from https://github.com/nkolban +// Copyright 2020 Anthony Doud & Joel Baranick +// This work is licensed under the GNU General Public License v2 +// Prototype hardware build from plans in the SmartSpin2k repository are licensed under Cern Open Hardware Licence version 2 Permissive + #include "BLE_Common.h" #include "sensors/CyclePowerData.h" diff --git a/src/sensors/EchelonData.cpp b/src/sensors/EchelonData.cpp new file mode 100644 index 00000000..ddf6acdb --- /dev/null +++ b/src/sensors/EchelonData.cpp @@ -0,0 +1,52 @@ +// SmartSpin2K code +// This software registers an ESP32 as a BLE FTMS device which then uses a stepper motor to turn the resistance knob on a regular spin bike. +// BLE code based on examples from https://github.com/nkolban +// Copyright 2020 Anthony Doud & Joel Baranick +// This work is licensed under the GNU General Public License v2 +// Prototype hardware build from plans in the SmartSpin2k repository are licensed under Cern Open Hardware Licence version 2 Permissive +// Echelon Decoding model based on https://github.com/snowzach/echbt + +#include "BLE_Common.h" +#include "sensors/EchelonData.h" + +bool EchelonData::hasHeartRate() { return false; } + +bool EchelonData::hasCadence() { return !isnan(this->cadence); } + +bool EchelonData::hasPower() { return this->cadence >= 0 && this->resistance >= 0; } + +bool EchelonData::hasSpeed() { return false; } + +int EchelonData::getHeartRate() { return INT_MIN; } + +float EchelonData::getCadence() { return this->cadence; }; + +int EchelonData::getPower() { return this->power; }; + +float EchelonData::getSpeed() { return NAN; } + +void EchelonData::decode(uint8_t *data, size_t length) +{ + switch (data[1]) + { + // Cadence notification + case 0xD1: + this->cadence = int((data[9] << 8) + data[10]); + break; + // Resistance notification + case 0xD2: + this->resistance = int(data[3]); + break; + } + if (isnan(this->cadence) || this->resistance < 0) { + return; + } + if (this->cadence == 0 || this->resistance == 0) + { + power = 0; + } + else + { + power = pow(1.090112, resistance) * pow(1.015343, cadence) * 7.228958; + } +} \ No newline at end of file diff --git a/src/sensors/FitnessMachineIndoorBikeData.cpp b/src/sensors/FitnessMachineIndoorBikeData.cpp index 2324aac6..d8d414ff 100644 --- a/src/sensors/FitnessMachineIndoorBikeData.cpp +++ b/src/sensors/FitnessMachineIndoorBikeData.cpp @@ -1,3 +1,10 @@ +// SmartSpin2K code +// This software registers an ESP32 as a BLE FTMS device which then uses a stepper motor to turn the resistance knob on a regular spin bike. +// BLE code based on examples from https://github.com/nkolban +// Copyright 2020 Anthony Doud & Joel Baranick +// This work is licensed under the GNU General Public License v2 +// Prototype hardware build from plans in the SmartSpin2k repository are licensed under Cern Open Hardware Licence version 2 Permissive + #include "BLE_Common.h" #include "sensors/FitnessMachineIndoorBikeData.h" diff --git a/src/sensors/FlywheelData.cpp b/src/sensors/FlywheelData.cpp index 79a2f554..b4de4a84 100644 --- a/src/sensors/FlywheelData.cpp +++ b/src/sensors/FlywheelData.cpp @@ -1,3 +1,10 @@ +// SmartSpin2K code +// This software registers an ESP32 as a BLE FTMS device which then uses a stepper motor to turn the resistance knob on a regular spin bike. +// BLE code based on examples from https://github.com/nkolban +// Copyright 2020 Anthony Doud & Joel Baranick +// This work is licensed under the GNU General Public License v2 +// Prototype hardware build from plans in the SmartSpin2k repository are licensed under Cern Open Hardware Licence version 2 Permissive + #include "BLE_Common.h" #include "sensors/FlywheelData.h" diff --git a/src/sensors/HeartRateData.cpp b/src/sensors/HeartRateData.cpp index 604ff6e2..fd861fd4 100644 --- a/src/sensors/HeartRateData.cpp +++ b/src/sensors/HeartRateData.cpp @@ -1,3 +1,10 @@ +// SmartSpin2K code +// This software registers an ESP32 as a BLE FTMS device which then uses a stepper motor to turn the resistance knob on a regular spin bike. +// BLE code based on examples from https://github.com/nkolban +// Copyright 2020 Anthony Doud & Joel Baranick +// This work is licensed under the GNU General Public License v2 +// Prototype hardware build from plans in the SmartSpin2k repository are licensed under Cern Open Hardware Licence version 2 Permissive + #include "sensors/HeartRateData.h" bool HeartRateData::hasHeartRate() { return true; } diff --git a/src/sensors/SensorData.cpp b/src/sensors/SensorData.cpp index 34d51192..f24325f3 100644 --- a/src/sensors/SensorData.cpp +++ b/src/sensors/SensorData.cpp @@ -1,3 +1,10 @@ +// SmartSpin2K code +// This software registers an ESP32 as a BLE FTMS device which then uses a stepper motor to turn the resistance knob on a regular spin bike. +// BLE code based on examples from https://github.com/nkolban +// Copyright 2020 Anthony Doud & Joel Baranick +// This work is licensed under the GNU General Public License v2 +// Prototype hardware build from plans in the SmartSpin2k repository are licensed under Cern Open Hardware Licence version 2 Permissive + #include "sensors/SensorData.h" String SensorData::getId() { return this->id; } \ No newline at end of file diff --git a/src/sensors/SensorDataFactory.cpp b/src/sensors/SensorDataFactory.cpp index 68ea30f3..c33d4490 100644 --- a/src/sensors/SensorDataFactory.cpp +++ b/src/sensors/SensorDataFactory.cpp @@ -1,3 +1,10 @@ +// SmartSpin2K code +// This software registers an ESP32 as a BLE FTMS device which then uses a stepper motor to turn the resistance knob on a regular spin bike. +// BLE code based on examples from https://github.com/nkolban +// Copyright 2020 Anthony Doud & Joel Baranick +// This work is licensed under the GNU General Public License v2 +// Prototype hardware build from plans in the SmartSpin2k repository are licensed under Cern Open Hardware Licence version 2 Permissive + #include "BLE_Common.h" #include "sensors/SensorDataFactory.h" #include "sensors/SensorData.h" @@ -5,6 +12,7 @@ #include "sensors/FlywheelData.h" #include "sensors/FitnessMachineIndoorBikeData.h" #include "sensors/HeartRateData.h" +#include "sensors/EchelonData.h" std::shared_ptr SensorDataFactory::getSensorData(BLERemoteCharacteristic *characteristic, uint8_t *data, size_t length) { @@ -33,6 +41,10 @@ std::shared_ptr SensorDataFactory::getSensorData(BLERemoteCharacteri else if (uuid == FLYWHEEL_UART_SERVICE_UUID) { sensorData = std::shared_ptr(new FlywheelData()); + } + else if (uuid == ECHELON_DATA_UUID) + { + sensorData = std::shared_ptr(new EchelonData()); } else {