diff --git a/CHANGELOG.md b/CHANGELOG.md index 0539b455..6b6a2ead 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -52,6 +52,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Continue updating power metrics to other clients if one client disconnects. - Freed 19k of ram by consolidating tasks and using timers instead of delays. - Updated baud rate to 115200 to ensure compatibility with other ESP32 variants. +- Added ability to send target watts through the custom characteristic. - Added a final test to check if ERG mode has commanded a move in the proper direction. ### Hardware diff --git a/include/BLE_Custom_Characteristic.h b/include/BLE_Custom_Characteristic.h index bf045867..105a872a 100644 --- a/include/BLE_Custom_Characteristic.h +++ b/include/BLE_Custom_Characteristic.h @@ -30,8 +30,8 @@ const uint8_t BLE_stealthChop = 0x0A; // Stepper StealthChop (Makes i const uint8_t BLE_inclineMultiplier = 0x0B; // Incline * this = steps to move. 3.0 is a good starting value for most bikes. const uint8_t BLE_powerCorrectionFactor = 0x0C; // Correction factor for FTMS and CPS connected devices. .1-2.0 const uint8_t BLE_simulateHr = 0x0D; // If set to 1, override connected HR and use simulated above. -const uint8_t BLE_simulateWatts = 0x0E; // "" for Power Meter -const uint8_t BLE_simulateCad = 0x0F; // "" for Cad +const uint8_t BLE_simulateWatts = 0x0E; // Are we sending watts +const uint8_t BLE_simulateCad = 0x0F; // Are we sending cad const uint8_t BLE_FTMSMode = 0x10; // get or set FTMS mode using values such as FitnessMachineControlPointProcedure::SetTargetPower const uint8_t BLE_autoUpdate = 0x11; // Attempt to update firmware on reboot? const uint8_t BLE_ssid = 0x12; // WiFi SSID. If it's not a network in range, fallback to AP mode made with devicename and "password" @@ -56,6 +56,8 @@ const uint8_t BLE_scanBLE = 0x24; // Scan for new BLE devices const uint8_t BLE_firmwareVer = 0x25; // String of the current firmware version const uint8_t BLE_resetPowerTable = 0x26; // Delete all power table information. const uint8_t BLE_powerTableData = 0x27; // sets or requests power table data +const uint8_t BLE_simulatedTargetWatts = 0x28; // current target watts +const uint8_t BLE_simulateTargetWatts = 0x29; // are we sending target watts class BLE_ss2kCustomCharacteristic { public: diff --git a/src/BLE_Custom_Characteristic.cpp b/src/BLE_Custom_Characteristic.cpp index 46a3ece3..5baeea93 100644 --- a/src/BLE_Custom_Characteristic.cpp +++ b/src/BLE_Custom_Characteristic.cpp @@ -679,6 +679,34 @@ void BLE_ss2kCustomCharacteristic::process(std::string rxValue) { } } break; + case BLE_simulatedTargetWatts: //0x28 + logBufLength += snprintf(logBuf + logBufLength, kLogBufCapacity - logBufLength, "<-targetWatts"); + if (rxValue[0] == cc_read) { + returnValue[0] = cc_success; + returnValue[2] = (uint8_t)(rtConfig->watts.getTarget() & 0xff); + returnValue[3] = (uint8_t)(rtConfig->watts.getTarget() >> 8); + returnLength += 2; + } + if (rxValue[0] == cc_write) { + returnValue[0] = cc_success; + rtConfig->watts.setValue(bytes_to_u16(rxValue[3], rxValue[2])); + logBufLength += snprintf(logBuf + logBufLength, kLogBufCapacity - logBufLength, "(%d)", rtConfig->watts.getTarget()); + } + break; + case BLE_simulateTargetWatts: //0x29 + logBufLength += snprintf(logBuf + logBufLength, kLogBufCapacity - logBufLength, "<-simulatetargetwatts"); + if (rxValue[0] == cc_read) { + returnValue[0] = cc_success; + returnValue[2] = (uint8_t)(rtConfig->getSimTargetWatts()); + returnLength += 1; + } + if (rxValue[0] == cc_write) { + returnValue[0] = cc_success; + rtConfig->setSimTargetWatts(rxValue[2]); + logBufLength += snprintf(logBuf + logBufLength, kLogBufCapacity - logBufLength, "(%s)", rtConfig->getSimTargetWatts() ? "true" : "false"); + } + break; + } SS2K_LOG(CUSTOM_CHAR_LOG_TAG, "%s", logBuf); @@ -700,6 +728,7 @@ void BLE_ss2kCustomCharacteristic::process(std::string rxValue) { // iterate through all smartspin user parameters and notify the specific one if changed void BLE_ss2kCustomCharacteristic::parseNemit() { static userParameters _oldParams; + static RuntimeParameters _oldRTParams; if (userConfig->getAutoUpdate() != _oldParams.getAutoUpdate()) { _oldParams.setAutoUpdate(userConfig->getAutoUpdate()); @@ -813,4 +842,19 @@ void BLE_ss2kCustomCharacteristic::parseNemit() { BLE_ss2kCustomCharacteristic::notify(BLE_shiftDir); return; } + if(rtConfig->getFTMSMode() != _oldRTParams.getFTMSMode()){ + _oldRTParams.setFTMSMode(rtConfig->getFTMSMode()); + BLE_ss2kCustomCharacteristic::notify(BLE_FTMSMode); + return; + } + if(rtConfig->watts.getTarget() != _oldRTParams.watts.getTarget()){ + _oldRTParams.watts.setTarget(rtConfig->watts.getTarget()); + BLE_ss2kCustomCharacteristic::notify(BLE_simulatedTargetWatts); + return; + } + if(rtConfig->getSimTargetWatts() != _oldRTParams.getSimTargetWatts()){ + _oldRTParams.setSimTargetWatts(rtConfig->getSimTargetWatts()); + BLE_ss2kCustomCharacteristic::notify(BLE_simulateTargetWatts); + return; + } } \ No newline at end of file diff --git a/src/BLE_Fitness_Machine_Service.cpp b/src/BLE_Fitness_Machine_Service.cpp index 687eaf09..a202f73b 100644 --- a/src/BLE_Fitness_Machine_Service.cpp +++ b/src/BLE_Fitness_Machine_Service.cpp @@ -131,6 +131,8 @@ void BLE_Fitness_Machine_Service::processFTMSWrite() { case FitnessMachineControlPointProcedure::RequestControl: returnValue[2] = FitnessMachineControlPointResultCode::Success; // 0x01; pCharacteristic->setValue(returnValue, 3); + rtConfig->watts.setTarget(0); + rtConfig->setSimTargetWatts(false); logBufLength += snprintf(logBuf + logBufLength, kLogBufCapacity - logBufLength, "-> Control Request"); ftmsTrainingStatus[1] = FitnessMachineTrainingStatus::Idle; // 0x01; fitnessMachineTrainingStatus->setValue(ftmsTrainingStatus, 2); @@ -238,7 +240,6 @@ void BLE_Fitness_Machine_Service::processFTMSWrite() { rtConfig->setFTMSMode((uint8_t)rxValue[0]); returnValue[2] = FitnessMachineControlPointResultCode::Success; // 0x01; pCharacteristic->setValue(returnValue, 3); - signed char buf[2]; // int16_t windSpeed = (rxValue[2] << 8) + rxValue[1]; buf[0] = rxValue[3]; // (Least significant byte)